From 11aa44d34d13af1f15eb0642276cd223879b6c5d Mon Sep 17 00:00:00 2001 From: Teknium <127238744+teknium1@users.noreply.github.com> Date: Mon, 30 Mar 2026 17:21:59 -0700 Subject: [PATCH] docs(telegram): add webhook mode documentation (#4089) Documents the Telegram webhook mode from #3880: - New 'Webhook Mode' section in telegram.md with polling vs webhook comparison, config table, Fly.io deployment example, troubleshooting - Add TELEGRAM_WEBHOOK_URL/PORT/SECRET to environment-variables.md - Add Telegram section to .env.example (existing + webhook vars) Co-authored-by: raulbcs --- .env.example | 15 +++++ .../docs/reference/environment-variables.md | 3 + website/docs/user-guide/messaging/telegram.md | 61 +++++++++++++++++++ 3 files changed, 79 insertions(+) diff --git a/.env.example b/.env.example index bcb5708d6..3df76497e 100644 --- a/.env.example +++ b/.env.example @@ -231,6 +231,21 @@ VOICE_TOOLS_OPENAI_KEY= # Slack allowed users (comma-separated Slack user IDs) # SLACK_ALLOWED_USERS= +# ============================================================================= +# TELEGRAM INTEGRATION +# ============================================================================= +# Telegram Bot Token - From @BotFather (https://t.me/BotFather) +# TELEGRAM_BOT_TOKEN= +# TELEGRAM_ALLOWED_USERS= # Comma-separated user IDs +# TELEGRAM_HOME_CHANNEL= # Default chat for cron delivery +# TELEGRAM_HOME_CHANNEL_NAME= # Display name for home channel + +# Webhook mode (optional — for cloud deployments like Fly.io/Railway) +# Default is long polling. Setting TELEGRAM_WEBHOOK_URL switches to webhook mode. +# TELEGRAM_WEBHOOK_URL=https://my-app.fly.dev/telegram +# TELEGRAM_WEBHOOK_PORT=8443 +# TELEGRAM_WEBHOOK_SECRET= # Recommended for production + # WhatsApp (built-in Baileys bridge — run `hermes whatsapp` to pair) # WHATSAPP_ENABLED=false # WHATSAPP_ALLOWED_USERS=15551234567 diff --git a/website/docs/reference/environment-variables.md b/website/docs/reference/environment-variables.md index d94121481..fd57ffb02 100644 --- a/website/docs/reference/environment-variables.md +++ b/website/docs/reference/environment-variables.md @@ -153,6 +153,9 @@ For native Anthropic auth, Hermes prefers Claude Code's own credential files whe | `TELEGRAM_ALLOWED_USERS` | Comma-separated user IDs allowed to use the bot | | `TELEGRAM_HOME_CHANNEL` | Default Telegram chat/channel for cron delivery | | `TELEGRAM_HOME_CHANNEL_NAME` | Display name for the Telegram home channel | +| `TELEGRAM_WEBHOOK_URL` | Public HTTPS URL for webhook mode (enables webhook instead of polling) | +| `TELEGRAM_WEBHOOK_PORT` | Local listen port for webhook server (default: `8443`) | +| `TELEGRAM_WEBHOOK_SECRET` | Secret token for verifying updates come from Telegram | | `DISCORD_BOT_TOKEN` | Discord bot token | | `DISCORD_ALLOWED_USERS` | Comma-separated Discord user IDs allowed to use the bot | | `DISCORD_HOME_CHANNEL` | Default Discord channel for cron delivery | diff --git a/website/docs/user-guide/messaging/telegram.md b/website/docs/user-guide/messaging/telegram.md index c984ecdbc..473619ccf 100644 --- a/website/docs/user-guide/messaging/telegram.md +++ b/website/docs/user-guide/messaging/telegram.md @@ -112,6 +112,66 @@ hermes gateway The bot should come online within seconds. Send it a message on Telegram to verify. +## Webhook Mode + +By default, Hermes connects to Telegram using **long polling** — the gateway makes outbound requests to Telegram's servers to fetch new updates. This works well for local and always-on deployments. + +For **cloud deployments** (Fly.io, Railway, Render, etc.), **webhook mode** is more cost-effective. These platforms can auto-wake suspended machines on inbound HTTP traffic, but not on outbound connections. Since polling is outbound, a polling bot can never sleep. Webhook mode flips the direction — Telegram pushes updates to your bot's HTTPS URL, enabling sleep-when-idle deployments. + +| | Polling (default) | Webhook | +|---|---|---| +| Direction | Gateway → Telegram (outbound) | Telegram → Gateway (inbound) | +| Best for | Local, always-on servers | Cloud platforms with auto-wake | +| Setup | No extra config | Set `TELEGRAM_WEBHOOK_URL` | +| Idle cost | Machine must stay running | Machine can sleep between messages | + +### Configuration + +Add the following to `~/.hermes/.env`: + +```bash +TELEGRAM_WEBHOOK_URL=https://my-app.fly.dev/telegram +# TELEGRAM_WEBHOOK_PORT=8443 # optional, default 8443 +# TELEGRAM_WEBHOOK_SECRET=mysecret # optional, recommended +``` + +| Variable | Required | Description | +|----------|----------|-------------| +| `TELEGRAM_WEBHOOK_URL` | Yes | Public HTTPS URL where Telegram will send updates. The URL path is auto-extracted (e.g., `/telegram` from the example above). | +| `TELEGRAM_WEBHOOK_PORT` | No | Local port the webhook server listens on (default: `8443`). | +| `TELEGRAM_WEBHOOK_SECRET` | No | Secret token for verifying that updates actually come from Telegram. **Strongly recommended** for production deployments. | + +When `TELEGRAM_WEBHOOK_URL` is set, the gateway starts an HTTP webhook server instead of polling. When unset, polling mode is used — no behavior change from previous versions. + +### Cloud deployment example (Fly.io) + +1. Add the env vars to your Fly.io app secrets: + +```bash +fly secrets set TELEGRAM_WEBHOOK_URL=https://my-app.fly.dev/telegram +fly secrets set TELEGRAM_WEBHOOK_SECRET=$(openssl rand -hex 32) +``` + +2. Expose the webhook port in your `fly.toml`: + +```toml +[[services]] + internal_port = 8443 + protocol = "tcp" + + [[services.ports]] + handlers = ["tls", "http"] + port = 443 +``` + +3. Deploy: + +```bash +fly deploy +``` + +The gateway log should show: `[telegram] Connected to Telegram (webhook mode)`. + ## Home Channel Use the `/sethome` command in any Telegram chat (DM or group) to designate it as the **home channel**. Scheduled tasks (cron jobs) deliver their results to this channel. @@ -335,6 +395,7 @@ You usually don't need to configure this manually. The auto-discovery via DoH ha | Voice messages not transcribed | Verify STT is available: install `faster-whisper` for local transcription, or set `GROQ_API_KEY` / `VOICE_TOOLS_OPENAI_KEY` in `~/.hermes/.env`. | | Voice replies are files, not bubbles | Install `ffmpeg` (needed for Edge TTS Opus conversion). | | Bot token revoked/invalid | Generate a new token via `/revoke` then `/newbot` or `/token` in BotFather. Update your `.env` file. | +| Webhook not receiving updates | Verify `TELEGRAM_WEBHOOK_URL` is publicly reachable (test with `curl`). Ensure your platform/reverse proxy routes inbound HTTPS traffic from the URL's port to the local listen port configured by `TELEGRAM_WEBHOOK_PORT` (they do not need to be the same number). Ensure SSL/TLS is active — Telegram only sends to HTTPS URLs. Check firewall rules. | ## Exec Approval