-
Notifications
You must be signed in to change notification settings - Fork 1
Telegram Channel
HITL (human-in-the-loop) delivery + the Ask assistant over Telegram. Inline buttons, grounded replies, no command line.
- HITL approvals — when the AI watcher decides "ask", the request lands in your chat with Approve / Decline buttons. Tap one, the session acts on it, you get an echo.
- Ask chat (optional) — DM the bot any question about your sessions. See Ask Assistant.
-
Create the bot — DM @BotFather on Telegram,
/newbot, pick a name, copy the token (looks like123456:ABC-DEF…). - Paste it in AgentPulse — Settings → Telegram → paste the token in the wizard.
-
Pick a delivery mode — two options, both supported:
- Polling (default) — AgentPulse dials out to Telegram on a 25-second long-poll. Works from any network: home-lab, NAT'd, private-DNS, air-gapped. No public URL needed. 1–2 second delivery latency.
-
Webhook — Telegram pushes updates to
<your-url>/api/v1/channels/telegram/webhook. Instant delivery, no constant outbound traffic, but your instance must be reachable from the public internet.
-
Click Save & activate — AgentPulse validates the token via
getMe, generates a strong webhook secret (if webhook mode), encrypts everything into the settings table. You'll see the bot's@usernameand a green status light. -
Enroll a chat — click Generate code in the Add-a-channel card. Scan the QR with your phone, or tap the deep link. Send
/start <code>to the bot. The channel flips to verified.
Done. New HITL requests now deliver to that chat with inline buttons.
| Polling | Webhook | |
|---|---|---|
| Works behind NAT / private DNS | ✅ | ❌ |
| Public URL needed | ❌ | ✅ HTTPS |
| Latency | 1–2s | instant |
| Outbound traffic | constant (1 req / 25s) | zero |
| Inbound traffic | zero | bursty |
| Setup friction | zero | requires public-reachable endpoint |
For home-labs behind a private MetalLB IP or residential ISP without port-forwarding, polling is the right answer. For publicly-hosted deployments behind Cloudflare or a real TLS cert, webhook is more efficient.
You can switch between them any time in Settings. The service tears down whichever side isn't wanted before standing up the new one (they're mutually exclusive at Telegram's end).
Bot token + webhook secret live encrypted in the settings table via the existing AES-256-GCM secrets module (same one the AI providers use). The AGENTPULSE_SECRETS_KEY env var is required for encrypted rotation.
The env vars TELEGRAM_BOT_TOKEN / TELEGRAM_WEBHOOK_SECRET are still honored as a bootstrap fallback for legacy 0.1.0-era deployments, but new setups should paste in the UI so they can rotate without a restart.
Settings → Telegram → each verified channel has an Answer free-form DMs via the Ask assistant checkbox. Default on (enrollment was the opt-in signal). Flip it off to keep the channel HITL-only — the bot will ignore plain messages from that chat while still delivering approve/decline buttons.
Requires Labs → Ask assistant to be on globally.
When a user taps Approve / Decline in Telegram, the callback_query hits AgentPulse's webhook/poller and:
- Verifies the HMAC secret (webhook mode) or trusts the authenticated
getUpdatesresponse (polling mode). - Verifies that the chat that clicked the button is the same chat the HITL was delivered to — a user who learns a
hitl_idcan't forge a tap from their own chat. - Resolves the HITL and emits audit events on the session timeline (
AiHitlResponse+AiContinueSentif approved).
"no available server" on first send to Telegram
- Usually the LLM backend (Qwen on Ollama), not Telegram. See AI Watcher → Known limitations.
Webhook save fails with "Bad Request: bad webhook: IP address X is reserved"
- Your AgentPulse's public hostname resolves to a private IP (LAN). Telegram can't reach it. Switch to polling mode.
401 "Unauthorized" from Traefik on the webhook
- The public webhook route must not be behind Authentik. The deploy manifests route
/api/v1/channels/telegram/webhookthrough a middleware-free ingress rule.
Bot responds to HITL but ignores my chat messages
- Check Labs → Ask assistant is on.
- Check the per-channel
askEnabledtoggle in Settings → Telegram.
-
src/server/services/channels/telegram.ts— Telegram Bot API wrapper + adapter. -
src/server/services/channels/telegram-credentials.ts— encrypted token storage, DB-first/env-fallback reads, in-memory cache. -
src/server/services/channels/telegram-poller.ts— long-poll loop with crash-safe offset tracking. -
src/server/services/channels/channels-service.ts— channel enrollment + lifecycle. -
src/server/routes/channels.ts— webhook + admin REST. -
src/web/components/settings/TelegramChannelPanel.tsx— wizard + status panel.