2025-12-09 17:51:05 +00:00
---
summary: "Telegram bot support status, capabilities, and configuration"
read_when:
- Working on Telegram features or webhooks
---
2025-12-07 22:46:02 +01:00
# Telegram (Bot API)
2026-01-07 00:25:16 +01:00
Status: production-ready for bot DMs + groups via grammY. Long-polling by default; webhook optional.
2026-01-11 02:40:28 +01:00
## Quick setup (beginner)
1) Create a bot with ** @BotFather ** and copy the token.
2) Set the token:
- Env: `TELEGRAM_BOT_TOKEN=...`
2026-01-13 06:16:43 +00:00
- Or config: `channels.telegram.botToken: "..."` .
2026-01-17 00:12:41 +00:00
- If both are set, config takes precedence (env fallback is default-account only).
2026-01-11 02:40:28 +01:00
3) Start the gateway.
4) DM access is pairing by default; approve the pairing code on first contact.
Minimal config:
```json5
{
2026-01-13 06:16:43 +00:00
channels: {
telegram: {
enabled: true,
botToken: "123:abc",
dmPolicy: "pairing"
}
2026-01-11 02:40:28 +01:00
}
}
```
2026-01-07 00:25:16 +01:00
## What it is
2026-01-13 06:16:43 +00:00
- A Telegram Bot API channel owned by the Gateway.
- Deterministic routing: replies go back to Telegram; the model never chooses channels.
2026-01-11 02:52:50 +00:00
- DMs share the agent's main session; groups stay isolated (`agent:<agentId>:telegram:group:<chatId>` ).
2026-01-07 00:25:16 +01:00
## Setup (fast path)
2026-01-08 09:33:35 +00:00
### 1) Create a bot token (BotFather)
1) Open Telegram and chat with ** @BotFather **.
2) Run `/newbot` , then follow the prompts (name + username ending in `bot` ).
3) Copy the token and store it safely.
Optional BotFather settings:
- `/setjoingroups` — allow/deny adding the bot to groups.
- `/setprivacy` — control whether the bot sees all group messages.
### 2) Configure the token (env or config)
Example:
2026-01-07 00:25:16 +01:00
2025-12-07 22:46:02 +01:00
```json5
{
2026-01-13 06:16:43 +00:00
channels: {
telegram: {
enabled: true,
botToken: "123:abc",
dmPolicy: "pairing",
groups: { "*": { requireMention: true } }
}
2025-12-07 22:46:02 +01:00
}
}
```
2026-01-07 00:25:16 +01:00
2026-01-17 00:12:41 +00:00
Env option: `TELEGRAM_BOT_TOKEN=...` (works for the default account).
If both env and config are set, config takes precedence.
2026-01-11 02:40:28 +01:00
2026-01-13 06:16:43 +00:00
Multi-account support: use `channels.telegram.accounts` with per-account tokens and optional `name` . See [`gateway/configuration` ](/gateway/configuration#telegramaccounts--discordaccounts--slackaccounts--signalaccounts--imessageaccounts ) for the shared pattern.
2026-01-08 01:18:37 +01:00
2026-01-16 23:12:50 +00:00
3) Start the gateway. Telegram starts when a token is resolved (config first, env fallback).
2026-01-07 00:25:16 +01:00
4) DM access defaults to pairing. Approve the code when the bot is first contacted.
2026-01-13 06:16:43 +00:00
5) For groups: add the bot, decide privacy/admin behavior (below), then set `channels.telegram.groups` to control mention gating + allowlists.
2026-01-08 09:33:35 +00:00
## Token + privacy + permissions (Telegram side)
### Token creation (BotFather)
- `/newbot` creates the bot and returns the token (keep it secret).
- If a token leaks, revoke/regenerate it via @BotFather and update your config.
### Group message visibility (Privacy Mode)
Telegram bots default to **Privacy Mode** , which limits which group messages they receive.
If your bot must see *all* group messages, you have two options:
- Disable privacy mode with `/setprivacy` **or**
- Add the bot as a group **admin** (admin bots receive all messages).
**Note:** When you toggle privacy mode, Telegram requires removing + re‑ adding the bot
to each group for the change to take effect.
### Group permissions (admin rights)
Admin status is set inside the group (Telegram UI). Admin bots always receive all
group messages, so use admin if you need full visibility.
2026-01-07 00:25:16 +01:00
## How it works (behavior)
2026-01-13 06:16:43 +00:00
- Inbound messages are normalized into the shared channel envelope with reply context and media placeholders.
2026-01-09 12:44:23 +00:00
- Group replies require a mention by default (native @mention or `agents.list[].groupChat.mentionPatterns` / `messages.groupChat.mentionPatterns` ).
- Multi-agent override: set per-agent patterns on `agents.list[].groupChat.mentionPatterns` .
2026-01-07 00:25:16 +01:00
- Replies always route back to the same Telegram chat.
2026-01-09 12:44:23 +00:00
- Long-polling uses grammY runner with per-chat sequencing; overall concurrency is capped by `agents.defaults.maxConcurrent` .
2026-01-15 06:21:05 +00:00
- Telegram Bot API does not support read receipts; there is no `sendReadReceipts` option.
2026-01-07 00:25:16 +01:00
2026-01-08 02:34:32 +01:00
## Formatting (Telegram HTML)
- Outbound Telegram text uses `parse_mode: "HTML"` (Telegram’ s supported tag subset).
- Markdown-ish input is rendered into **Telegram-safe HTML** (bold/italic/strike/code/links); block elements are flattened to text with newlines/bullets.
- Raw HTML from models is escaped to avoid Telegram parse errors.
- If Telegram rejects the HTML payload, Clawdbot retries the same message as plain text.
2026-01-16 08:20:48 +00:00
## Commands (native + custom)
Clawdbot registers native commands (like `/status` , `/reset` , `/model` ) with Telegram’ s bot menu on startup.
You can add custom commands to the menu via config:
```json5
{
channels: {
telegram: {
customCommands: [
{ command: "backup", description: "Git backup" },
{ command: "generate", description: "Create an image" }
]
}
}
}
```
Notes:
- Custom commands are **menu entries only** ; Clawdbot does not implement them unless you handle them elsewhere.
- Command names are normalized (leading `/` stripped, lowercased) and must match `a-z` , `0-9` , `_` (1– 32 chars).
- Custom commands **cannot override native commands** . Conflicts are ignored and logged.
- If `commands.native` is disabled, only custom commands are registered (or cleared if none).
2026-01-08 04:02:04 +01:00
## Limits
2026-01-13 06:16:43 +00:00
- Outbound text is chunked to `channels.telegram.textChunkLimit` (default 4000).
- Media downloads/uploads are capped by `channels.telegram.mediaMaxMb` (default 5).
2026-01-14 10:09:26 +00:00
- Telegram Bot API requests time out after `channels.telegram.timeoutSeconds` (default 500 via grammY). Set lower to avoid long hangs.
2026-01-13 06:16:43 +00:00
- Group history context uses `channels.telegram.historyLimit` (or `channels.telegram.accounts.*.historyLimit` ), falling back to `messages.groupChat.historyLimit` . Set `0` to disable (default 50).
2026-01-15 02:22:29 +00:00
- DM history can be limited with `channels.telegram.dmHistoryLimit` (user turns). Per-user overrides: `channels.telegram.dms["<user_id>"].historyLimit` .
2026-01-08 04:02:04 +01:00
2026-01-07 08:54:58 +00:00
## Group activation modes
2026-01-09 12:44:23 +00:00
By default, the bot only responds to mentions in groups (`@botname` or patterns in `agents.list[].groupChat.mentionPatterns` ). To change this behavior:
2026-01-07 08:54:58 +00:00
### Via config (recommended)
```json5
{
2026-01-13 06:16:43 +00:00
channels: {
telegram: {
groups: {
"-1001234567890": { requireMention: false } // always respond in this group
}
2026-01-07 08:54:58 +00:00
}
}
}
```
2026-01-13 06:16:43 +00:00
**Important:** Setting `channels.telegram.groups` creates an **allowlist** - only listed groups (or `"*"` ) will be accepted.
2026-01-18 01:21:27 +00:00
Forum topics inherit their parent group config (allowFrom, requireMention, skills, prompts) unless you add per-topic overrides under `channels.telegram.groups.<groupId>.topics.<topicId>` .
2026-01-07 08:54:58 +00:00
To allow all groups with always-respond:
```json5
{
2026-01-13 06:16:43 +00:00
channels: {
telegram: {
groups: {
"*": { requireMention: false } // all groups, always respond
}
2026-01-07 08:54:58 +00:00
}
}
}
```
To keep mention-only for all groups (default behavior):
```json5
{
2026-01-13 06:16:43 +00:00
channels: {
telegram: {
groups: {
"*": { requireMention: true } // or omit groups entirely
}
2026-01-07 08:54:58 +00:00
}
}
}
```
### Via command (session-level)
Send in the group:
- `/activation always` - respond to all messages
- `/activation mention` - require mentions (default)
**Note:** Commands update session state only. For persistent behavior across restarts, use config.
### Getting the group chat ID
Forward any message from the group to `@userinfobot` or `@getidsbot` on Telegram to see the chat ID (negative number like `-1001234567890` ).
2026-01-11 03:57:44 +01:00
**Tip:** For your own user ID, DM the bot and it will reply with your user ID (pairing message), or use `/whoami` once commands are enabled.
2026-01-10 14:51:51 +01:00
2026-01-15 06:09:14 +00:00
**Privacy note:** `@userinfobot` is a third-party bot. If you prefer, add the bot to the group, send a message, and use `clawdbot logs --follow` to read `chat.id` , or use the Bot API `getUpdates` .
2026-01-10 14:51:51 +01:00
2026-01-15 01:41:11 +00:00
## Config writes
By default, Telegram is allowed to write config updates triggered by channel events or `/config set|unset` .
This happens when:
- A group is upgraded to a supergroup and Telegram emits `migrate_to_chat_id` (chat ID changes). Clawdbot can migrate `channels.telegram.groups` automatically.
- You run `/config set` or `/config unset` in a Telegram chat (requires `commands.config: true` ).
Disable with:
```json5
{
channels: { telegram: { configWrites: false } }
}
```
2026-01-07 02:10:56 +00:00
## Topics (forum supergroups)
Telegram forum topics include a `message_thread_id` per message. Clawdbot:
- Appends `:topic:<threadId>` to the Telegram group session key so each topic is isolated.
- Sends typing indicators and replies with `message_thread_id` so responses stay in the topic.
2026-01-16 00:07:45 +00:00
- General topic (thread id `1` ) is special: message sends omit `message_thread_id` (Telegram rejects it), but typing indicators still include it.
2026-01-07 02:10:56 +00:00
- Exposes `MessageThreadId` + `IsForum` in template context for routing/templating.
2026-01-13 06:16:43 +00:00
- Topic-specific configuration is available under `channels.telegram.groups.<chatId>.topics.<threadId>` (skills, allowlists, auto-reply, system prompts, disable).
2026-01-17 23:48:39 +00:00
- Topic configs inherit group settings (requireMention, allowlists, skills, prompts, enabled) unless overridden per topic.
2026-01-07 02:10:56 +00:00
2026-01-11 02:44:32 +00:00
Private chats can include `message_thread_id` in some edge cases. Clawdbot keeps the DM session key unchanged, but still uses the thread id for replies/draft streaming when it is present.
2026-01-07 11:08:11 +01:00
2026-01-15 20:55:03 -05:00
## Inline Buttons
2026-01-16 20:16:35 +00:00
Telegram supports inline keyboards with callback buttons.
2026-01-15 20:55:03 -05:00
```json5
{
"channels": {
"telegram": {
2026-01-16 20:16:35 +00:00
"capabilities": {
"inlineButtons": "allowlist"
}
2026-01-15 20:55:03 -05:00
}
}
}
```
For per-account configuration:
```json5
{
"channels": {
"telegram": {
"accounts": {
"main": {
2026-01-16 20:16:35 +00:00
"capabilities": {
"inlineButtons": "allowlist"
}
2026-01-15 20:55:03 -05:00
}
}
}
}
}
```
2026-01-16 20:16:35 +00:00
Scopes:
- `off` — inline buttons disabled
- `dm` — only DMs (group targets blocked)
- `group` — only groups (DM targets blocked)
- `all` — DMs + groups
- `allowlist` — DMs + groups, but only senders allowed by `allowFrom` /`groupAllowFrom` (same rules as control commands)
Default: `allowlist` .
Legacy: `capabilities: ["inlineButtons"]` = `inlineButtons: "all"` .
2026-01-15 20:55:03 -05:00
### Sending buttons
Use the message tool with the `buttons` parameter:
```json5
{
"action": "send",
"channel": "telegram",
"to": "123456789",
"message": "Choose an option:",
"buttons": [
[
{"text": "Yes", "callback_data": "yes"},
{"text": "No", "callback_data": "no"}
],
[
{"text": "Cancel", "callback_data": "cancel"}
]
]
}
```
When a user clicks a button, the callback data is sent back to the agent as a message with the format:
`callback_data: value`
### Configuration options
2026-01-16 20:16:35 +00:00
Telegram capabilities can be configured at two levels (object form shown above; legacy string arrays still supported):
2026-01-15 20:55:03 -05:00
2026-01-16 20:16:35 +00:00
- `channels.telegram.capabilities` : Global default capability config applied to all Telegram accounts unless overridden.
- `channels.telegram.accounts.<account>.capabilities` : Per-account capabilities that override the global defaults for that specific account.
2026-01-15 20:55:03 -05:00
2026-01-16 20:16:35 +00:00
Use the global setting when all Telegram bots/accounts should behave the same. Use per-account configuration when different bots need different behaviors (for example, one account only handles DMs while another is allowed in groups).
2026-01-07 00:25:16 +01:00
## Access control (DMs + groups)
2026-01-07 08:54:58 +00:00
### DM access
2026-01-13 06:16:43 +00:00
- Default: `channels.telegram.dmPolicy = "pairing"` . Unknown senders receive a pairing code; messages are ignored until approved (codes expire after 1 hour).
2026-01-07 00:25:16 +01:00
- Approve via:
2026-01-10 16:36:43 +01:00
- `clawdbot pairing list telegram`
- `clawdbot pairing approve telegram <CODE>`
2026-01-07 02:04:02 +01:00
- Pairing is the default token exchange used for Telegram DMs. Details: [Pairing ](/start/pairing )
2026-01-18 22:51:09 +00:00
- `channels.telegram.allowFrom` accepts numeric user IDs (recommended) or `@username` entries. It is **not** the bot username; use the human sender’ s ID. The wizard accepts `@username` and resolves it to the numeric ID when possible.
2026-01-15 06:09:14 +00:00
#### Finding your Telegram user ID
Safer (no third-party bot):
1) Start the gateway and DM your bot.
2) Run `clawdbot logs --follow` and look for `from.id` .
Alternate (official Bot API):
1) DM your bot.
2) Fetch updates with your bot token and read `message.from.id` :
```bash
curl "https://api.telegram.org/bot< bot_token > /getUpdates"
```
Third-party (less private):
- DM `@userinfobot` or `@getidsbot` and use the returned user id.
2026-01-07 00:25:16 +01:00
2026-01-07 08:54:58 +00:00
### Group access
Two independent controls:
2026-01-13 06:16:43 +00:00
**1. Which groups are allowed** (group allowlist via `channels.telegram.groups` ):
2026-01-07 08:54:58 +00:00
- No `groups` config = all groups allowed
- With `groups` config = only listed groups or `"*"` are allowed
- Example: `"groups": { "-1001234567890": {}, "*": {} }` allows all groups
2026-01-13 06:16:43 +00:00
**2. Which senders are allowed** (sender filtering via `channels.telegram.groupPolicy` ):
2026-01-12 08:21:50 +00:00
- `"open"` = all senders in allowed groups can message
2026-01-13 06:16:43 +00:00
- `"allowlist"` = only senders in `channels.telegram.groupAllowFrom` can message
2026-01-07 08:54:58 +00:00
- `"disabled"` = no group messages accepted at all
2026-01-12 08:21:50 +00:00
Default is `groupPolicy: "allowlist"` (blocked unless you add `groupAllowFrom` ).
2026-01-07 08:54:58 +00:00
2026-01-13 06:16:43 +00:00
Most users want: `groupPolicy: "allowlist"` + `groupAllowFrom` + specific groups listed in `channels.telegram.groups`
2026-01-07 00:25:16 +01:00
## Long-polling vs webhook
- Default: long-polling (no public URL required).
2026-01-13 06:16:43 +00:00
- Webhook mode: set `channels.telegram.webhookUrl` (optionally `channels.telegram.webhookSecret` + `channels.telegram.webhookPath` ).
2026-01-07 00:25:16 +01:00
- The local listener binds to `0.0.0.0:8787` and serves `POST /telegram-webhook` by default.
2026-01-13 06:16:43 +00:00
- If your public URL is different, use a reverse proxy and point `channels.telegram.webhookUrl` at the public endpoint.
2026-01-07 00:25:16 +01:00
## Reply threading
Telegram supports optional threaded replies via tags:
- `[[reply_to_current]]` -- reply to the triggering message.
- `[[reply_to:<id>]]` -- reply to a specific message id.
2026-01-13 06:16:43 +00:00
Controlled by `channels.telegram.replyToMode` :
2026-01-08 00:50:29 +00:00
- `first` (default), `all` , `off` .
2026-01-07 00:25:16 +01:00
2026-01-08 03:13:54 +00:00
## Audio messages (voice vs file)
Telegram distinguishes **voice notes** (round bubble) from **audio files** (metadata card).
Clawdbot defaults to audio files for backward compatibility.
To force a voice note bubble in agent replies, include this tag anywhere in the reply:
- `[[audio_as_voice]]` — send audio as a voice note instead of a file.
2026-01-13 06:16:43 +00:00
The tag is stripped from the delivered text. Other channels ignore this tag.
2026-01-08 03:13:54 +00:00
2026-01-17 17:32:13 +00:00
For message tool sends, set `asVoice: true` with a voice-compatible audio `media` URL
(`message` is optional when media is present):
```json5
{
"action": "send",
"channel": "telegram",
"to": "123456789",
"media": "https://example.com/voice.ogg",
"asVoice": true
}
```
2026-01-07 11:08:11 +01:00
## Streaming (drafts)
Telegram can stream **draft bubbles** while the agent is generating a response.
Clawdbot uses Bot API `sendMessageDraft` (not real messages) and then sends the
final reply as a normal message.
Requirements (Telegram Bot API 9.3+):
- **Private chats with topics enabled** (forum topic mode for the bot).
- Incoming messages must include `message_thread_id` (private topic thread).
- Streaming is ignored for groups/supergroups/channels.
Config:
2026-01-13 06:16:43 +00:00
- `channels.telegram.streamMode: "off" | "partial" | "block"` (default: `partial` )
2026-01-07 11:08:11 +01:00
- `partial` : update the draft bubble with the latest streaming text.
- `block` : update the draft bubble in larger blocks (chunked).
- `off` : disable draft streaming.
2026-01-10 18:30:06 +01:00
- Optional (only for `streamMode: "block"` ):
2026-01-13 06:16:43 +00:00
- `channels.telegram.draftChunk: { minChars?, maxChars?, breakPreference? }`
- defaults: `minChars: 200` , `maxChars: 800` , `breakPreference: "paragraph"` (clamped to `channels.telegram.textChunkLimit` ).
2026-01-07 11:08:11 +01:00
2026-01-13 06:16:43 +00:00
Note: draft streaming is separate from **block streaming** (channel messages).
Block streaming is off by default and requires `channels.telegram.blockStreaming: true`
2026-01-09 22:40:58 +01:00
if you want early Telegram messages instead of draft updates.
2026-01-07 11:08:11 +01:00
Reasoning stream (Telegram only):
- `/reasoning stream` streams reasoning into the draft bubble while the reply is
generating, then sends the final answer without reasoning.
2026-01-13 06:16:43 +00:00
- If `channels.telegram.streamMode` is `off` , reasoning stream is disabled.
2026-01-07 17:15:53 +01:00
More context: [Streaming + chunking ](/concepts/streaming ).
2026-01-07 11:08:11 +01:00
2026-01-07 17:48:19 +00:00
## Retry policy
2026-01-13 06:16:43 +00:00
Outbound Telegram API calls retry on transient network/429 errors with exponential backoff and jitter. Configure via `channels.telegram.retry` . See [Retry policy ](/concepts/retry ).
2026-01-07 17:48:19 +00:00
2026-01-08 00:50:29 +00:00
## Agent tool (messages + reactions)
- Tool: `telegram` with `sendMessage` action (`to` , `content` , optional `mediaUrl` , `replyToMessageId` , `messageThreadId` ).
2026-01-07 04:10:13 +01:00
- Tool: `telegram` with `react` action (`chatId` , `messageId` , `emoji` ).
2026-01-15 00:29:28 +00:00
- Tool: `telegram` with `deleteMessage` action (`chatId` , `messageId` ).
2026-01-07 04:24:11 +01:00
- Reaction removal semantics: see [/tools/reactions ](/tools/reactions ).
2026-01-15 00:29:28 +00:00
- Tool gating: `channels.telegram.actions.reactions` , `channels.telegram.actions.sendMessage` , `channels.telegram.actions.deleteMessage` (default: enabled).
2026-01-07 04:10:13 +01:00
2026-01-13 21:34:40 +02:00
## Reaction notifications
**How reactions work:**
Telegram reactions arrive as **separate `message_reaction` events** , not as properties in message payloads. When a user adds a reaction, Clawdbot:
1. Receives the `message_reaction` update from Telegram API
2. Converts it to a **system event** with format: `"Telegram reaction added: {emoji} by {user} on msg {id}"`
3. Enqueues the system event using the **same session key** as regular messages
4. When the next message arrives in that conversation, system events are drained and prepended to the agent's context
The agent sees reactions as **system notifications** in the conversation history, not as message metadata.
**Configuration:**
- `channels.telegram.reactionNotifications` : Controls which reactions trigger notifications
2026-01-16 20:51:39 +00:00
- `"off"` — ignore all reactions
- `"own"` — notify when users react to bot messages (best-effort; in-memory) (default)
2026-01-13 21:34:40 +02:00
- `"all"` — notify for all reactions
- `channels.telegram.reactionLevel` : Controls agent's reaction capability
- `"off"` — agent cannot react to messages
2026-01-15 17:20:17 +00:00
- `"ack"` — bot sends acknowledgment reactions (👀 while processing) (default)
2026-01-13 21:34:40 +02:00
- `"minimal"` — agent can react sparingly (guideline: 1 per 5-10 exchanges)
- `"extensive"` — agent can react liberally when appropriate
**Forum groups:** Reactions in forum groups include `message_thread_id` and use session keys like `agent:main:telegram:group:{chatId}:topic:{threadId}` . This ensures reactions and messages in the same topic stay together.
**Example config:**
```json5
{
channels: {
telegram: {
reactionNotifications: "all", // See all reactions
reactionLevel: "minimal" // Agent can react sparingly
}
}
}
```
**Requirements:**
- Telegram bots must explicitly request `message_reaction` in `allowed_updates` (configured automatically by Clawdbot)
- For webhook mode, reactions are included in the webhook `allowed_updates`
- For polling mode, reactions are included in the `getUpdates` `allowed_updates`
2026-01-07 00:25:16 +01:00
## Delivery targets (CLI/cron)
- Use a chat id (`123456789` ) or a username (`@name` ) as the target.
2026-01-17 04:06:14 +00:00
- Example: `clawdbot message send --channel telegram --target 123456789 --message "hi"` .
2026-01-07 00:25:16 +01:00
2026-01-07 08:54:58 +00:00
## Troubleshooting
2026-01-08 23:14:11 +01:00
**Bot doesn’ t respond to non-mention messages in a group:**
2026-01-13 06:16:43 +00:00
- If you set `channels.telegram.groups.*.requireMention=false` , Telegram’ s Bot API **privacy mode** must be disabled.
2026-01-08 23:14:11 +01:00
- BotFather: `/setprivacy` → **Disable** (then remove + re-add the bot to the group)
2026-01-13 06:16:43 +00:00
- `clawdbot channels status` shows a warning when config expects unmentioned group messages.
- `clawdbot channels status --probe` can additionally check membership for explicit numeric group IDs (it can’ t audit wildcard `"*"` rules).
2026-01-08 23:14:11 +01:00
- Quick test: `/activation always` (session-only; use config for persistence)
2026-01-07 08:54:58 +00:00
**Bot not seeing group messages at all:**
2026-01-13 06:16:43 +00:00
- If `channels.telegram.groups` is set, the group must be listed or use `"*"`
2026-01-07 08:54:58 +00:00
- Check Privacy Settings in @BotFather → "Group Privacy" should be **OFF**
- Verify bot is actually a member (not just an admin with no read access)
2026-01-08 06:48:28 +00:00
- Check gateway logs: `clawdbot logs --follow` (look for "skipping group message")
2026-01-07 08:54:58 +00:00
**Bot responds to mentions but not `/activation always` :**
- The `/activation` command updates session state but doesn't persist to config
2026-01-13 06:16:43 +00:00
- For persistent behavior, add group to `channels.telegram.groups` with `requireMention: false`
2026-01-07 08:54:58 +00:00
**Commands like `/status` don't work:**
2026-01-13 06:16:43 +00:00
- Make sure your Telegram user ID is authorized (via pairing or `channels.telegram.allowFrom` )
2026-01-07 08:54:58 +00:00
- Commands require authorization even in groups with `groupPolicy: "open"`
2026-01-21 17:29:39 +00:00
**Long-polling aborts immediately on Node 22+ (often with proxies/custom fetch):**
- Node 22+ is stricter about `AbortSignal` instances; foreign signals can abort `fetch` calls right away.
- Upgrade to a Clawdbot build that normalizes abort signals, or run the gateway on Node 20 until you can upgrade.
2026-01-15 07:23:19 +00:00
**Bot starts, then silently stops responding (or logs `HttpError: Network request ... failed` ):**
- Some hosts resolve `api.telegram.org` to IPv6 first. If your server does not have working IPv6 egress, grammY can get stuck on IPv6-only requests.
- Fix by enabling IPv6 egress **or** forcing IPv4 resolution for `api.telegram.org` (for example, add an `/etc/hosts` entry using the IPv4 A record, or prefer IPv4 in your OS DNS stack), then restart the gateway.
- Quick check: `dig +short api.telegram.org A` and `dig +short api.telegram.org AAAA` to confirm what DNS returns.
2026-01-07 00:25:16 +01:00
## Configuration reference (Telegram)
2026-01-07 02:04:02 +01:00
Full configuration: [Configuration ](/gateway/configuration )
2026-01-07 00:25:16 +01:00
Provider options:
2026-01-13 06:16:43 +00:00
- `channels.telegram.enabled` : enable/disable channel startup.
- `channels.telegram.botToken` : bot token (BotFather).
- `channels.telegram.tokenFile` : read token from file path.
- `channels.telegram.dmPolicy` : `pairing | allowlist | open | disabled` (default: pairing).
- `channels.telegram.allowFrom` : DM allowlist (ids/usernames). `open` requires `"*"` .
- `channels.telegram.groupPolicy` : `open | allowlist | disabled` (default: allowlist).
- `channels.telegram.groupAllowFrom` : group sender allowlist (ids/usernames).
- `channels.telegram.groups` : per-group defaults + allowlist (use `"*"` for global defaults).
- `channels.telegram.groups.<id>.requireMention` : mention gating default.
- `channels.telegram.groups.<id>.skills` : skill filter (omit = all skills, empty = none).
- `channels.telegram.groups.<id>.allowFrom` : per-group sender allowlist override.
- `channels.telegram.groups.<id>.systemPrompt` : extra system prompt for the group.
- `channels.telegram.groups.<id>.enabled` : disable the group when `false` .
- `channels.telegram.groups.<id>.topics.<threadId>.*` : per-topic overrides (same fields as group).
- `channels.telegram.groups.<id>.topics.<threadId>.requireMention` : per-topic mention gating override.
2026-01-16 20:16:35 +00:00
- `channels.telegram.capabilities.inlineButtons` : `off | dm | group | all | allowlist` (default: allowlist).
- `channels.telegram.accounts.<account>.capabilities.inlineButtons` : per-account override.
2026-01-13 06:16:43 +00:00
- `channels.telegram.replyToMode` : `off | first | all` (default: `first` ).
- `channels.telegram.textChunkLimit` : outbound chunk size (chars).
- `channels.telegram.streamMode` : `off | partial | block` (draft streaming).
- `channels.telegram.mediaMaxMb` : inbound/outbound media cap (MB).
- `channels.telegram.retry` : retry policy for outbound Telegram API calls (attempts, minDelayMs, maxDelayMs, jitter).
- `channels.telegram.proxy` : proxy URL for Bot API calls (SOCKS/HTTP).
- `channels.telegram.webhookUrl` : enable webhook mode.
- `channels.telegram.webhookSecret` : webhook secret (optional).
- `channels.telegram.webhookPath` : local webhook path (default `/telegram-webhook` ).
- `channels.telegram.actions.reactions` : gate Telegram tool reactions.
- `channels.telegram.actions.sendMessage` : gate Telegram tool message sends.
2026-01-15 00:29:28 +00:00
- `channels.telegram.actions.deleteMessage` : gate Telegram tool message deletes.
2026-01-16 20:51:39 +00:00
- `channels.telegram.reactionNotifications` : `off | own | all` — control which reactions trigger system events (default: `own` when not set).
2026-01-16 20:35:43 +00:00
- `channels.telegram.reactionLevel` : `off | ack | minimal | extensive` — control agent's reaction capability (default: `minimal` when not set).
2026-01-07 00:25:16 +01:00
Related global options:
2026-01-09 12:44:23 +00:00
- `agents.list[].groupChat.mentionPatterns` (mention gating patterns).
- `messages.groupChat.mentionPatterns` (global fallback).
2026-01-13 06:16:43 +00:00
- `commands.native` (defaults to `"auto"` → on for Telegram/Discord, off for Slack), `commands.text` , `commands.useAccessGroups` (command behavior). Override with `channels.telegram.commands.native` .
2026-01-10 02:11:51 +01:00
- `messages.responsePrefix` , `messages.ackReaction` , `messages.ackReactionScope` , `messages.removeAckAfterReply` .