Skip to content

Update main.py - #47

Open
check6559-wq wants to merge 1 commit into
aeither:mainfrom
check6559-wq:patch-1
Open

check6559-wq wants to merge 1 commit into
aeither:mainfrom
check6559-wq:patch-1

Conversation

@check6559-wq

@check6559-wq check6559-wq commented Mar 31, 2026 •

Copy link
Copy Markdown

Summary by CodeRabbit

  • New Features
    • Added new bot commands: /otp for time-limited one-time passwords, /profile for viewing user information and plans, and /help for accessing documentation
    • Introduced admin panel with user statistics, management tools, and broadcast capabilities
    • Enabled API key generation and preview functionality for users
    • Integrated referral system to track user referrals
    • Added inline action buttons for seamless command execution and menu navigation

@coderabbitai

coderabbitai Bot commented Mar 31, 2026 •

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

The main.py file undergoes a comprehensive transformation from a minimal command/echo bot to a feature-complete implementation with user authentication, in-memory state management, API key generation, OTP verification, admin panel, and referral tracking functionality.

Changes

Cohort / File(s) Summary
Bot Core Rewrite
main.py
Complete reimplementation replacing .env loading and register_commands with hardcoded config defaults. Introduced in-memory state management (user_data, otp_storage, api_keys), helper functions for admin checks and credential generation, and new command handlers (/start, /otp, /profile, /help, /admin, /upgrade, /genkey, /broadcast). Added callback query handlers for inline actions and catch-all message handler. Changed from webhook deletion loop to infinity_polling() startup.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Poem

🐰 Hop and cheer, a bot's reborn,
From echo calls to features worn,
OTP codes and keys now flow,
Admin panels steal the show,
Referrals tracked through tunnels deep,
This code change makes the bot leap! 🎉

🚥 Pre-merge checks | ✅ 1 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title 'Update main.py' is vague and generic, using a non-descriptive term that doesn't convey meaningful information about the substantial changeset. Replace with a specific title describing the main change, such as 'Add comprehensive bot commands and admin functionality' or 'Implement OTP, API keys, and user profile system'.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🧹 Nitpick comments (5)
main.py (5)

386-392: Repeated iteration over user_data is inefficient.

The stats calculation iterates user_data.values() four times (lines 386-388, 391-392). For a bot with many users, this is wasteful. Consider computing stats in a single pass.

Proposed optimization
# Single-pass stats calculation
plan_counts = {'free': 0, 'silver': 0, 'gold': 0}
total_referrals = 0
top_referrer = None
max_refs = 0

for uid, data in user_data.items():
    plan_counts[data['plan']] = plan_counts.get(data['plan'], 0) + 1
    total_referrals += data['referrals']
    if data['referrals'] > max_refs:
        max_refs = data['referrals']
        top_referrer = uid
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@main.py` around lines 386 - 392, Iterate user_data once to compute
plan_counts, total_referrals, top_referrer and max_refs in a single-pass (e.g.,
initialize plan_counts = {'free':0,'silver':0,'gold':0}, total_referrals = 0,
top_referrer = 'None', max_refs = -1 and update inside a for uid, data in
user_data.items() loop), then replace the repeated list comprehensions in the
output block with references to plan_counts['free'], plan_counts['silver'],
plan_counts['gold'], total_referrals and top_referrer; ensure you handle the
empty-user case so top_referrer remains 'None' when user_data is empty.

5-5: Remove unused import.

json is imported but never used in this file.

-import json
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@main.py` at line 5, Remove the unused top-level import "json" from the file
(the import statement "import json") so there are no unused imports in main.py;
simply delete that import line and run linters/tests to confirm nothing else
depends on the removed symbol.

15-18: In-memory storage will lose all data on restart.

The comment acknowledges this limitation, but consider logging a warning at startup or documenting the expected behavior. Users will lose their plan upgrades, referrals, and API keys whenever the bot restarts.

For production use, consider persisting to SQLite (minimal dependency) or Redis. At minimum, add a startup warning:

