Alerting via Telegram

A bot running unattended needs to reach you when something needs attention — Telegram is a common choice: free, fast, works from your phone, simple HTTP API.

Setup

  1. Message @BotFather on Telegram, run /newbot, get a bot token.
  2. Message your new bot once (anything) so it can message you back.
  3. Get your chat ID: https://api.telegram.org/bot<TOKEN>/getUpdates after sending a message — find "chat":{"id": ...} in the response.
# alerts.py
import requests

TELEGRAM_BOT_TOKEN = "your_bot_token"
TELEGRAM_CHAT_ID = "your_chat_id"

def send_alert(message: str, urgent: bool = False):
    prefix = "🚨 " if urgent else "ℹ️ "
    url = f"https://api.telegram.org/bot{TELEGRAM_BOT_TOKEN}/sendMessage"
    try:
        requests.post(url, json={"chat_id": TELEGRAM_CHAT_ID, "text": prefix + message}, timeout=5)
    except requests.RequestException:
        logging.error("Failed to send Telegram alert — falling back to log only")

What deserves an alert vs. what deserves only a log line

Alert fatigue is real — if every routine event pages you, you'll start ignoring the channel entirely, defeating its purpose. Rough guideline:

Alert (interrupts you)Log only (review later)
Kill switch triggeredNormal order placed/filled
Order rejectedRoutine reconciliation check passed
Daily loss limit breachedSignal evaluated, no action taken
WebSocket repeatedly failing to reconnectPosition P&L update
Access token expired, re-auth neededSuccessful daily square-off
def send_alert_if_significant(event_type: str, **fields):
    SIGNIFICANT = {"order_rejected", "kill_switch_triggered", "daily_loss_breached", "feed_stale", "auth_expired"}
    log_event(event_type, **fields)   # always log
    if event_type in SIGNIFICANT:
        send_alert(f"{event_type}: {json.dumps(fields)}", urgent=True)

Two-way — Telegram can also trigger actions (with strong safeguards)

def handle_telegram_command(update: dict):
    text = update["message"]["text"]
    chat_id = str(update["message"]["chat"]["id"])
    if chat_id != TELEGRAM_CHAT_ID:
        return   # ignore commands from anyone but you
    if text == "/status":
        send_alert(get_bot_status_summary())
    elif text == "/killswitch":
        kill_switch.trigger(KillLevel.FLATTEN_ALL, "Manual trigger via Telegram")

The chat_id check is not optional — without it, anyone who discovers your bot's token (e.g. leaked in a public repo) could send commands that your bot acts on. Treat the bot token with the same care as any other secret (chapter 6).

Next: 092 — Heartbeat and API downtime handling