Telegram Integration
Shiba can be operated from Telegram DMs and group chats — same approval-gated flow as Slack: a /shiba command queues a run, an inline-keyboard card gates it, an approver’s tap launches it, and the outcome posts back into the same chat. It costs nothing beyond the Worker you already run: Telegram bots are free, and the webhook is the same Worker — no polling process, no relay, no SDK.
Before you start
- Approval Gates — how the pending-approval model works
- Slack Integration — the lane Telegram mirrors
The model
Section titled “The model”Telegram chat (DM or group)└── POST /api/telegram/webhook (X-Telegram-Bot-Api-Secret-Token auth) └── Orchestrator DO named telegram:{chat_id} ├── Pending approval ← /shiba <repo> <task> ├── Approve / Reject ← inline keyboard, TELEGRAM_APPROVERS only └── Run → Sandbox → PR → post-back to the same chat- A chat (DM or group id) owns one orchestrator conversation.
- A pending approval is a pointer (
approve:{uuid}); the button press decides it. - A run executes in the Cloudflare Sandbox and posts progress back in-chat.
How It Works
Section titled “How It Works”- Inbound webhook: Telegram delivers updates to
POST /api/telegram/webhook, authenticated by a shared secret in theX-Telegram-Bot-Api-Secret-Tokenheader (Telegram has no request signing —setWebhook’ssecret_tokenis the whole auth story). Redeliveries are deduped onupdate_id. - Conversation-per-orchestrator: the Durable Object is named
telegram:{chat_id}, so each chat gets its own run registry and approval queue — the same pattern asslack:{team}:{channel}:{ts}. - Commands:
/shiba <repo-url> <task>queues a run in DMs and groups alike (/shiba@YourBotworks in groups)./startand/helpprint usage. - Approval card: the run posts a message with inline-keyboard Approve / Reject buttons. Only Telegram user ids in
TELEGRAM_APPROVERScan decide — unset means nobody can. - Post-back: run start, completion (with PR link), failure, and cancellation post back into the chat via
sendMessage.
-
Create the bot with @BotFather:
/newbot→ pick a name and username. Copy the token (123456:ABC-...). -
Store secrets and vars in your Cloudflare environment:
Terminal window pnpm wrangler secret put TELEGRAM_BOT_TOKEN --config apps/backend/wrangler.jsoncpnpm wrangler secret put TELEGRAM_WEBHOOK_SECRET --config apps/backend/wrangler.jsonc# comma-separated Telegram user ids allowed to click Approve:pnpm wrangler secret put TELEGRAM_APPROVERS --config apps/backend/wrangler.jsoncTELEGRAM_WEBHOOK_SECRETis any random string you invent (openssl rand -hex 32); it must match thesecret_tokenyou register below. Your numeric Telegram id is in @userinfobot. -
Register the webhook (replace the host and secrets):
Terminal window curl "https://api.telegram.org/bot<TELEGRAM_BOT_TOKEN>/setWebhook" \-d "url=https://your-worker.workers.dev/api/telegram/webhook" \-d "secret_token=<TELEGRAM_WEBHOOK_SECRET>" \-d 'allowed_updates=["message","callback_query"]' -
Optional:
TELEGRAM_AGENT_HARNESSpicks the coding agent for Telegram runs (falling back toAGENT_HARNESS), andTELEGRAM_CHAT_REPOSmaps a chat id to a default repo so/shiba <task>works without a URL:{"-1001234567890": "https://github.com/owner/repo"}
Example Interaction
Section titled “Example Interaction”In a DM with the bot — or /shiba in a group:
You:
/shiba https://github.com/owner/repo fix the flaky login testShiba: Approval requested — Repo: owner/repo · Task: fix the flaky login test
[ Approve ] [ Reject ]
The tap only counts if your Telegram id is in TELEGRAM_APPROVERS; everyone else gets a refusal toast. Once approved, the run starts, and Shiba posts the outcome — changed files and the PR link — back into the same chat.
Related documentation
Section titled “Related documentation”- Discord Interactions — the other chat lane, same plumbing
- Slack Integration — the original approval lane
- Configuration & Secrets — every
TELEGRAM_*variable
