Skip to content

feat: optional async Telegram notifications for bot monitoring#4

Open
matteocelani wants to merge 8 commits into
strongca22-cpu:mainfrom
matteocelani:feature/telegram-alerts
Open

feat: optional async Telegram notifications for bot monitoring#4
matteocelani wants to merge 8 commits into
strongca22-cpu:mainfrom
matteocelani:feature/telegram-alerts

Conversation

@matteocelani

Copy link
Copy Markdown

Summary

Adds a comprehensive, non-blocking Telegram notification system to monitor the bot in real-time.

Changes

  • New file: src/telegram_notifier.py — async Telegram client with retry logic
  • src/main.py — startup and graceful shutdown alerts
  • strategies/gabagool_strategy.py — order failure alerts (YES/NO side) with full error context
  • src/client.py — enriched ApiError with status_code and response_body fields
  • src/bot.py — re-raise exceptions from place_order() instead of silently returning None

Notifications sent

Event Message
Bot started 🚀 mode (LIVE/DRY RUN) + config summary
Bot stopped 🛑 reason
YES order failed ❌ market, prices, margin, exact HTTP error body
NO order failed ❌ critical alert (YES leg already open)
Periodic status ⏱️ every ~13 min: positions, exposure, P&L

Configuration

Set TELEGRAM_BOT_TOKEN and TELEGRAM_CHAT_ID in config/.env. Fully optional — if not configured, the bot runs normally without notifications.

matteocelani and others added 8 commits May 13, 2026 10:31
The bot places GTC limit orders (Good-Til-Cancelled), not market orders.
Make this explicit in user-facing messages and add a quick link to the
configured Polymarket profile so the operator can verify positions/orders
directly from each notification.

- send_bot_started / send_status_update: state that orders are GTC limit
- send_arbitrage_executed: tag the trade as "GTC Limit (YES + NO)"
- send_order_failed: tag as "GTC Limit" + expand common causes (insufficient
  balance, invalid tick size, maker/signer mismatch, geo-block 403)
- New helper _profile_line(): reads POLY_SAFE_ADDRESS and builds a clickable
  https://polymarket.com/it/profile/<addr> link, included in start/status/
  trade messages when the env var is set.
- send_telegram_sync: disable_web_page_preview=true to keep messages compact.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Replace the generic list of "common causes" appended to every order-failed
alert with a single one-line interpretation derived from the actual error
message. If no pattern matches, just show the raw error without padding.

Patterns recognised:
- cancel-only / cancel only       → Polymarket in maintenance, will resume
- insufficient balance            → funder wallet has not enough pUSD
- invalid tick size               → price not aligned to market tick
- maker address not allowed       → wrong signature_type/funder combo
- signer / api key mismatch       → API key bound to a different signer
- orderbook does not exist        → market closed or paused
- trading restricted / geo / 403  → geo-block, VPN required
- 503 + service                   → Polymarket temporarily unavailable

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Resolve the internal Polymarket market id to its event URL by hitting the
Gamma API to retrieve the market slug, then render the 🎯 Market line as a
clickable link to https://polymarket.com/it/event/<slug>.

The lookup runs via asyncio.to_thread() so the event loop is never blocked.
Falls back to the plain short id when the slug cannot be resolved.

Applied to:
- send_order_failed: link to the offending market
- send_arbitrage_executed: link to the market where the trade landed

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
When Gamma returns the market 'question' field (e.g. "BTC up/down 5m"),
display that text as the clickable label of the 🎯 Market line instead of
the raw numeric id. Falls back to the truncated id when the question is
unavailable.

- _resolve_market_url -> _resolve_market_info: now returns (url, question)
- _market_line: prefers the question text (truncated to 60 chars) over the id
- Both send_arbitrage_executed and send_order_failed updated accordingly

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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