TELEGRAM BOT INTEGRATION
IndiPoli can mirror significant notifications (trade confirmed / failed, auto-mode opportunity created, killswitch toggled) to a Telegram chat via your own bot. This is useful if you don’t use Web Push or just want a searchable log of every trade event in a dedicated channel.
1. CREATE A BOT VIA @BotFather
- In Telegram, search for
@BotFatherand open the chat. - Send
/newbot. - Give it a display name (e.g. My IndiPoli Alerts).
- Give it a username ending in
bot(e.g.my_indipoli_alerts_bot). Must be globally unique. - BotFather replies with a message containing a bot token in the form
123456789:ABCdef.... Copy it — treat it like a password.
2. GET YOUR CHAT ID
The bot needs to know which chat to message. For a personal one-to-one setup:
- Open a chat with your new bot (click the link BotFather sent, or search the username).
- Send the bot
/start. This unlocks the bot — bots can only DM users who started the conversation. - In a browser, visit (replace
YOUR_TOKEN):https://api.telegram.org/botYOUR_TOKEN/getUpdates - Look for the
"chat":{"id": 123456789, ...}block in the JSON response. That number is your chat id.
For a group chat: add the bot to the group, send any message, then hit the
same /getUpdates URL. Group chat ids are negative integers
(e.g. -1001234567890).
3. PASTE THE TOKEN + CHAT ID INTO SETTINGS
- Log in to IndiPoli.
- Go to /settings/telegram.
- Paste the bot token into the Token field. It is encrypted at rest with the same libsodium AEAD used for Moodix / Polymarket / LLM credentials.
- Paste the chat id into the Chat ID field. This is stored in plaintext — it is not a secret.
- Tick Enabled.
- Click Save, then Test Connection.
- You should immediately receive a test message in the configured chat: “Hello from IndiPoli”. If you don’t, see the troubleshooting section.
WHICH EVENTS DO I GET?
- Trade confirmed — CLOB order accepted; message includes market title, side, size.
- Trade failed — CLOB order rejected or receipt mismatched; message includes reason.
- Auto-mode opportunity created — only when the opportunity crosses your min-auto-probability threshold. Manual-mode opportunities are not sent (they’d be spam).
- Killswitch toggled — on or off.
These are the same events that trigger Web Push (if you have both enabled, you get both). They all funnel through the same event broker, so one notification in never produces duplicate Telegram messages.
RATE LIMITING
IndiPoli routes outgoing Telegram requests through its Phase 2 rate limiter
bucket (RATE_TELEGRAM_PER_MIN, default 30). Telegram’s
hard limit is 30 messages/second globally, 20/minute per group, 1/second per
user — if you hit the server limit the bucket will back off and drop
the message rather than crash the notification pipeline.
TROUBLESHOOTING
- “Forbidden: bot was blocked by the user”. You blocked the bot in Telegram. Unblock and retry Test Connection.
- “Chat not found”. The chat id is wrong, or the bot was never sent
/startin that chat. Re-do step 2. - “Unauthorized”. The token is wrong or has been revoked via
/revokein BotFather. Create a new token and re-paste. - Test succeeds but real events never arrive. Check the Enabled checkbox is on, then tail
var/log/app.logforTelegramClienterrors. Notification failures never break the main notification flow by design. - HTML/Markdown formatting in messages. IndiPoli sends plaintext only — no parse_mode. If you want rich formatting, fork the TelegramClient.
SECURITY NOTES
Anyone with your bot token can DM your chat as the bot. Treat it like any
other API key. If you suspect it has leaked, open @BotFather and send
/revoke to rotate the token — then paste the new one
into /settings/telegram.
The chat id is not a secret. But if you run a multi-tenant instance, other
tenants cannot see your chat id — the user_credentials
table is tenant-scoped and every read enforces tenant_id = :tenant_id.