print("⚠️  WARNING: Using in-memory storage - all data will be lost on restart!")
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@main.py` around lines 15 - 18, Add a startup warning and short persistence
guidance to make the risks of the in-memory stores explicit: log/print a clear
warning at app startup indicating that user_data, otp_storage, and api_keys are
in-memory and will be lost on restart, and update any startup/docs/comment block
to recommend using SQLite or Redis for production. Locate the initialization of
the dictionaries (user_data, otp_storage, api_keys) and insert a single startup
warning (e.g., via print or logger.warning) plus a brief comment pointing to
persistence options.

407-412: Slash-command menu is not registered with Telegram.

The previous implementation called register_commands() from commands.py to register commands via bot.set_my_commands(). This is now missing, so users won't see command suggestions when typing / in the chat.

Proposed fix - add command registration before polling
 if __name__ == "__main__":
     print("🤖 HIT PRO Bot started!")
     print(f"🌐 Web App: {WEBAPP_URL}")
     print(f"👑 Admins: {ADMIN_IDS}")
+    
+    # Register commands with Telegram
+    from telebot.types import BotCommand
+    bot.set_my_commands([
+        BotCommand("start", "Start the bot"),
+        BotCommand("profile", "Your account info"),
+        BotCommand("otp", "Get login OTP"),
+        BotCommand("help", "Show all commands"),
+    ])
+    
     bot.infinity_polling()
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@main.py` around lines 407 - 412, The slash-command menu isn't registered
because register_commands() from commands.py is not being called before starting
the bot; call the register_commands() function (and ensure it's imported at top,
e.g., from commands import register_commands) immediately before
bot.infinity_polling(), so that register_commands() can call
bot.set_my_commands(...) to register the commands with Telegram; add error
handling/logging around register_commands() to surface registration failures if
needed.

146-150: OTP storage grows unbounded without cleanup.

Expired OTPs are never removed from otp_storage. For a long-running bot, this leads to unbounded memory growth. Consider adding cleanup logic when generating new OTPs or using a periodic cleanup task.

Proposed fix - add cleanup when generating OTP
 def send_otp(chat_id):
     user_id = chat_id
