Telegram
Telegram (Bot API)
Section titled “Telegram (Bot API)”Status: production-ready for bot DMs + groups via grammY. Long polling is the default mode; webhook mode is optional.
Default DM policy for Telegram is pairing.
Cross-channel diagnostics and repair playbooks.
Full channel config patterns and examples.
Quick setup
Section titled “Quick setup”Create the bot token in BotFather
Open Telegram and chat with @BotFather (confirm the handle is exactly
@BotFather).Run
/newbot, follow prompts, and save the token.Configure token and DM policy
{channels: {telegram: {enabled: true,botToken: "123:abc",dmPolicy: "pairing",groups: { "*": { requireMention: true } },},},}Env fallback: `TELEGRAM_BOT_TOKEN=...` (default account only).Telegram does **not** use `openclaw channels login telegram`; configure token in config/env, then start gateway.Start gateway and approve first DM
Terminal window openclaw gatewayopenclaw pairing list telegramopenclaw pairing approve telegramPairing codes expire after 1 hour.
Telegram side settings
Section titled “Telegram side settings”Privacy mode and group visibility
Telegram bots default to Privacy Mode, which limits what group messages they receive.
If the bot must see all group messages, either:
- disable privacy mode via
/setprivacy, or - make the bot a group admin.
When toggling privacy mode, remove + re-add the bot in each group so Telegram applies the change.
Group permissions
Admin status is controlled in Telegram group settings.
Admin bots receive all group messages, which is useful for always-on group behavior.
Helpful BotFather toggles
/setjoingroupsto allow/deny group adds/setprivacyfor group visibility behavior
Access control and activation
Section titled “Access control and activation”`channels.telegram.dmPolicy` controls direct message access:
- `pairing` (default)- `allowlist` (requires at least one sender ID in `allowFrom`)- `open` (requires `allowFrom` to include `"*"`)- `disabled`
`channels.telegram.allowFrom` accepts numeric Telegram user IDs. `telegram:` / `tg:` prefixes are accepted and normalized.`dmPolicy: "allowlist"` with empty `allowFrom` blocks all DMs and is rejected by config validation.Onboarding accepts `@username` input and resolves it to numeric IDs.If you upgraded and your config contains `@username` allowlist entries, run `openclaw doctor --fix` to resolve them (best-effort; requires a Telegram bot token).If you previously relied on pairing-store allowlist files, `openclaw doctor --fix` can recover entries into `channels.telegram.allowFrom` in allowlist flows (for example when `dmPolicy: "allowlist"` has no explicit IDs yet).
For one-owner bots, prefer `dmPolicy: "allowlist"` with explicit numeric `allowFrom` IDs to keep access policy durable in config (instead of depending on previous pairing approvals).
### Finding your Telegram user ID
Safer (no third-party bot):
1. DM your bot.2. Run `openclaw logs --follow`.3. Read `from.id`.
Official Bot API method:curl "https://api.telegram.org/bot/getUpdates”
Third-party method (less private): `@userinfobot` or `@getidsbot`.Two controls apply together:
1. **Which groups are allowed** (`channels.telegram.groups`) - no `groups` config: - with `groupPolicy: "open"`: any group can pass group-ID checks - with `groupPolicy: "allowlist"` (default): groups are blocked until you add `groups` entries (or `"*"`) - `groups` configured: acts as allowlist (explicit IDs or `"*"`)
2. **Which senders are allowed in groups** (`channels.telegram.groupPolicy`) - `open` - `allowlist` (default) - `disabled`
`groupAllowFrom` is used for group sender filtering. If not set, Telegram falls back to `allowFrom`.`groupAllowFrom` entries should be numeric Telegram user IDs (`telegram:` / `tg:` prefixes are normalized).Do not put Telegram group or supergroup chat IDs in `groupAllowFrom`. Negative chat IDs belong under `channels.telegram.groups`.Non-numeric entries are ignored for sender authorization.Security boundary (`2026.2.25+`): group sender auth does **not** inherit DM pairing-store approvals.Pairing stays DM-only. For groups, set `groupAllowFrom` or per-group/per-topic `allowFrom`.Runtime note: if `channels.telegram` is completely missing, runtime defaults to fail-closed `groupPolicy="allowlist"` unless `channels.defaults.groupPolicy` is explicitly set.
Example: allow any member in one specific group:{ channels: { telegram: { groups: { "-1001234567890": { groupPolicy: "open", requireMention: false, }, }, }, },}Example: allow only specific users inside one specific group:{ channels: { telegram: { groups: { "-1001234567890": { requireMention: true, allowFrom: ["8734062810", "745123456"], }, }, }, },}Group replies require mention by default.
Mention can come from:
- native `@botusername` mention, or- mention patterns in: - `agents.list[].groupChat.mentionPatterns` - `messages.groupChat.mentionPatterns`
Session-level command toggles:
- `/activation always`- `/activation mention`
These update session state only. Use config for persistence.
Persistent config example:{ channels: { telegram: { groups: { "*": { requireMention: false }, }, }, },}Getting the group chat ID:
- forward a group message to `@userinfobot` / `@getidsbot`- or read `chat.id` from `openclaw logs --follow`- or inspect Bot API `getUpdates`Runtime behavior
Section titled “Runtime behavior”- Telegram is owned by the gateway process.
- Routing is deterministic: Telegram inbound replies back to Telegram (the model does not pick channels).
- Inbound messages normalize into the shared channel envelope with reply metadata and media placeholders.
- Group sessions are isolated by group ID. Forum topics append
:topic:<threadId>to keep topics isolated. - DM messages can carry
message_thread_id; OpenClaw routes them with thread-aware session keys and preserves thread ID for replies. - Long polling uses grammY runner with per-chat/per-thread sequencing. Overall runner sink concurrency uses
agents.defaults.maxConcurrent. - Telegram Bot API has no read-receipt support (
sendReadReceiptsdoes not apply).
Feature reference
Section titled “Feature reference”Live stream preview (message edits)
OpenClaw can stream partial replies in real time:
- direct chats: preview message +
editMessageText - groups/topics: preview message +
editMessageText
Requirement:
channels.telegram.streamingisoff | partial | block | progress(default:partial)progressmaps topartialon Telegram (compat with cross-channel naming)- legacy
channels.telegram.streamModeand booleanstreamingvalues are auto-mapped
For text-only replies:
- DM: OpenClaw keeps the same preview message and performs a final edit in place (no second message)
- group/topic: OpenClaw keeps the same preview message and performs a final edit in place (no second message)
For complex replies (for example media payloads), OpenClaw falls back to normal final delivery and then cleans up the preview message.
Preview streaming is separate from block streaming. When block streaming is explicitly enabled for Telegram, OpenClaw skips the preview stream to avoid double-streaming.
If native draft transport is unavailable/rejected, OpenClaw automatically falls back to sendMessage + editMessageText.
Telegram-only reasoning stream:
/reasoning streamsends reasoning to the live preview while generating- final answer is sent without reasoning text
Formatting and HTML fallback
Outbound text uses Telegram parse_mode: "HTML".
- Markdown-ish text is rendered to Telegram-safe HTML.
- Raw model HTML is escaped to reduce Telegram parse failures.
- If Telegram rejects parsed HTML, OpenClaw retries as plain text.
Link previews are enabled by default and can be disabled with channels.telegram.linkPreview: false.
Native commands and custom commands
Telegram command menu registration is handled at startup with `setMyCommands`.
Native command defaults:
- `commands.native: "auto"` enables native commands for Telegram
Add custom command menu entries:{ channels: { telegram: { customCommands: [ { command: "backup", description: "Git backup" }, { command: "generate", description: "Create an image" }, ], }, },}Rules:
- names are normalized (strip leading `/`, lowercase)- valid pattern: `a-z`, `0-9`, `_`, length `1..32`- custom commands cannot override native commands- conflicts/duplicates are skipped and logged
Notes:
- custom commands are menu entries only; they do not auto-implement behavior- plugin/skill commands can still work when typed even if not shown in Telegram menu
If native commands are disabled, built-ins are removed. Custom/plugin commands may still register if configured.
Common setup failures:
- `setMyCommands failed` with `BOT_COMMANDS_TOO_MUCH` means the Telegram menu still overflowed after trimming; reduce plugin/skill/custom commands or disable `channels.telegram.commands.native`.- `setMyCommands failed` with network/fetch errors usually means outbound DNS/HTTPS to `api.telegram.org` is blocked.
### Device pairing commands (`device-pair` plugin)
When the `device-pair` plugin is installed:
1. `/pair` generates setup code2. paste code in iOS app3. `/pair pending` lists pending requests (including role/scopes)4. approve the request: - `/pair approvefor explicit approval -/pair approvewhen there is only one pending request -/pair approve latest` for most recent
If a device retries with changed auth details (for example role/scopes/public key), the previous pending request is superseded and the new request uses a different `requestId`. Re-run `/pair pending` before approving.
More details: [Pairing](/en/channels/pairing#pair-via-telegram-recommended-for-ios).Inline buttons
Configure inline keyboard scope:{ channels: { telegram: { capabilities: { inlineButtons: "allowlist", }, }, },}Per-account override:{ channels: { telegram: { accounts: { main: { capabilities: { inlineButtons: "allowlist", }, }, }, }, },}Scopes:
- `off`- `dm`- `group`- `all`- `allowlist` (default)
Legacy `capabilities: ["inlineButtons"]` maps to `inlineButtons: "all"`.
Message action example:{ 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" }], ],}Callback clicks are passed to the agent as text:`callback_data:`
Telegram message actions for agents and automation
Telegram tool actions include:
sendMessage(to,content, optionalmediaUrl,replyToMessageId,messageThreadId)react(chatId,messageId,emoji)deleteMessage(chatId,messageId)editMessage(chatId,messageId,content)createForumTopic(chatId,name, optionaliconColor,iconCustomEmojiId)
Channel message actions expose ergonomic aliases (send, react, delete, edit, sticker, sticker-search, topic-create).
Gating controls:
channels.telegram.actions.sendMessagechannels.telegram.actions.deleteMessagechannels.telegram.actions.reactionschannels.telegram.actions.sticker(default: disabled)
Note: edit and topic-create are currently enabled by default and do not have separate channels.telegram.actions.* toggles.
Runtime sends use the active config/secrets snapshot (startup/reload), so action paths do not perform ad-hoc SecretRef re-resolution per send.
Reaction removal semantics: /tools/reactions
Reply threading tags
Telegram supports explicit reply threading tags in generated output:
[[reply_to_current]]replies to the triggering message- `[[reply_to:
]]` replies to a specific Telegram message ID
`channels.telegram.replyToMode` controls handling:
- `off` (default)- `first`- `all`
Note: `off` disables implicit reply threading. Explicit `[[reply_to_*]]` tags are still honored.Forum topics and thread behavior
Forum supergroups:
- topic session keys append `:topic:
- replies and typing target the topic thread - topic config path: channels.telegram.groups.
.topics.
`
General topic (`threadId=1`) special-case:
- message sends omit `message_thread_id` (Telegram rejects `sendMessage(...thread_id=1)`)- typing actions still include `message_thread_id`
Topic inheritance: topic entries inherit group settings unless overridden (`requireMention`, `allowFrom`, `skills`, `systemPrompt`, `enabled`, `groupPolicy`).`agentId` is topic-only and does not inherit from group defaults.
**Per-topic agent routing**: Each topic can route to a different agent by setting `agentId` in the topic config. This gives each topic its own isolated workspace, memory, and session. Example:
```json5{ channels: { telegram: { groups: { "-1001234567890": { topics: { "1": { agentId: "main" }, // General topic → main agent "3": { agentId: "zu" }, // Dev topic → zu agent "5": { agentId: "coder" } // Code review → coder agent } } } } }}```
Each topic then has its own session key: `agent:zu:telegram:group:-1001234567890:topic:3`
**Persistent ACP topic binding**: Forum topics can pin ACP harness sessions through top-level typed ACP bindings:
- `bindings[]` with `type: "acp"` and `match.channel: "telegram"`
Example:
```json5{ agents: { list: [ { id: "codex", runtime: { type: "acp", acp: { agent: "codex", backend: "acpx", mode: "persistent", cwd: "/workspace/openclaw", }, }, }, ], }, bindings: [ { type: "acp", agentId: "codex", match: { channel: "telegram", accountId: "default", peer: { kind: "group", id: "-1001234567890:topic:42" }, }, }, ], channels: { telegram: { groups: { "-1001234567890": { topics: { "42": { requireMention: false, }, }, }, }, }, },}```
This is currently scoped to forum topics in groups and supergroups.
**Thread-bound ACP spawn from chat**:
- `/acp spawn—thread here|auto` can bind the current Telegram topic to a new ACP session.
- Follow-up topic messages route to the bound ACP session directly (no
/acp steerrequired). - OpenClaw pins the spawn confirmation message in-topic after a successful bind.
- Requires
channels.telegram.threadBindings.spawnAcpSessions=true.
Template context includes:
MessageThreadIdIsForum
DM thread behavior:
- private chats with
message_thread_idkeep DM routing but use thread-aware session keys/reply targets.
Audio, video, and stickers
### Audio messages
Telegram distinguishes voice notes vs audio files.
- default: audio file behavior- tag `[[audio_as_voice]]` in agent reply to force voice-note send
Message action example:{ action: "send", channel: "telegram", to: "123456789", media: "https://example.com/voice.ogg", asVoice: true,}### Video messages
Telegram distinguishes video files vs video notes.
Message action example:{ action: "send", channel: "telegram", to: "123456789", media: "https://example.com/video.mp4", asVideoNote: true,}Video notes do not support captions; provided message text is sent separately.
### Stickers
Inbound sticker handling:
- static WEBP: downloaded and processed (placeholder ``) - animated TGS: skipped - video WEBM: skipped
Sticker context fields:
- `Sticker.emoji`- `Sticker.setName`- `Sticker.fileId`- `Sticker.fileUniqueId`- `Sticker.cachedDescription`
Sticker cache file:
- `~/.openclaw/telegram/sticker-cache.json`
Stickers are described once (when possible) and cached to reduce repeated vision calls.
Enable sticker actions:{ channels: { telegram: { actions: { sticker: true, }, }, },}Send sticker action:{ action: "sticker", channel: "telegram", to: "123456789", fileId: "CAACAgIAAxkBAAI...",}Search cached stickers:{ action: "sticker-search", channel: "telegram", query: "cat waving", limit: 5,}Reaction notifications
Telegram reactions arrive as message_reaction updates (separate from message payloads).
When enabled, OpenClaw enqueues system events like:
Telegram reaction added: 👍 by Alice (@alice) on msg 42
Config:
channels.telegram.reactionNotifications:off | own | all(default:own)channels.telegram.reactionLevel:off | ack | minimal | extensive(default:minimal)
Notes:
ownmeans user reactions to bot-sent messages only (best-effort via sent-message cache).- Reaction events still respect Telegram access controls (
dmPolicy,allowFrom,groupPolicy,groupAllowFrom); unauthorized senders are dropped. - Telegram does not provide thread IDs in reaction updates.
- non-forum groups route to group chat session
- forum groups route to the group general-topic session (
:topic:1), not the exact originating topic
allowed_updates for polling/webhook include message_reaction automatically.
Ack reactions
ackReaction sends an acknowledgement emoji while OpenClaw is processing an inbound message.
Resolution order:
- `channels.telegram.accounts.
.ackReaction -channels.telegram.ackReaction -messages.ackReaction - agent identity emoji fallback (agents.list[].identity.emoji`, else ”👀”)
Notes:
- Telegram expects unicode emoji (for example "👀").- Use `""` to disable the reaction for a channel or account.Config writes from Telegram events and commands
Channel config writes are enabled by default (`configWrites !== false`).
Telegram-triggered writes include:
- group migration events (`migrate_to_chat_id`) to update `channels.telegram.groups`- `/config set` and `/config unset` (requires command enablement)
Disable:{ channels: { telegram: { configWrites: false, }, },}Long polling vs webhook
Default: long polling.
Webhook mode:
- set
channels.telegram.webhookUrl - set
channels.telegram.webhookSecret(required when webhook URL is set) - optional
channels.telegram.webhookPath(default/telegram-webhook) - optional
channels.telegram.webhookHost(default127.0.0.1) - optional
channels.telegram.webhookPort(default8787)
Default local listener for webhook mode binds to 127.0.0.1:8787.
If your public endpoint differs, place a reverse proxy in front and point webhookUrl at the public URL.
Set webhookHost (for example 0.0.0.0) when you intentionally need external ingress.
Limits, retry, and CLI targets
channels.telegram.textChunkLimitdefault is 4000.channels.telegram.chunkMode="newline"prefers paragraph boundaries (blank lines) before length splitting.channels.telegram.mediaMaxMb(default 100) caps inbound and outbound Telegram media size.channels.telegram.timeoutSecondsoverrides Telegram API client timeout (if unset, grammY default applies).- group context history uses
channels.telegram.historyLimitormessages.groupChat.historyLimit(default 50);0disables. - DM history controls:
channels.telegram.dmHistoryLimit- `channels.telegram.dms[”
“].historyLimit -channels.telegram.retry` config applies to Telegram send helpers (CLI/tools/actions) for recoverable outbound API errors.
CLI send target can be numeric chat ID or username:openclaw message send --channel telegram --target 123456789 --message "hi"openclaw message send --channel telegram --target @name --message "hi"Telegram polls use `openclaw message poll` and support forum topics:openclaw message poll --channel telegram --target 123456789 \ --poll-question "Ship it?" --poll-option "Yes" --poll-option "No"openclaw message poll --channel telegram --target -1001234567890:topic:42 \ --poll-question "Pick a time" --poll-option "10am" --poll-option "2pm" \ --poll-duration-seconds 300 --poll-publicTelegram-only poll flags:
- `--poll-duration-seconds` (5-600)- `--poll-anonymous`- `--poll-public`- `--thread-id` for forum topics (or use a `:topic:` target)
Telegram send also supports:
- `--buttons` for inline keyboards when `channels.telegram.capabilities.inlineButtons` allows it- `--force-document` to send outbound images and GIFs as documents instead of compressed photo or animated-media uploads
Action gating:
- `channels.telegram.actions.sendMessage=false` disables outbound Telegram messages, including polls- `channels.telegram.actions.poll=false` disables Telegram poll creation while leaving regular sends enabledExec approvals in Telegram
Telegram supports exec approvals in approver DMs and can optionally post approval prompts in the originating chat or topic.
Config path:
channels.telegram.execApprovals.enabledchannels.telegram.execApprovals.approvers(optional; falls back to numeric owner IDs inferred fromallowFromand directdefaultTowhen possible)channels.telegram.execApprovals.target(dm|channel|both, default:dm)agentFilter,sessionFilter
Approvers must be numeric Telegram user IDs. Telegram auto-enables native exec approvals when enabled is unset or "auto" and at least one approver can be resolved, either from execApprovals.approvers or from the account’s numeric owner config (allowFrom and direct-message defaultTo). Set enabled: false to disable Telegram as a native approval client explicitly. Approval requests otherwise fall back to other configured approval routes or the exec approval fallback policy.
Telegram also renders the shared approval buttons used by other chat channels. The native Telegram adapter mainly adds approver DM routing, channel/topic fanout, and typing hints before delivery.
Delivery rules:
target: "dm"sends approval prompts only to resolved approver DMstarget: "channel"sends the prompt back to the originating Telegram chat/topictarget: "both"sends to approver DMs and the originating chat/topic
Only resolved approvers can approve or deny. Non-approvers cannot use /approve and cannot use Telegram approval buttons.
Channel delivery shows the command text in the chat, so only enable channel or both in trusted groups/topics. When the prompt lands in a forum topic, OpenClaw preserves the topic for both the approval prompt and the post-approval follow-up. Exec approvals expire after 30 minutes by default.
Inline approval buttons also depend on channels.telegram.capabilities.inlineButtons allowing the target surface (dm, group, or all).
Related docs: Exec approvals
Error reply controls
Section titled “Error reply controls”When the agent encounters a delivery or provider error, Telegram can either reply with the error text or suppress it. Two config keys control this behavior:
| Key | Values | Default | Description |
|---|---|---|---|
channels.telegram.errorPolicy | reply, silent | reply | reply sends a friendly error message to the chat. silent suppresses error replies entirely. |
channels.telegram.errorCooldownMs | number (ms) | 60000 | Minimum time between error replies to the same chat. Prevents error spam during outages. |
Per-account, per-group, and per-topic overrides are supported (same inheritance as other Telegram config keys).
{ channels: { telegram: { errorPolicy: "reply", errorCooldownMs: 120000, groups: { "-1001234567890": { errorPolicy: "silent", // suppress errors in this group }, }, }, },}Troubleshooting
Section titled “Troubleshooting”Bot does not respond to non mention group messages
- If
requireMention=false, Telegram privacy mode must allow full visibility.- BotFather:
/setprivacy-> Disable - then remove + re-add bot to group
- BotFather:
openclaw channels statuswarns when config expects unmentioned group messages.openclaw channels status --probecan check explicit numeric group IDs; wildcard"*"cannot be membership-probed.- quick session test:
/activation always.
Bot not seeing group messages at all
- when
channels.telegram.groupsexists, group must be listed (or include"*") - verify bot membership in group
- review logs:
openclaw logs --followfor skip reasons
Commands work partially or not at all
- authorize your sender identity (pairing and/or numeric
allowFrom) - command authorization still applies even when group policy is
open setMyCommands failedwithBOT_COMMANDS_TOO_MUCHmeans the native menu has too many entries; reduce plugin/skill/custom commands or disable native menussetMyCommands failedwith network/fetch errors usually indicates DNS/HTTPS reachability issues toapi.telegram.org
Polling or network instability
- Node 22+ + custom fetch/proxy can trigger immediate abort behavior if AbortSignal types mismatch.- Some hosts resolve `api.telegram.org` to IPv6 first; broken IPv6 egress can cause intermittent Telegram API failures.- If logs include `TypeError: fetch failed` or `Network request for 'getUpdates' failed!`, OpenClaw now retries these as recoverable network errors.- On VPS hosts with unstable direct egress/TLS, route Telegram API calls through `channels.telegram.proxy`:channels: telegram: proxy: socks5://:
@proxy-host:1080
- Node 22+ defaults to `autoSelectFamily=true` (except WSL2) and `dnsResultOrder=ipv4first`. - If your host is WSL2 or explicitly works better with IPv4-only behavior, force family selection:
```yamlchannels: telegram: network: autoSelectFamily: false- Environment overrides (temporary): - `OPENCLAW_TELEGRAM_DISABLE_AUTO_SELECT_FAMILY=1` - `OPENCLAW_TELEGRAM_ENABLE_AUTO_SELECT_FAMILY=1` - `OPENCLAW_TELEGRAM_DNS_RESULT_ORDER=ipv4first`- Validate DNS answers:dig +short api.telegram.org Adig +short api.telegram.org AAAAMore help: Channel troubleshooting.
Telegram config reference pointers
Section titled “Telegram config reference pointers”Primary reference:
-
channels.telegram.enabled: enable/disable channel startup. -
channels.telegram.botToken: bot token (BotFather). -
channels.telegram.tokenFile: read token from a regular file path. Symlinks are rejected. -
channels.telegram.dmPolicy:pairing | allowlist | open | disabled(default: pairing). -
channels.telegram.allowFrom: DM allowlist (numeric Telegram user IDs).allowlistrequires at least one sender ID.openrequires"*".openclaw doctor --fixcan resolve legacy@usernameentries to IDs and can recover allowlist entries from pairing-store files in allowlist migration flows. -
channels.telegram.actions.poll: enable or disable Telegram poll creation (default: enabled; still requiressendMessage). -
channels.telegram.defaultTo: default Telegram target used by CLI--deliverwhen no explicit--reply-tois provided. -
channels.telegram.groupPolicy:open | allowlist | disabled(default: allowlist). -
channels.telegram.groupAllowFrom: group sender allowlist (numeric Telegram user IDs).openclaw doctor --fixcan resolve legacy@usernameentries to IDs. Non-numeric entries are ignored at auth time. Group auth does not use DM pairing-store fallback (2026.2.25+). -
Multi-account precedence:
- When two or more account IDs are configured, set
channels.telegram.defaultAccount(or includechannels.telegram.accounts.default) to make default routing explicit. - If neither is set, OpenClaw falls back to the first normalized account ID and
openclaw doctorwarns. channels.telegram.accounts.default.allowFromandchannels.telegram.accounts.default.groupAllowFromapply only to thedefaultaccount.- Named accounts inherit
channels.telegram.allowFromandchannels.telegram.groupAllowFromwhen account-level values are unset. - Named accounts do not inherit
channels.telegram.accounts.default.allowFrom/groupAllowFrom.
- When two or more account IDs are configured, set
-
channels.telegram.groups: per-group defaults + allowlist (use"*"for global defaults).channels.telegram.groups.<id>.groupPolicy: per-group override for groupPolicy (open | allowlist | disabled).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 whenfalse.channels.telegram.groups.<id>.topics.<threadId>.*: per-topic overrides (group fields + topic-onlyagentId).channels.telegram.groups.<id>.topics.<threadId>.agentId: route this topic to a specific agent (overrides group-level and binding routing).
-
channels.telegram.groups.<id>.topics.<threadId>.groupPolicy: per-topic override for groupPolicy (open | allowlist | disabled). -
channels.telegram.groups.<id>.topics.<threadId>.requireMention: per-topic mention gating override. -
top-level
bindings[]withtype: "acp"and canonical topic idchatId:topic:topicIdinmatch.peer.id: persistent ACP topic binding fields (see ACP Agents). -
channels.telegram.direct.<id>.topics.<threadId>.agentId: route DM topics to a specific agent (same behavior as forum topics). -
channels.telegram.execApprovals.enabled: enable Telegram as a chat-based exec approval client for this account. -
channels.telegram.execApprovals.approvers: Telegram user IDs allowed to approve or deny exec requests. Optional whenchannels.telegram.allowFromor a directchannels.telegram.defaultToalready identifies the owner. -
channels.telegram.execApprovals.target:dm | channel | both(default:dm).channelandbothpreserve the originating Telegram topic when present. -
channels.telegram.execApprovals.agentFilter: optional agent ID filter for forwarded approval prompts. -
channels.telegram.execApprovals.sessionFilter: optional session key filter (substring or regex) for forwarded approval prompts. -
channels.telegram.accounts.<account>.execApprovals: per-account override for Telegram exec approval routing and approver authorization. -
channels.telegram.capabilities.inlineButtons:off | dm | group | all | allowlist(default: allowlist). -
channels.telegram.accounts.<account>.capabilities.inlineButtons: per-account override. -
channels.telegram.commands.nativeSkills: enable/disable Telegram native skills commands. -
channels.telegram.replyToMode:off | first | all(default:off). -
channels.telegram.textChunkLimit: outbound chunk size (chars). -
channels.telegram.chunkMode:length(default) ornewlineto split on blank lines (paragraph boundaries) before length chunking. -
channels.telegram.linkPreview: toggle link previews for outbound messages (default: true). -
channels.telegram.streaming:off | partial | block | progress(live stream preview; default:partial;progressmaps topartial;blockis legacy preview mode compatibility). Telegram preview streaming uses a single preview message that is edited in place. -
channels.telegram.mediaMaxMb: inbound/outbound Telegram media cap (MB, default: 100). -
channels.telegram.retry: retry policy for Telegram send helpers (CLI/tools/actions) on recoverable outbound API errors (attempts, minDelayMs, maxDelayMs, jitter). -
channels.telegram.network.autoSelectFamily: override Node autoSelectFamily (true=enable, false=disable). Defaults to enabled on Node 22+, with WSL2 defaulting to disabled. -
channels.telegram.network.dnsResultOrder: override DNS result order (ipv4firstorverbatim). Defaults toipv4firston Node 22+. -
channels.telegram.proxy: proxy URL for Bot API calls (SOCKS/HTTP). -
channels.telegram.webhookUrl: enable webhook mode (requireschannels.telegram.webhookSecret). -
channels.telegram.webhookSecret: webhook secret (required when webhookUrl is set). -
channels.telegram.webhookPath: local webhook path (default/telegram-webhook). -
channels.telegram.webhookHost: local webhook bind host (default127.0.0.1). -
channels.telegram.webhookPort: local webhook bind port (default8787). -
channels.telegram.actions.reactions: gate Telegram tool reactions. -
channels.telegram.actions.sendMessage: gate Telegram tool message sends. -
channels.telegram.actions.deleteMessage: gate Telegram tool message deletes. -
channels.telegram.actions.sticker: gate Telegram sticker actions — send and search (default: false). -
channels.telegram.reactionNotifications:off | own | all— control which reactions trigger system events (default:ownwhen not set). -
channels.telegram.reactionLevel:off | ack | minimal | extensive— control agent’s reaction capability (default:minimalwhen not set). -
channels.telegram.errorPolicy:reply | silent— control error reply behavior (default:reply). Per-account/group/topic overrides supported. -
channels.telegram.errorCooldownMs: minimum ms between error replies to the same chat (default:60000). Prevents error spam during outages.
Telegram-specific high-signal fields:
- startup/auth:
enabled,botToken,tokenFile,accounts.*(tokenFilemust point to a regular file; symlinks are rejected) - access control:
dmPolicy,allowFrom,groupPolicy,groupAllowFrom,groups,groups.*.topics.*, top-levelbindings[](type: "acp") - exec approvals:
execApprovals,accounts.*.execApprovals - command/menu:
commands.native,commands.nativeSkills,customCommands - threading/replies:
replyToMode - streaming:
streaming(preview),blockStreaming - formatting/delivery:
textChunkLimit,chunkMode,linkPreview,responsePrefix - media/network:
mediaMaxMb,timeoutSeconds,retry,network.autoSelectFamily,proxy - webhook:
webhookUrl,webhookSecret,webhookPath,webhookHost - actions/capabilities:
capabilities.inlineButtons,actions.sendMessage|editMessage|deleteMessage|reactions|sticker - reactions:
reactionNotifications,reactionLevel - errors:
errorPolicy,errorCooldownMs - writes/history:
configWrites,historyLimit,dmHistoryLimit,dms.*.historyLimit