Skip to main content
Bridge a Telegram bot or a Slack app to an agent: a message to the bot runs an agent turn and the answer comes back in the same chat. The bridge is identical to the WhatsApp guide — only the channel plugin, its env group, and the webhook wiring differ. Every route still runs its turn as a least-privilege execution_key — mint and bind one exactly as in WhatsApp to an agent before creating the route.

Telegram

Configure the channel

manifest.yml
BOT_TOKEN comes from BotFather; it is the auth for outbound sends. WEBHOOK_SECRET is echoed by Telegram in X-Telegram-Bot-Api-Secret-Token and the inbound door checks it constant-time (fail-closed when unset). PUBLIC_BASE_URL is this deployment’s public origin. Unlike the other channels, Telegram’s webhook is registered automatically: on startup the plugin calls setWebhook (idempotent) to point Telegram at {PUBLIC_BASE_URL}/api/channels/telegram/inbound with the secret token. You do not configure it by hand.

Create the route

A Telegram route’s our_identity is the bot’s numeric id — the digits before the : in the bot token:
client_address is the numeric chat id, so each chat holds its own conversation.

Slack

Configure the channel

manifest.yml
BOT_TOKEN (xoxb-…, scope chat:write) authorizes outbound posts. SIGNING_SECRET keys the Slack v0 HMAC the inbound door verifies over the raw body.
CHANNEL_SLACK_BOT_USER_ID (the app’s own bot user id, U…) is required for a Slack bridge route. It is the route’s our_identity and the self-message filter — without it, a bridge message raises loudly rather than looping the bot on its own posts. (An ask_user-only Slack deployment that runs no bridge route does not need it.)

Point the Events API at the deployment

Slack has no startup hook — set the Request URL once in your Slack app’s Event Subscriptions to {public base URL}/api/channels/slack/inbound and subscribe to the message events your bot should hear. Slack verifies the URL against the signing secret.

Create the route

A Slack route’s our_identity is the bot user id; client_address is the Slack conversation id (C…/D…):

Test it and add more

Message the bot and watch the agent reply in the same chat. Read a record with tai conversations get-message <route> <message_id>; list failed deliveries with tai conversations failed. More bots or workspaces are more rows — one route per (channel, our_identity) pair.

See also