+    # Clean up expired OTPs
+    current_time = time.time()
+    expired_keys = [k for k, v in otp_storage.items() if v['expires'] < current_time]
+    for k in expired_keys:
+        del otp_storage[k]
+    
     otp = generate_otp()
     otp_storage[user_id] = {
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@main.py` around lines 146 - 150, otp_storage is being populated with entries
that never get removed, causing unbounded growth; update the OTP generation path
that assigns otp_storage[user_id] (the block using 'code', 'timestamp',
'expires' with time.time()) to first purge expired entries by iterating over
otp_storage and deleting any where entry['expires'] <= time.time() before
inserting the new OTP, or alternatively add a lightweight background cleanup
task that periodically scans otp_storage and deletes expired entries; ensure you
reference and update the same otp_storage structure and the fields
'expires'/'timestamp' so lookups and removals remain consistent.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@main.py`:
- Around line 53-57: Parse and validate the referral parameter before converting
to int: when extracting param from message.text (the code around param =
message.text.split()[1]) check that param.startswith('ref_') and that the
substring param[4:] consists only of digits (or use a try/except around
int(param[4:])); on invalid input catch ValueError (or skip/ log the bad param)
and only call handle_referral(user_id, referrer_id) when conversion succeeds so
handle_referral and referrer_id are never called with malformed data.
- Around line 24-28: The functions generate_otp and generate_api_key use
random.randint (Mersenne Twister) which is not cryptographically secure; import
the secrets module and replace random usage: for generate_otp produce a 6-digit
OTP with secrets (e.g., secrets.randbelow(900000) + 100000 or building from
secrets.choice on digits) and for generate_api_key use a secure token from
secrets (e.g., secrets.token_urlsafe or secrets.token_hex) combined with your
hitchk_ prefix and timestamp if needed; update imports to include secrets and
remove reliance on random for these two functions.
- Line 9: Remove the hardcoded Telegram token fallback by changing the BOT_TOKEN
constant to read only from the environment (os.getenv/os.environ) without a
default, and add a fail-fast check where BOT_TOKEN is used (e.g., at startup)
that raises an explicit error or exits if the env var is missing; update any
tests or deployment configs to provide the new token via environment or a
secrets manager, and ensure the exposed token is revoked and replaced outside
the codebase as part of the remediation.
- Around line 307-313: Replace the bare except and broad Exception handling
around the bot.send_message calls: catch the specific Telegram exception (e.g.,
telegram.error.Unauthorized or the library-specific exception thrown when a user
blocks the bot) for the inner try around bot.send_message(target_user, ...) and
handle it by logging a warning instead of pass; for the outer except around the
whole upgrade flow catch more specific exceptions where possible or catch
Exception as e but send a generic user-facing message via
bot.send_message(message.chat.id, "❌ An internal error occurred while upgrading
the plan.") and log the detailed error (using logging.exception or similar)
rather than exposing str(e) to the user; update code references: the inner
try/except protecting bot.send_message(target_user, ...) and the outer except
handling the overall upgrade flow.
- Around line 346-359: The broadcast handler currently slices message.text with
[11:] (fragile), spams bot.send_message to all user_data keys without rate
limiting, and uses a bare except that swallows errors; fix by parsing the
payload with message.text.split(maxsplit=1) to safely get broadcast_text (handle
missing second element with a usage reply), iterate user_data keys and throttle
sends to respect Telegram limits (e.g., sleep between sends or batch at
~30/sec), replace the bare except with a specific exception catch (e.g.,
telegram.error.TelegramError or Exception as e) and log the error before
incrementing failed, and keep updating sent/failed counters after each send
attempt so bot.send_message, broadcast_text, user_data, sent, and failed are
used consistently.

---

Nitpick comments:
In `@main.py`:
- Around line 386-392: Iterate user_data once to compute plan_counts,
total_referrals, top_referrer and max_refs in a single-pass (e.g., initialize
plan_counts = {'free':0,'silver':0,'gold':0}, total_referrals = 0, top_referrer
= 'None', max_refs = -1 and update inside a for uid, data in user_data.items()
loop), then replace the repeated list comprehensions in the output block with
references to plan_counts['free'], plan_counts['silver'], plan_counts['gold'],
total_referrals and top_referrer; ensure you handle the empty-user case so
top_referrer remains 'None' when user_data is empty.
- Line 5: Remove the unused top-level import "json" from the file (the import
statement "import json") so there are no unused imports in main.py; simply
delete that import line and run linters/tests to confirm nothing else depends on
the removed symbol.
- Around line 15-18: Add a startup warning and short persistence guidance to
make the risks of the in-memory stores explicit: log/print a clear warning at
app startup indicating that user_data, otp_storage, and api_keys are in-memory
and will be lost on restart, and update any startup/docs/comment block to
recommend using SQLite or Redis for production. Locate the initialization of the
dictionaries (user_data, otp_storage, api_keys) and insert a single startup
warning (e.g., via print or logger.warning) plus a brief comment pointing to
persistence options.
- Around line 407-412: The slash-command menu isn't registered because
register_commands() from commands.py is not being called before starting the
bot; call the register_commands() function (and ensure it's imported at top,
e.g., from commands import register_commands) immediately before
bot.infinity_polling(), so that register_commands() can call
bot.set_my_commands(...) to register the commands with Telegram; add error
handling/logging around register_commands() to surface registration failures if
needed.
- Around line 146-150: otp_storage is being populated with entries that never
get removed, causing unbounded growth; update the OTP generation path that
assigns otp_storage[user_id] (the block using 'code', 'timestamp', 'expires'
with time.time()) to first purge expired entries by iterating over otp_storage
and deleting any where entry['expires'] <= time.time() before inserting the new
OTP, or alternatively add a lightweight background cleanup task that
periodically scans otp_storage and deletes expired entries; ensure you reference
and update the same otp_storage structure and the fields 'expires'/'timestamp'
so lookups and removals remain consistent.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 15b82107-f29f-430a-9d05-449030479b42

📥 Commits

Reviewing files that changed from the base of the PR and between 5cfd740 and df9ef97.

📒 Files selected for processing (1)
  • main.py

Comment thread main.py
from telebot import types

# Configuration
BOT_TOKEN = os.getenv('TELEGRAM_BOT_TOKEN', '8742056784:AAHzOGPUiuhqyi7pIWrPSiBWwtF0LTgAd3M')

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Critical: Hardcoded bot token must be removed immediately.

This line contains what appears to be a real Telegram Bot API token as a fallback default. Once committed, this secret is exposed in version control history and can be used by anyone to hijack the bot.

  1. Revoke this token immediately via @BotFather
  2. Generate a new token
  3. Remove the hardcoded fallback entirely
Proposed fix
-BOT_TOKEN = os.getenv('TELEGRAM_BOT_TOKEN', '8742056784:AAHzOGPUiuhqyi7pIWrPSiBWwtF0LTgAd3M')
+BOT_TOKEN = os.getenv('TELEGRAM_BOT_TOKEN')
+if not BOT_TOKEN:
+    raise RuntimeError("TELEGRAM_BOT_TOKEN environment variable is required")
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
BOT_TOKEN = os.getenv('TELEGRAM_BOT_TOKEN', '8742056784:AAHzOGPUiuhqyi7pIWrPSiBWwtF0LTgAd3M')
BOT_TOKEN = os.getenv('TELEGRAM_BOT_TOKEN')
if not BOT_TOKEN:
raise RuntimeError("TELEGRAM_BOT_TOKEN environment variable is required")
🧰 Tools
🪛 Betterleaks (1.1.1)

[high] 9-9: Detected a Telegram Bot API Token, risking unauthorized bot operations and message interception on Telegram.

(telegram-bot-api-token)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@main.py` at line 9, Remove the hardcoded Telegram token fallback by changing
the BOT_TOKEN constant to read only from the environment (os.getenv/os.environ)
without a default, and add a fail-fast check where BOT_TOKEN is used (e.g., at
startup) that raises an explicit error or exits if the env var is missing;
update any tests or deployment configs to provide the new token via environment
or a secrets manager, and ensure the exposed token is revoked and replaced
outside the codebase as part of the remediation.

Comment thread main.py
Comment on lines +24 to +28
def generate_otp():
return str(random.randint(100000, 999999))

def generate_api_key():
return f"hitchk_{random.randint(100000, 999999)}_{int(time.time())}"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Use cryptographically secure random generation for OTPs and API keys.

random.randint() uses a predictable PRNG (Mersenne Twister). OTPs and API keys are security-sensitive and should use the secrets module instead.

Proposed fix

Add import at top of file:

import secrets

Then update the functions:

 def generate_otp():
-    return str(random.randint(100000, 999999))
+    return f"{secrets.randbelow(900000) + 100000}"

 def generate_api_key():
-    return f"hitchk_{random.randint(100000, 999999)}_{int(time.time())}"
+    return f"hitchk_{secrets.token_hex(8)}_{int(time.time())}"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
def generate_otp():
return str(random.randint(100000, 999999))
def generate_api_key():
return f"hitchk_{random.randint(100000, 999999)}_{int(time.time())}"
def generate_otp():
return f"{secrets.randbelow(900000) + 100000}"
def generate_api_key():
return f"hitchk_{secrets.token_hex(8)}_{int(time.time())}"
🧰 Tools
🪛 Ruff (0.15.7)

[error] 25-25: Standard pseudo-random generators are not suitable for cryptographic purposes

(S311)


[error] 28-28: Standard pseudo-random generators are not suitable for cryptographic purposes

(S311)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@main.py` around lines 24 - 28, The functions generate_otp and
generate_api_key use random.randint (Mersenne Twister) which is not
cryptographically secure; import the secrets module and replace random usage:
for generate_otp produce a 6-digit OTP with secrets (e.g.,
secrets.randbelow(900000) + 100000 or building from secrets.choice on digits)
and for generate_api_key use a secure token from secrets (e.g.,
secrets.token_urlsafe or secrets.token_hex) combined with your hitchk_ prefix
and timestamp if needed; update imports to include secrets and remove reliance
on random for these two functions.

Comment thread main.py
Comment on lines +53 to +57
if len(message.text.split()) > 1:
param = message.text.split()[1]
if param.startswith('ref_'):
referrer_id = int(param[4:])
handle_referral(user_id, referrer_id)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Add error handling for referral parameter parsing.

int(param[4:]) will raise ValueError if the referral parameter contains non-numeric characters (e.g., /start ref_abc), causing the handler to fail silently or raise an unhandled exception.

Proposed fix
     if len(message.text.split()) > 1:
         param = message.text.split()[1]
         if param.startswith('ref_'):
-            referrer_id = int(param[4:])
-            handle_referral(user_id, referrer_id)
+            try:
+                referrer_id = int(param[4:])
+                handle_referral(user_id, referrer_id)
+            except ValueError:
+                pass  # Invalid referral link format, ignore
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@main.py` around lines 53 - 57, Parse and validate the referral parameter
before converting to int: when extracting param from message.text (the code
around param = message.text.split()[1]) check that param.startswith('ref_') and
that the substring param[4:] consists only of digits (or use a try/except around
int(param[4:])); on invalid input catch ValueError (or skip/ log the bad param)
and only call handle_referral(user_id, referrer_id) when conversion succeeds so
handle_referral and referrer_id are never called with malformed data.

Comment thread main.py
Comment on lines +307 to +313
try:
bot.send_message(target_user, f"🎉 **Plan Upgraded!**\n\nYour plan: {plan_emoji[new_plan]} **{new_plan.upper()}**\n\nEnjoy your new features!")
except:
pass # User might have blocked the bot

except Exception as e:
bot.send_message(message.chat.id, f"❌ Error: {str(e)}")

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Improve exception handling - avoid bare except and overly broad catches.

Lines 309-310 use bare except: pass which silently swallows all errors including programming errors. Lines 312-313 catch Exception broadly and expose internal error messages to users.

Proposed fix
         try:
             bot.send_message(target_user, f"🎉 **Plan Upgraded!**\n\nYour plan: {plan_emoji[new_plan]} **{new_plan.upper()}**\n\nEnjoy your new features!")
-        except:
-            pass  # User might have blocked the bot
+        except telebot.apihelper.ApiException:
+            pass  # User blocked bot or chat not found
         
-    except Exception as e:
-        bot.send_message(message.chat.id, f"❌ Error: {str(e)}")
+    except ValueError:
+        bot.send_message(message.chat.id, "❌ Invalid user ID format")
🧰 Tools
🪛 Ruff (0.15.7)

[error] 309-309: Do not use bare except

(E722)


[error] 309-310: try-except-pass detected, consider logging the exception

(S110)


[warning] 312-312: Do not catch blind exception: Exception

(BLE001)


[warning] 313-313: Use explicit conversion flag

Replace with conversion flag

(RUF010)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@main.py` around lines 307 - 313, Replace the bare except and broad Exception
handling around the bot.send_message calls: catch the specific Telegram
exception (e.g., telegram.error.Unauthorized or the library-specific exception
thrown when a user blocks the bot) for the inner try around
bot.send_message(target_user, ...) and handle it by logging a warning instead of
pass; for the outer except around the whole upgrade flow catch more specific
exceptions where possible or catch Exception as e but send a generic user-facing
message via bot.send_message(message.chat.id, "❌ An internal error occurred
while upgrading the plan.") and log the detailed error (using logging.exception
or similar) rather than exposing str(e) to the user; update code references: the
inner try/except protecting bot.send_message(target_user, ...) and the outer
except handling the overall upgrade flow.

Comment thread main.py
Comment on lines +346 to +359
broadcast_text = message.text[11:] # Remove '/broadcast '
if not broadcast_text:
bot.send_message(message.chat.id, "Usage: `/broadcast [your message]`", parse_mode='Markdown')
return

sent = 0
failed = 0

for user_id in user_data.keys():
try:
bot.send_message(user_id, f"📢 **HIT PRO Announcement**\n\n{broadcast_text}", parse_mode='Markdown')
sent += 1
except:
failed += 1

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Broadcast implementation has fragile parsing and missing rate limiting.

  1. Line 346 uses hardcoded offset [11:] - fragile if command format changes. Use message.text.split(maxsplit=1) instead.
  2. No rate limiting between messages - Telegram enforces ~30 messages/second limit, which will cause failures for larger user bases.
  3. Bare except on line 358 swallows all errors silently.
Proposed fix
     try:
-        broadcast_text = message.text[11:]  # Remove '/broadcast '
+        parts = message.text.split(maxsplit=1)
+        broadcast_text = parts[1] if len(parts) > 1 else ""
         if not broadcast_text:
             bot.send_message(message.chat.id, "Usage: `/broadcast [your message]`", parse_mode='Markdown')
             return
         
         sent = 0
         failed = 0
         
         for user_id in user_data.keys():
             try:
                 bot.send_message(user_id, f"📢 **HIT PRO Announcement**\n\n{broadcast_text}", parse_mode='Markdown')
                 sent += 1
-            except:
+                time.sleep(0.05)  # Rate limit: ~20 msgs/sec
+            except telebot.apihelper.ApiException:
                 failed += 1
🧰 Tools
🪛 Ruff (0.15.7)

[error] 358-358: Do not use bare except

(E722)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@main.py` around lines 346 - 359, The broadcast handler currently slices
message.text with [11:] (fragile), spams bot.send_message to all user_data keys
without rate limiting, and uses a bare except that swallows errors; fix by
parsing the payload with message.text.split(maxsplit=1) to safely get
broadcast_text (handle missing second element with a usage reply), iterate
user_data keys and throttle sends to respect Telegram limits (e.g., sleep
between sends or batch at ~30/sec), replace the bare except with a specific
exception catch (e.g., telegram.error.TelegramError or Exception as e) and log
the error before incrementing failed, and keep updating sent/failed counters
after each send attempt so bot.send_message, broadcast_text, user_data, sent,
and failed are used consistently.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant