Supported Platforms
Telegram
Bot token (via @BotFather) — works over in-process long-poll or webhook. Supports inline buttons, photos, documents, voice, and video attachments up to 20 MB.
QR-code or code pairing via a Baileys-based worker subprocess. Supports text, media attachments, and a “self-chat” mode so you don’t need a second phone to test.
Lark / Feishu
App ID + App Secret pairing via Lark Open Platform (international) or Feishu Open Platform (China). Use the “Built for agents” Create button on the app-creation page to skip the scope and event-subscription setup. Long-connection mode, rich-text via Lark
post, interactive cards, image/file attachments.How It Works
1
Enable a platform in Settings
Open Settings → Messaging and configure Telegram (paste a bot token) or WhatsApp (scan a QR code). Each workspace has its own messaging config.
2
Bind a chat to a session
From the external chat, send
/new to create a fresh session, /bind to pick from recent sessions, or /pair <code> to redeem a pairing code generated from the app.3
Chat drives the agent
Once bound, everything you type is forwarded to the agent as a prompt. The agent’s reply is rendered back into the chat using your chosen response mode.
Commands
Available inside any chat — the gateway treats any message starting with/ as a command.
Binding is workspace-scoped. Each messaging binding lives inside one workspace — you can bind the same chat to different sessions in different workspaces, and the gateway only accepts commands/pairing codes originating from the current workspace.
Response Modes
How the agent’s output is rendered back to the chat.
Response mode is configured per binding — you can have one chat on
progress and another on final_only in the same workspace.
Telegram edit interval. To stay within Telegram’s rate limits, the renderer batches edits on a ~3.5 s interval (≈ 20 edits/min). WhatsApp doesn’t support message editing, so
progress mode on WhatsApp posts only the final “thinking” bubble and replaces it with the answer.Pairing Codes
When you already have a session open in the app and want to continue it from your phone, use a pairing code instead of typing the session ID:1
Generate a code from the session menu
In the app, open the session you want to bind, click the three-dot menu, and choose Pair to messaging…. A 6-digit code is shown.
2
Redeem it from the chat
In the external chat, send
/pair 123456 (use your real code). The gateway validates the code, binds the chat, and confirms.- Codes expire after a short TTL.
- The
/paircommand is rate-limited per sender — wrong guesses still consume the budget. - Codes only work inside the workspace that issued them.
Attachments
Supported on Telegram: photos, documents, voice messages, video, and audio. Files are downloaded to a temp location and forwarded to the session asFileAttachment objects — the same way uploads from the app are handled. Hard cap: 20 MB per attachment.
WhatsApp attachment forwarding follows the same pattern; platform-specific limits and MIME handling are documented in the WhatsApp page.
Approval Channel
When the bound session is in Ask permission mode, the agent asks for approval before running a bash command. TheapprovalChannel per binding decides where that prompt appears:
The session’s own permission mode is still authoritative —
approvalChannel only controls where the prompt is shown, not whether it happens.
Plan Submission
When the agent submits a plan in Explore mode, Telegram bindings get inline✅ Accept plan / ♻️ Accept & compact buttons (plus the plan content inline or as a plan.md attachment). WhatsApp bindings get a text pointer telling you to open the desktop app — plans can’t be accepted from WhatsApp yet. See WhatsApp → Plan Submission for the reasons.
Security & Scope
- Per-workspace. Each workspace has its own messaging config, bindings, and pairing codes. Binding in workspace A never accepts codes issued by workspace B.
- Plan-token revocation. Plan tokens (used for bash-approval flows) are keyed by binding — rebinding a chat invalidates outstanding tokens for the old binding.
- Rate limiting.
/pairis throttled per sender. Inbound messages are routed through a per-binding queue so spam doesn’t back-pressure other bindings. - No group/channel chats. Telegram group and channel messages are rejected at the adapter boundary — only private DMs can drive a session.
Configuration Location
Messaging config is persisted per workspace:bindings.json take effect on the next inbound message. Deleting whatsapp-session/ forces a re-pair.
Headless Server
The gateway also runs inside the standalone headless Bun server (packages/server). Telegram uses webhook mode on the server (you configure a webhook URL), while WhatsApp still runs its Baileys worker subprocess. See Server for deployment details.