Repository navigation
Refactor Telegram bot to fetch hot Solana pairs - #38
drzhivago123 wants to merge 1 commit into
Conversation
📝 WalkthroughWalkthroughRefactors Telegram bot initialization to use a simplified flow. Removes the echo-all message behavior and Changes
Sequence DiagramsequenceDiagram
participant User as User (Telegram)
participant Bot as Telegram Bot
participant API as Dexscreener API
User->>Bot: Click "🔥 Hot Solana Picks" button
Bot->>API: GET /dex/tokens/solana
API-->>Bot: JSON response with Solana pairs data
Bot->>Bot: Filter by liquidity, volume, price-change
Bot->>Bot: Compute ranking score & sort
Bot-->>User: Send top 5 hot picks (or error message)
Estimated code review effort🎯 2 (Simple) | ⏱️ ~12 minutes Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (4)
main.py (4)
119-119: Addif __name__ == "__main__":guard.
bot.infinity_polling()runs at import time, which prevents importing this module for testing or reuse without starting the bot.♻️ Proposed fix
-bot.infinity_polling() +if __name__ == "__main__": + bot.infinity_polling()🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@main.py` at line 119, The module currently calls bot.infinity_polling() at import time; wrap that call in a main guard by moving bot.infinity_polling() inside an if __name__ == "__main__": block so the bot only starts when the script is executed directly (locate the existing bot.infinity_polling() invocation and enclose it in the guard).
45-49: Inconsistent return type: list vs dict.
get_hot_pairs()returns a list on success but a dict on error. This forces the caller to useisinstance()checks. Consider raising an exception or returning an empty list with logged error for consistency.♻️ Proposed fix using exception
except Exception as e: - return {"error": str(e)} + logger.error("Failed to fetch hot pairs: %s", e) + raiseThen update the handler:
def hot_picks_handler(message): bot.send_message(message.chat.id, "Scanning Solana pairs...") - results = get_hot_pairs() - - if isinstance(results, dict) and results.get("error"): - bot.send_message(message.chat.id, f"Error fetching market data:\n{results['error']}") - return + try: + results = get_hot_pairs() + except Exception as e: + bot.send_message(message.chat.id, f"Error fetching market data:\n{e}") + return🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@main.py` around lines 45 - 49, get_hot_pairs() currently returns a list on success but a dict on error; change it to raise the caught exception instead of returning {"error": str(e)} so the return type stays a list on success and errors are handled via exceptions. Replace the "return {"error": ...}" in get_hot_pairs() with "raise" (propagate the exception) and update the calling code (the request handler or whichever function invokes get_hot_pairs()) to catch exceptions, log the error, and return an appropriate HTTP response or an empty list as the API contract requires.
59-65: Consider cleaning up orphanedcommands.pyand registering commands.The
commands.pymodule (which definesregister_commands()) is no longer imported or called, leaving it as dead code. Additionally, without callingbot.set_my_commands(), Telegram's command autocomplete menu won't show available commands to users.Either:
- Delete
commands.pyif command registration is not needed- Or register the
/startcommand for Telegram's autocomplete:from telebot.types import BotCommand bot.set_my_commands([BotCommand("start", "Start the bot")])🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@main.py` around lines 59 - 65, The commands.py module (and its register_commands()) is orphaned or command registration is missing; either remove commands.py if unused, or import and call register_commands() at startup and explicitly register Telegram commands by calling bot.set_my_commands(...) with a list of telebot.types.BotCommand entries (e.g. for "start") so the /start command (handled by start_handler) appears in Telegram's autocomplete; update the main bootstrap to perform this registration before the bot starts polling.
42-43: Silent exception swallowing hinders debugging.When parsing fails for a pair, the exception is silently discarded. Consider logging the exception for debugging purposes, especially in a bot context where issues may be hard to reproduce.
♻️ Proposed fix
+import logging + +logger = logging.getLogger(__name__)Then in the function:
except Exception: - continue + logger.debug("Skipping malformed pair data: %s", p.get("pairAddress", "unknown")) + continue🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@main.py` around lines 42 - 43, Replace the silent broad except that just does "except Exception: continue" with logging of the exception and contextual data before continuing: catch Exception as e (the same except block), call logger.exception or logging.exception with a message that includes the relevant parsing item identifier (e.g., the pair variable or input being parsed) and the exception, then continue; update the except block inside the function that contains the "except Exception: continue" to ensure errors are recorded (use logger.exception("Failed parsing pair %s", pair, exc_info=True) or equivalent).
🤖 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 5-6: The code currently passes TOKEN =
os.getenv("TELEGRAM_BOT_TOKEN") directly into TeleBot(TOKEN) which will raise a
cryptic error when the env var is missing; add an explicit validation after
retrieving TOKEN (before calling TeleBot) that checks if TOKEN is None or empty
and fail fast with a clear message (raise SystemExit or ValueError or log and
sys.exit) indicating that TELEGRAM_BOT_TOKEN is not set, so the TeleBot(...)
call only runs with a valid token.
---
Nitpick comments:
In `@main.py`:
- Line 119: The module currently calls bot.infinity_polling() at import time;
wrap that call in a main guard by moving bot.infinity_polling() inside an if
__name__ == "__main__": block so the bot only starts when the script is executed
directly (locate the existing bot.infinity_polling() invocation and enclose it
in the guard).
- Around line 45-49: get_hot_pairs() currently returns a list on success but a
dict on error; change it to raise the caught exception instead of returning
{"error": str(e)} so the return type stays a list on success and errors are
handled via exceptions. Replace the "return {"error": ...}" in get_hot_pairs()
with "raise" (propagate the exception) and update the calling code (the request
handler or whichever function invokes get_hot_pairs()) to catch exceptions, log
the error, and return an appropriate HTTP response or an empty list as the API
contract requires.
- Around line 59-65: The commands.py module (and its register_commands()) is
orphaned or command registration is missing; either remove commands.py if
unused, or import and call register_commands() at startup and explicitly
register Telegram commands by calling bot.set_my_commands(...) with a list of
telebot.types.BotCommand entries (e.g. for "start") so the /start command
(handled by start_handler) appears in Telegram's autocomplete; update the main
bootstrap to perform this registration before the bot starts polling.
- Around line 42-43: Replace the silent broad except that just does "except
Exception: continue" with logging of the exception and contextual data before
continuing: catch Exception as e (the same except block), call logger.exception
or logging.exception with a message that includes the relevant parsing item
identifier (e.g., the pair variable or input being parsed) and the exception,
then continue; update the except block inside the function that contains the
"except Exception: continue" to ensure errors are recorded (use
logger.exception("Failed parsing pair %s", pair, exc_info=True) or equivalent).
| TOKEN = os.getenv("TELEGRAM_BOT_TOKEN") | ||
| bot = TeleBot(TOKEN) |
There was a problem hiding this comment.
Missing validation for TELEGRAM_BOT_TOKEN environment variable.
If TELEGRAM_BOT_TOKEN is not set, TOKEN will be None, causing TeleBot(None) to fail with a cryptic error at runtime. Add validation to fail fast with a clear message.
🛡️ Proposed fix
TOKEN = os.getenv("TELEGRAM_BOT_TOKEN")
+if not TOKEN:
+ raise RuntimeError("TELEGRAM_BOT_TOKEN environment variable is required")
bot = TeleBot(TOKEN)📝 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.
| TOKEN = os.getenv("TELEGRAM_BOT_TOKEN") | |
| bot = TeleBot(TOKEN) | |
| TOKEN = os.getenv("TELEGRAM_BOT_TOKEN") | |
| if not TOKEN: | |
| raise RuntimeError("TELEGRAM_BOT_TOKEN environment variable is required") | |
| bot = TeleBot(TOKEN) |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@main.py` around lines 5 - 6, The code currently passes TOKEN =
os.getenv("TELEGRAM_BOT_TOKEN") directly into TeleBot(TOKEN) which will raise a
cryptic error when the env var is missing; add an explicit validation after
retrieving TOKEN (before calling TeleBot) that checks if TOKEN is None or empty
and fail fast with a clear message (raise SystemExit or ValueError or log and
sys.exit) indicating that TELEGRAM_BOT_TOKEN is not set, so the TeleBot(...)
call only runs with a valid token.
Summary by CodeRabbit
Release Notes
New Features
Bug Fixes