Skip to content

Telegram

Telegram integration uses the standard Bot API via a bot token you create with @BotFather. There’s no account linking — you talk to your bot, and the bot drives a Craft Agent session.

Open @BotFather in Telegram

Search for @BotFather and start a chat.

Create a new bot

Send /newbot and follow the prompts. Give it a display name and a username (must end in bot, e.g. my_craft_agent_bot).

Copy the token

BotFather replies with a line like:

1234567890:ABCdefGHIjklMNOpqrsTUVwxyz-0123456789

This is your bot token. Treat it like a password — anyone with it can impersonate your bot.

(Optional) Disable privacy mode for group support

If you want your bot to work in groups, send /setprivacy → choose your bot → Disable. For 1-on-1 use (the supported and recommended mode), you can skip this.

Open Settings → Messaging

In Craft Agent, open Settings → Messaging. You’ll see a tile for each supported platform.

Click Connect on the Telegram tile

A dialog opens asking for the bot token.

Paste the token and click Test

Craft Agent calls Telegram’s getMe endpoint. On success you’ll see the bot’s name and username; on failure you’ll see Telegram’s error message verbatim.

Click Save

The token is persisted to your workspace keychain and the Telegram adapter starts listening.

Open your bot in Telegram

Tap the t.me/<your_bot_username> link BotFather sent you, or search for your bot’s username.

Send /new

This creates a new session in your active workspace and binds the chat to it. You’ll get a reply like:

Created "abc123" — you're connected. Just type to start.

Type anything

Your message is forwarded to the agent. Replies come back as messages in the chat according to your response mode (default: progress).

Send a photo, document, voice message, video, or audio file and the gateway downloads the blob, wraps it as a FileAttachment, and forwards it to the session alongside your caption.

TypeForwarded as
PhotoImage attachment (original resolution)
DocumentFile attachment with original MIME type
VoiceAudio attachment (ogg/opus)
VideoVideo attachment
AudioAudio attachment

Hard cap: 20 MB per attachment. Oversize files or failed downloads trigger a user-visible reply in the chat instead of being silently dropped.

Telegram supports inline keyboard buttons, so flows like /bind render a tappable list of recent sessions instead of a numbered text list:

Recent sessions:
[ Morning standup ]
[ Release v0.8.10 ]
[ Debug session ]

Tap a button → bound. The gateway clears the keyboard on the posted message so stale buttons don’t pile up.

Bots are addressable by anyone who knows the username, so by default a fresh workspace ships with owner-only access for Telegram. Only senders on the workspace’s allowed-users list can run pre-binding commands (/new, /bind, /unbind, /status, /stop) or route messages to a bound session.

First-pair rule. When you redeem a pairing code from a fresh workspace, your Telegram user_id is captured automatically and added as the first owner. You don’t have to type any numeric ids — the bot learns them from your /pair message.

Adding more users. When someone else messages the bot, they get a “Bot is private” reply and appear under Settings → Messaging → Pending requests with a one-click Allow button. No numeric ids needed.

Per-binding allow-list. Each session-channel binding can override the workspace policy with one of three modes:

ModeMeaning
Inherits workspaceDefault. Falls back to the workspace allowed-users list.
Custom allow-listOnly the explicitly checked users can use this binding. Useful for sharing one session with a guest without giving them access to everything.
Open to anyoneAnyone in an accepted chat can use this binding. Use only for genuinely public bots.

Migration. Workspaces that paired Telegram before access control existed stay in open mode until you click Lock down in Settings → Messaging. Existing bindings keep their current behaviour to avoid breaking traffic.

Why no group-message gating? Group/channel messages are rejected at the adapter boundary unless you’ve paired a workspace supergroup. Inside a paired supergroup, sender-level rules apply identically to DMs.

  • In-app (desktop Electron): the adapter uses long-poll (grammY’s built-in updater). No public URL needed.
  • Headless server: the adapter uses webhook mode. You configure a public URL (e.g., https://your-server.tld/telegram/webhook), register it with setWebhook, and Telegram posts updates to it. The server verifies the X-Telegram-Bot-Api-Secret-Token header.

See Server → Headless for the webhook deployment path.

Bot replies with 'No session bound to this chat'

This is expected on the first message to a fresh bot. Send /new to create and bind a session, or /pair <code> to redeem a pairing code from the app.

Test fails with '401 Unauthorized'

The bot token is wrong or was revoked in BotFather. Run /token in @BotFather to get a fresh one, or /revoke then /newbot if you want a clean slate.

Bot receives messages but nothing happens

Check that the workspace the bot is configured in is the active workspace in the app. Each workspace has its own messaging config — a bot registered under workspace A won’t drive sessions in workspace B.

Messages in a group don't work

By design — only private DMs with the bot can drive a session. Group and channel messages are rejected at the adapter boundary.

Attachment 'too large' reply

Telegram’s Bot API caps file downloads at 20 MB. Upload the file via the app’s attachment picker instead, or split it.