Telegram (Bot API)¶
Statut : prĂȘt pour la production pour les Messages prives des bots + les groupes via grammY. Long-polling par dĂ©faut ; webhook optionnel.
Configuration (chemin rapide)¶
@BotFather.
```
`/newbot` cree le bot et renvoie le token (gardezâle secret).
```
{
channels: {
telegram: {
enabled: true,
botToken: "123:abc",
dmPolicy: "pairing",
groups: { "*": { requireMention: true } },
},
},
}
```
Option env : `TELEGRAM_BOT_TOKEN=...` (fonctionne pour le compte par defaut).
```
`openclaw pairing approve telegram <CODE>`
```
Pairing codes expire after 1 hour.
```
channels.telegram.groups pour controler le filtrage par mention + les listes dâautorisation.
TELEGRAM_BOT_TOKEN only applies to the default account.
Telegram side settings¶
```
`/setprivacy` â controler si le bot voit tous les messages de groupe.
```
```
Ajouter le bot comme **admin** du groupe (les bots admins recoivent tous les messages).
```
```
`/setjoingroups` â autoriser/interdire lâajout du bot aux groupes.
```
Access control and activation¶
channels.telegram.dmPolicy controls direct message access:
```
`channels.telegram.allowFrom` accepte des IDs utilisateur numeriques (recommande) ou des entrees `@username`. Ce nâest **pas** le nom dâutilisateur du bot ; utilisez lâID de lâexpediteur humain. Lâassistant accepte `@username` et le resout vers lâID numerique lorsque possible.
```
curl "https://api.telegram.org/bot<bot_token>/getUpdates"
```
Envoyez un Message prive a `@userinfobot` ou `@getidsbot` et utilisez lâID utilisateur renvoye.
```
```
{
channels: {
telegram: {
groups: {
"*": { requireMention: false }, // all groups, always respond
},
},
},
}
```
{
channels: {
telegram: {
groups: {
"-1001234567890": {
groupPolicy: "open",
requireMention: false,
},
},
},
},
}
```
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: true }, // or omit groups entirely
},
},
},
}
```
Transmettez nâimporte quel message du groupe a `@userinfobot` ou `@getidsbot` sur Telegram pour voir lâID du chat (nombre negatif comme `-1001234567890`).
```
Runtime behavior¶
- Telegram is owned by the gateway process.
- Routage deterministe : les reponses repartent vers Telegram ; le modele ne choisit jamais les canaux.
- Les messages entrants sont normalises dans lâenveloppe de canal partagee avec contexte de reponse et emplacements media.
- Group sessions are isolated by group ID. Ajoute
:topic:<threadId>a la cle de session du groupe Telegram afin que chaque sujet soit isole. - Les chats prives peuvent inclure
message_thread_iddans certains cas limites. OpenClaw conserve la cle de session DM inchangĂ©e, mais utilise tout de meme lâid de fil pour les reponses/le streaming de brouillons lorsquâil est present. - Long polling uses grammY runner with per-chat/per-thread sequencing. Le longâpolling utilise le runner grammY avec un sequencage par chat ; la concurrence globale est plafonnee par
agents.defaults.maxConcurrent. - LâAPI Bot Telegram ne prend pas en charge les accusĂ©s de lecture ; il nâexiste pas dâoption
sendReadReceipts.
Feature reference¶
sendMessageDraft.
```
Requirement:
- `channels.telegram.streamMode` is not `"off"` (default: `"partial"`)
Modes:
- `off`: no live preview
- `partial`: frequent preview updates from partial text
- `block`: chunked preview updates using `channels.telegram.draftChunk`
`draftChunk` defaults for `streamMode: "block"`:
- `minChars: 200`
- `maxChars: 800`
- `breakPreference: "paragraph"`
`maxChars` is clamped by `channels.telegram.textChunkLimit`.
This works in direct chats and groups/topics.
For text-only replies, 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.
`streamMode` is separate from block streaming. When block streaming is explicitly enabled for Telegram, OpenClaw skips the preview stream to avoid double-streaming.
Telegram-only reasoning stream:
- `/reasoning stream` sends reasoning to the live preview while generating
- final answer is sent without reasoning text
```
parse_mode: "HTML" (sousâensemble de balises pris en charge par Telegram).
```
- 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`.
```
```
OpenClaw enregistre des commandes natives (comme `/status`, `/reset`, `/model`) dans le menu de bot Telegram au demarrage. Vous pouvez ajouter des commandes personnalisees au menu via la config :
```
{
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 failure:
- `setMyCommands failed` 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 code
2. paste code in iOS app
3. `/pair approve` approves latest pending request
More details: [Pairing](/channels/pairing#pair-via-telegram-recommended-for-ios).
```
{
channels: {
telegram: {
capabilities: {
inlineButtons: "allowlist",
},
},
},
}
```
Per-account override:
```
{
channels: {
telegram: {
accounts: {
main: {
capabilities: {
inlineButtons: "allowlist",
},
},
},
},
},
}
```
`"disabled"` = aucun message de groupe accepte
La valeur par defaut est `groupPolicy: "allowlist"` (bloque tant que vous nâajoutez pas `groupAllowFrom`).
```
{
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" }],
],
}
```
Lorsquâun utilisateur clique sur un bouton, les donnees de rappel sont renvoyees a lâagent sous forme de message au format :
`callback_data: value`
```
```
- `sendMessage` (`to`, `content`, optional `mediaUrl`, `replyToMessageId`, `messageThreadId`)
- `react` (`chatId`, `messageId`, `emoji`)
- `deleteMessage` (`chatId`, `messageId`)
- `editMessage` (`chatId`, `messageId`, `content`)
Channel message actions expose ergonomic aliases (`send`, `react`, `delete`, `edit`, `sticker`, `sticker-search`).
Gating controls:
- `channels.telegram.actions.sendMessage`
- `channels.telegram.actions.editMessage`
- `channels.telegram.actions.deleteMessage`
- `channels.telegram.actions.reactions`
- `channels.telegram.actions.sticker` (default: disabled)
Reaction removal semantics: [/tools/reactions](/tools/reactions)
```
```
- `[[reply_to_current]]` replies to the triggering message
- `[[reply_to:<id>]]` 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.
```
```
Fils de discussion en chat prive uniquement (Telegram inclut `message_thread_id` dans les messages entrants).
```
```
`[[audio_as_voice]]` â envoyer lâaudio comme note vocale au lieu dâun fichier.
```
{
action: "send",
channel: "telegram",
to: "123456789",
media: "https://example.com/voice.ogg",
asVoice: true,
}
```
Video messages (video vs video note)
```
{
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 `<media:sticker>`)
- 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,
},
},
},
}
```
Envoi dâautocollants
```
{
action: "sticker",
channel: "telegram",
to: "123456789",
fileId: "CAACAgIAAxkBAAI...",
}
```
Cache des autocollants
```
{
action: "sticker-search",
channel: "telegram",
query: "cat waving",
limit: 5,
}
message_reaction depuis lâAPI Telegram
```
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:
- `own` means user reactions to bot-sent messages only (best-effort via sent-message cache).
- 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.
```
message_reaction distincts, et non comme des proprietes dans les charges de message. Lorsquâun utilisateur ajoute une reaction, OpenClaw :
```
Resolution order:
- `channels.telegram.accounts.<accountId>.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.
```
configWrites !== false).
```
Par defaut, Telegram est autorise a ecrire des mises a jour de configuration declenchees par des evenements de canal ou `/config set|unset`.
```
{
channels: { telegram: { configWrites: false } },
}
```
Si votre URL publique est differente, utilisez un proxy inverse et pointez `channels.telegram.webhookUrl` vers le point de terminaison public.
```
channels.telegram.textChunkLimit (par defaut 4000).
Segmentation optionnelle par sauts de ligne : definissez channels.telegram.chunkMode="newline" pour scinder sur les lignes vides (frontieres de paragraphes) avant la segmentation par longueur.
Les telechargements/envois de medias sont plafonnes par channels.telegram.mediaMaxMb (par defaut 5).
Les requetes API Bot Telegram expirent apres channels.telegram.timeoutSeconds (par defaut 500 via grammY).
Le contexte dâhistorique de groupe utilise channels.telegram.historyLimit (ou channels.telegram.accounts.*.historyLimit), avec repli sur messages.groupChat.historyLimit. Definissez 0 pour desactiver (par defaut 50).
- DM history controls:
- channels.telegram.dmHistoryLimit
- channels.telegram.dms["<user_id>"].historyLimit
- outbound Telegram API retries are configurable via channels.telegram.retry.
```
CLI send target can be numeric chat ID or username:
```
Exemple : `openclaw message send --channel telegram --target 123456789 --message "hi"`.
Problemes courants¶
```
Si vous avez defini `channels.telegram.groups.*.requireMention=false`, le **mode confidentialite** de lâAPI Bot Telegram doit etre desactive.
```
```
- when `channels.telegram.groups` exists, group must be listed (or include `"*"`)
- verify bot membership in group
- review logs: `openclaw logs --follow` for skip reasons
```
```
`setMyCommands failed` dans les journaux signifie generalement que la sortie HTTPS/DNS est bloquee vers `api.telegram.org`.
```
```
- 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.
- Validate DNS answers:
```
dig +short api.telegram.org A
dig +short api.telegram.org AAAA
Plus dâaide : Depannage des canaux.
Reference de configuration (Telegram)¶
Primary reference:
-
channels.telegram.enabled : activer/desactiver le demarrage du canal. -
channels.telegram.botToken : token du bot (BotFather). -
channels.telegram.tokenFile : lire le token depuis un chemin de fichier. -
channels.telegram.dmPolicy :pairing | allowlist | open | disabled(par defaut : appairage). -
channels.telegram.allowFrom : liste dâautorisation DM (ids/noms dâutilisateur).openrequiert"*".openclaw doctor --fixcan resolve legacy@usernameentries to IDs. -
channels.telegram.groupPolicy :open | allowlist | disabled(par defaut : liste dâautorisation). -
channels.telegram.groupAllowFrom : liste dâautorisation des expĂ©diteurs de groupe (ids/noms dâutilisateur).openclaw doctor --fixcan resolve legacy@usernameentries to IDs. -
channels.telegram.groups : valeurs par defaut par groupe + liste dâautorisation (utilisez"*"pour les valeurs globales). channels.telegram.groups.<id>.groupPolicy : surcharge par groupe pour groupPolicy (open | allowlist | disabled).channels.telegram.groups.<id>.requireMention : filtrage par mention par defaut.channels.telegram.groups.<id>.skills : filtre de skills (omis = tous les skills, vide = aucun).channels.telegram.groups.<id>.allowFrom : surcharge de liste dâautorisation des expĂ©diteurs par groupe.channels.telegram.groups.<id>.systemPrompt : invite systeme supplementaire pour le groupe.channels.telegram.groups.<id>.enabled : desactiver le groupe lorsquefalse.- .topics.
channels.telegram.groups.<id>.* : surcharges par sujet (memes champs que le groupe). channels.telegram.groups.<id>.topics.<threadId>.groupPolicy : surcharge par sujet pour groupPolicy (open | allowlist | disabled).-
.topics.
channels.telegram.groups.<id>.requireMention : surcharge de filtrage par mention par sujet. -
channels.telegram.capabilities.inlineButtons :off | dm | group | all | allowlist(par defaut : liste dâautorisation). -
channels.telegram.accounts.<account>.capabilities.inlineButtons : surcharge par compte. -
channels.telegram.replyToMode :off | first | all(par defaut :first). -
channels.telegram.textChunkLimit : taille de segmentation sortante (caracteres). -
channels.telegram.chunkMode :length(par defaut) ounewlinepour scinder sur les lignes vides (frontieres de paragraphes) avant la segmentation par longueur. -
channels.telegram.linkPreview : activer/desactiver les apercus de lien pour les messages sortants (par defaut : true). -
channels.telegram.streamMode :off | partial | block(streaming de brouillons). -
channels.telegram.mediaMaxMb : plafond media entrant/sortant (Mo). -
channels.telegram.retry : politique de reessai pour les appels API Telegram sortants (tentatives, minDelayMs, maxDelayMs, jitter). -
channels.telegram.network.autoSelectFamily : surcharge de Node autoSelectFamily (true=activer, false=desactiver). Desactive par defaut sur Node 22 pour eviter les delais Happy Eyeballs. -
channels.telegram.proxy : URL de proxy pour les appels API Bot (SOCKS/HTTP). -
channels.telegram.webhookUrl : activer le mode webhook (necessitechannels.telegram.webhookSecret). -
channels.telegram.webhookSecret : secret de webhook (requis lorsque webhookUrl est defini). -
channels.telegram.webhookPath : chemin local du webhook (par defaut/telegram-webhook). -
Lâecouteur local se lie a
0.0.0.0:8787et sertPOST /telegram-webhookpar defaut. -
channels.telegram.actions.reactions : filtrer les reactions de lâoutil Telegram. -
channels.telegram.actions.sendMessage : filtrer les envois de messages de lâoutil Telegram. -
channels.telegram.actions.deleteMessage : filtrer les suppressions de messages de lâoutil Telegram. -
channels.telegram.actions.sticker : filtrer les actions dâautocollants Telegram â envoi et recherche (par defaut : false). -
channels.telegram.reactionNotifications :off | own | allâ controler quelles reactions declenchent des evenements systeme (par defaut :ownlorsquâil nâest pas defini). -
channels.telegram.reactionLevel :off | ack | minimal | extensiveâ controler la capacite de reaction de lâagent (par defaut :minimallorsquâil nâest pas defini). -
Configuration complete : Configuration
Telegram-specific high-signal fields:
- startup/auth:
enabled,botToken,tokenFile,accounts.* - Les commandes necessitent une autorisation meme dans les groupes avec
groupPolicy: "open" - command/menu:
commands.native,customCommands - threading/replies:
replyToMode - Optionnel (uniquement pour
streamMode: "block")Â : - formatting/delivery:
textChunkLimit,chunkMode,linkPreview,responsePrefix - media/network:
mediaMaxMb,timeoutSeconds,retry,network.autoSelectFamily,proxy - Mode webhook : definissez
channels.telegram.webhookUrletchannels.telegram.webhookSecret(optionnellementchannels.telegram.webhookPath). - actions/capabilities:
capabilities.inlineButtons,actions.sendMessage|editMessage|deleteMessage|reactions|sticker - Notifications de reactions
- writes/history:
configWrites,historyLimit,dmHistoryLimit,dms.*.historyLimit