Krispy AI
guides

connect Telegram

BotFather โ†’ a supergroup with Topics โ†’ the webhook. how the handoff channel works.

connect Telegram

Telegram is the operator's channel. every visitor maps to one forum topic in a supergroup you own, so each conversation is its own thread on your phone and you reply inline. it's optional โ€” without it, the chat still answers (topic ops just no-op).

the fastest path: krispy init

the wizard's first step guides this end to end and validates the token live:

npx krispy init

it prints the BotFather steps, validates the pasted token via Telegram's getMe (green โœ“ @yourbot or a red retry), guides the supergroup-with-Topics + add-bot-as-admin setup, takes the chat id, and persists botToken + chatId. do it by hand instead:

1. create the bot

  1. open @BotFather in Telegram.
  2. send /newbot, follow the prompts (name + @username).
  3. BotFather replies with a token like 123456:ABC-DEF....

set it as a secret: bunx wrangler secret put TELEGRAM_BOT_TOKEN.

2. create the supergroup with Topics

  1. create a Telegram group, then enable Topics (Group โ†’ Edit โ†’ Topics). enabling Topics upgrades it to a supergroup.
  2. add your bot to the group and make it an admin โ€” it needs the Manage Topics permission (that's how it creates a topic per visitor).
  3. get the group's chat id โ€” e.g. add @RawDataBot briefly and read it, or read it from the bot's updates. it looks like -1001234567890.

set it: bunx wrangler secret put TELEGRAM_CHAT_ID.

3. register the webhook

so your replies reach the Worker. the secret_token must equal TELEGRAM_WEBHOOK_SECRET:

curl "https://api.telegram.org/bot<TOKEN>/setWebhook" \
  -d "url=https://krispy-edge.YOU.workers.dev/api/telegram/webhook" \
  -d "secret_token=<TELEGRAM_WEBHOOK_SECRET>"

how the handoff works

  • a visitor's first message creates a forum topic named <first 40 chars> ยท <session id> and stores the topic โ†” session link in KV.
  • every visitor message and every AI reply is mirrored into that topic (best-effort โ€” a Telegram outage never blocks the visitor's reply).
  • when the AI requests a human, the session becomes pending immediately. Later visitor messages keep landing in the topic, but the AI stays silent and the contact form does not repeat.
  • when you type a reply in the topic, Telegram calls POST /api/telegram/webhook. the Worker parses your reply, moves the session from pending to operator, and pushes your text to the visitor's browser live. only then does the widget say a team member joined.
  • send /done when finished to resolve the handoff and let the AI answer again. The silence handback does the same after a waiting visitor receives no operator reply for the configured interval.
  • the Worker ignores its own bot echoes, service messages (topic-created), and messages in the group's General topic โ€” only a real typed reply in a visitor topic counts.

quiet ops: mute the group, get pinged only on handoff

by default every routine mirror (visitor messages, AI replies) is posted silently (disable_notification) โ€” it lands in the thread but never buzzes your phone. so you can mute the whole group in Telegram and still have a full transcript to scroll when you want.

the only loud message is the handoff alert: when the AI escalates ([!HANDOFF], a too-long chat, or an AI outage), the Worker posts one notification-on message into the topic that @mentions your operators โ€” so your phone rings exactly when a human is needed.

  • operators are auto-learned. the first time you (or a teammate) reply in any visitor topic, your Telegram user is added to the tenant's operators list โ€” from then on you're taggable. zero config. even works if you have no public @username (it uses a text_mention entity carrying your user id).
  • the list is capped at 10 (oldest evicted). you can also set it explicitly via POST /api/tenant/config โ€” see the TenantConfig operators field.
  • no operators known yet? the handoff alert still fires โ€” it just carries no mention until someone has replied once.

operators holds Telegram user ids and is never exposed to the public widget config โ€” it's secret-adjacent, same tier as your bot token.

honest about the effort: BotFather, the supergroup-with-Topics, and admin rights are a real five minutes of clicking. there's no way around a bot token if you want replies on your phone.

On this page