Repository navigation
Refactor Telegram bot to fetch hot Solana pairs - #37
drzhivago123 wants to merge 1 commit into
Conversation
📝 WalkthroughWalkthroughThe bot implementation has been completely rewritten. It now fetches Solana token data from Dexscreener API, filters by liquidity and trading metrics, ranks by a computed score, and presents the top 5 tokens via a menu-driven interface. Error handling has shifted from startup-time blocking to runtime responses. Changes
Sequence DiagramsequenceDiagram
actor User
participant Bot as Telegram Bot
participant API as Dexscreener API
participant Filter as Token Filter & Score
User->>Bot: Click "🔥 Hot Solana Picks"
activate Bot
Bot->>API: GET /dexscreener/latest/pairs/solana?skip=0
activate API
API-->>Bot: pairs[] (all Solana tokens)
deactivate API
Bot->>Filter: Filter by liquidity, 5m volume, price change
activate Filter
Filter->>Filter: Compute score for each pair
Filter->>Filter: Sort by score (descending)
Filter-->>Bot: Top 5 tokens
deactivate Filter
Bot-->>User: Display ranked list + main menu
deactivate Bot
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~22 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 (3)
main.py (3)
119-119: Wrap polling in__main__guard for testability.Calling
bot.infinity_polling()at module level means the bot starts immediately on import, preventing unit testing or reuse of the module's functions.♻️ 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 which prevents importing for tests; move that call into a guarded entrypoint: create a main() function that calls bot.infinity_polling() and wrap its invocation in if __name__ == "__main__": main(). Update any startup logic tied to bot.infinity_polling() accordingly so tests can import functions/classes without starting the bot automatically.
82-91: Consider batching messages to avoid potential rate limits.Sending up to 5 individual messages in rapid succession could trigger Telegram's rate limiting. Consider combining results into a single formatted message.
♻️ Proposed batched message approach
- for idx, token in enumerate(results, start=1): - msg = ( - f"#{idx} {token['name']} ({token['symbol']})\n" - f"Price: ${token['price']}\n" - f"Liquidity: ${token['liquidity']:,.0f}\n" - f"5m Volume: ${token['volume_5m']:,.0f}\n" - f"5m Change: {token['price_change_5m']:.2f}%\n" - f"Chart: {token['url']}" - ) - bot.send_message(message.chat.id, msg) + lines = [] + for idx, token in enumerate(results, start=1): + lines.append( + f"#{idx} {token['name']} ({token['symbol']})\n" + f"💰 Price: ${token['price']}\n" + f"💧 Liquidity: ${token['liquidity']:,.0f}\n" + f"📊 5m Volume: ${token['volume_5m']:,.0f}\n" + f"📈 5m Change: {token['price_change_5m']:.2f}%\n" + f"🔗 {token['url']}" + ) + bot.send_message(message.chat.id, "\n\n".join(lines))🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@main.py` around lines 82 - 91, The loop sending individual messages (for idx, token in enumerate(results, start=1): ... bot.send_message(message.chat.id, msg)) can hit Telegram rate limits; instead build a single formatted string by iterating over results and appending each token's formatted block (include idx, token['name'], token['symbol'], price, liquidity, volume_5m, price_change_5m, url) into one message body, then call bot.send_message once to message.chat.id; ensure you respect Telegram max message length (chunk into multiple batched messages if the combined string exceeds the API limit) and reuse the same send operation rather than multiple sends in the loop.
42-43: Silent exception swallowing hinders debugging.Catching all exceptions and continuing without any logging makes it difficult to diagnose issues with malformed pair data. Consider logging the exception or at least the pair identifier that failed parsing.
♻️ Proposed fix to add logging
+import logging + +logger = logging.getLogger(__name__)Then in the exception handler:
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 catch-all "except Exception:" in main.py with "except Exception as e:" and log the error and the related pair identifier before continuing; e.g., call an existing logger (logger.exception or logger.error) with a message that includes the pair variable name used in the parsing loop (e.g., pair or pair_id) and the exception (or stack trace); if no logger exists, write the same information to stderr so malformed pair data failures are visible while still continuing.
🤖 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: Validate the TELEGRAM_BOT_TOKEN before constructing TeleBot:
check the TOKEN returned from os.getenv("TELEGRAM_BOT_TOKEN") is non-empty, and
if not, log an explicit error or raise SystemExit (e.g., use logging.error(...)
and sys.exit(1) or raise RuntimeError) so TeleBot(TOKEN) is never called with
None; update the initialization around TOKEN and TeleBot(TOKEN) to perform this
check and provide a clear failure message including that the TELEGRAM_BOT_TOKEN
environment variable is missing or invalid.
---
Nitpick comments:
In `@main.py`:
- Line 119: The module currently calls bot.infinity_polling() at import time
which prevents importing for tests; move that call into a guarded entrypoint:
create a main() function that calls bot.infinity_polling() and wrap its
invocation in if __name__ == "__main__": main(). Update any startup logic tied
to bot.infinity_polling() accordingly so tests can import functions/classes
without starting the bot automatically.
- Around line 82-91: The loop sending individual messages (for idx, token in
enumerate(results, start=1): ... bot.send_message(message.chat.id, msg)) can hit
Telegram rate limits; instead build a single formatted string by iterating over
results and appending each token's formatted block (include idx, token['name'],
token['symbol'], price, liquidity, volume_5m, price_change_5m, url) into one
message body, then call bot.send_message once to message.chat.id; ensure you
respect Telegram max message length (chunk into multiple batched messages if the
combined string exceeds the API limit) and reuse the same send operation rather
than multiple sends in the loop.
- Around line 42-43: Replace the silent catch-all "except Exception:" in main.py
with "except Exception as e:" and log the error and the related pair identifier
before continuing; e.g., call an existing logger (logger.exception or
logger.error) with a message that includes the pair variable name used in the
parsing loop (e.g., pair or pair_id) and the exception (or stack trace); if no
logger exists, write the same information to stderr so malformed pair data
failures are visible while still continuing.
| 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, and TeleBot(None) will fail with a cryptic error during polling or when sending messages. Validate the token at startup for a clear failure mode.
🛡️ Proposed fix to add validation
TOKEN = os.getenv("TELEGRAM_BOT_TOKEN")
+if not TOKEN:
+ raise RuntimeError("TELEGRAM_BOT_TOKEN environment variable is not set")
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 not set") | |
| 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, Validate the TELEGRAM_BOT_TOKEN before
constructing TeleBot: check the TOKEN returned from
os.getenv("TELEGRAM_BOT_TOKEN") is non-empty, and if not, log an explicit error
or raise SystemExit (e.g., use logging.error(...) and sys.exit(1) or raise
RuntimeError) so TeleBot(TOKEN) is never called with None; update the
initialization around TOKEN and TeleBot(TOKEN) to perform this check and provide
a clear failure message including that the TELEGRAM_BOT_TOKEN environment
variable is missing or invalid.
Make better roi
Summary by CodeRabbit
New Features
Improvements