Telegram (Bot API)

Status: productieklaar voor bot-DM’s + groepen via grammY. Long polling is de standaardmodus; webhookmodus is optioneel.

Snelle installatie

Stap 1: Maak het bot-token aan in BotFather

Open Telegram en chat met **@BotFather** (bevestig dat de handle exact `@BotFather` is).

Voer `/newbot` uit, volg de aanwijzingen en sla het token op.

Stap 2: Configureer token en DM-beleid

{
  channels: {
    telegram: {
      enabled: true,
      botToken: "123:abc",
      dmPolicy: "pairing",
      groups: { "*": { requireMention: true } },
    },
  },
}
Env-terugval: `TELEGRAM_BOT_TOKEN=...` (alleen standaardaccount).
Telegram gebruikt **geen** `openclaw channels login telegram`; configureer het token in config/env en start vervolgens de gateway.

Stap 3: Start de gateway en keur eerste DM goed

openclaw gateway
openclaw pairing list telegram
openclaw pairing approve telegram <CODE>
Koppelingscodes verlopen na 1 uur.

Stap 4: Voeg de bot toe aan een groep

Voeg de bot toe aan je groep en stel vervolgens `channels.telegram.groups` en `groupPolicy` in die aansluiten bij je toegangsmodel.

Opmerking: Tokenresolutie is accountbewust. In de praktijk winnen configwaarden van env-terugval, en TELEGRAM_BOT_TOKEN geldt alleen voor het standaardaccount.

Telegram-instellingen

Privacymodus en groepszichtbaarheid
Telegram-bots staan standaard in **Privacymodus**, wat beperkt welke groepsberichten ze ontvangen.

Als de bot alle groepsberichten moet zien, doe dan een van de volgende:

- schakel privacymodus uit via `/setprivacy`, of
- maak de bot een groepsbeheerder.

Na het wisselen van privacymodus moet je de bot verwijderen en opnieuw toevoegen in elke groep zodat Telegram de wijziging toepast.
Groepsmachtigingen
Beheerdersstatus wordt beheerd in Telegram-groepsinstellingen.

Beheerderbots ontvangen alle groepsberichten, wat handig is voor altijd-aan-groepsgedrag.
Handige BotFather-schakelaars
- `/setjoingroups` om groepstoevoegingen toe te staan/weigeren
- `/setprivacy` voor groepszichtbaarheidsgedrag

Toegangscontrole en activering

DM-beleid

`channels.telegram.dmPolicy` beheert directe berichttoegang:

- `pairing` (standaard)
- `allowlist` (vereist minstens een afzender-ID in `allowFrom`)
- `open` (vereist dat `allowFrom` `"*"` bevat)
- `disabled`

`channels.telegram.allowFrom` accepteert numerieke Telegram-gebruikers-ID's. `telegram:` / `tg:`-prefixen worden geaccepteerd en genormaliseerd.
`dmPolicy: "allowlist"` met lege `allowFrom` blokkeert alle DM's en wordt afgewezen door configvalidatie.
De onboardingwizard accepteert `@username`-invoer en lost deze op naar numerieke ID's.
Als je hebt geüpgraded en je configuratie `@username`-allowlist-vermeldingen bevat, voer `openclaw doctor --fix` uit om ze op te lossen (best-effort; vereist een Telegram-bot-token).
Als je eerder op pairing-store-allowlistbestanden vertrouwde, kan `openclaw doctor --fix` vermeldingen herstellen naar `channels.telegram.allowFrom` in allowlist-flows (bijvoorbeeld wanneer `dmPolicy: "allowlist"` nog geen expliciete ID's heeft).

Voor bots met een enkele eigenaar, gebruik bij voorkeur `dmPolicy: "allowlist"` met expliciete numerieke `allowFrom`-ID's om het toegangsbeleid duurzaam in de configuratie te houden (in plaats van afhankelijk te zijn van eerdere koppelingsgoedkeuringen).

### Je Telegram-gebruikers-ID vinden

Veiliger (geen bot van derden):

1. DM je bot.
2. Voer `openclaw logs --follow` uit.
3. Lees `from.id`.

Officiële Bot API-methode:
curl "https://api.telegram.org/bot<bot_token>/getUpdates"
Methode van derden (minder privé): `@userinfobot` of `@getidsbot`.

Groepsbeleid en allowlists

Twee controles werken samen:

1. **Welke groepen zijn toegestaan** (`channels.telegram.groups`)
   - geen `groups`-configuratie:
     - met `groupPolicy: "open"`: elke groep passeert groeps-ID-controles
     - met `groupPolicy: "allowlist"` (standaard): groepen worden geblokkeerd totdat je `groups`-vermeldingen (of `"*"`) toevoegt
   - `groups` geconfigureerd: fungeert als allowlist (expliciete ID's of `"*"`)

2. **Welke afzenders zijn toegestaan in groepen** (`channels.telegram.groupPolicy`)
   - `open`
   - `allowlist` (standaard)
   - `disabled`

`groupAllowFrom` wordt gebruikt voor groepsafzenderfiltering. Indien niet ingesteld, valt Telegram terug op `allowFrom`.
`groupAllowFrom`-vermeldingen moeten numerieke Telegram-gebruikers-ID's zijn (`telegram:` / `tg:`-prefixen worden genormaliseerd).
Zet geen Telegram-groeps- of supergroeps-chat-ID's in `groupAllowFrom`. Negatieve chat-ID's horen onder `channels.telegram.groups`.
Niet-numerieke vermeldingen worden genegeerd voor afzenderautorisatie.
Beveiligingsgrens (`2026.2.25+`): groepsafzenderauth erft **niet** van DM-pairing-store-goedkeuringen.
Koppeling blijft DM-only. Voor groepen stel je `groupAllowFrom` of per-groep/per-topic `allowFrom` in.
Runtime-opmerking: als `channels.telegram` volledig ontbreekt, valt de runtime standaard terug op fail-closed `groupPolicy="allowlist"` tenzij `channels.defaults.groupPolicy` expliciet is ingesteld.

Voorbeeld: elk lid in een specifieke groep toestaan:
{
  channels: {
    telegram: {
      groups: {
        "-1001234567890": {
          groupPolicy: "open",
          requireMention: false,
        },
      },
    },
  },
}
Voorbeeld: alleen specifieke gebruikers in een specifieke groep toestaan:
{
  channels: {
    telegram: {
      groups: {
        "-1001234567890": {
          requireMention: true,
          allowFrom: ["8734062810", "745123456"],
        },
      },
    },
  },
}
> **Waarschuwing:**

Veelgemaakte fout: groupAllowFrom is geen Telegram-groeps-allowlist.

  - Zet negatieve Telegram-groeps- of supergroeps-chat-ID's zoals `-1001234567890` onder `channels.telegram.groups`.
  - Zet Telegram-gebruikers-ID's zoals `8734062810` onder `groupAllowFrom` wanneer je wilt beperken welke mensen in een toegestane groep de bot kunnen triggeren.
  - Gebruik `groupAllowFrom: ["*"]` alleen wanneer je wilt dat elk lid van een toegestane groep met de bot kan praten.

Vermeldingsgedrag

Groepsantwoorden vereisen standaard een vermelding.

Een vermelding kan komen van:

- native `@botusername`-vermelding, of
- vermeldingspatronen in:
  - `agents.list[].groupChat.mentionPatterns`
  - `messages.groupChat.mentionPatterns`

Sessieniveau-commandoschakelaars:

- `/activation always`
- `/activation mention`

Deze werken alleen de sessiestatus bij. Gebruik config voor persistentie.

Persistent configuratie-voorbeeld:
{
  channels: {
    telegram: {
      groups: {
        "*": { requireMention: false },
      },
    },
  },
}
De groepschat-ID opzoeken:

- stuur een groepsbericht door naar `@userinfobot` / `@getidsbot`
- of lees `chat.id` uit `openclaw logs --follow`
- of inspecteer Bot API `getUpdates`

Runtimegedrag

  • Telegram wordt beheerd door het gatewayproces.
  • Routering is deterministisch: Telegram-inkomende berichten antwoorden terug naar Telegram (het model kiest geen kanalen).
  • Inkomende berichten worden genormaliseerd naar de gedeelde kanaalenvelop met antwoordmetadata en mediatijdelijke aanduidingen.
  • Groepssessies zijn geïsoleerd per groeps-ID. Forum-topics voegen :topic:<threadId> toe om topics geïsoleerd te houden.
  • DM-berichten kunnen message_thread_id bevatten; OpenClaw routeert ze met thread-bewuste sessiesleutels en bewaart thread-ID voor antwoorden.
  • Long polling gebruikt grammY-runner met per-chat/per-thread-sequentiëring. Algehele runner-sink-concurrency gebruikt agents.defaults.maxConcurrent.
  • Telegram Bot API heeft geen leesbevestigingsondersteuning (sendReadReceipts is niet van toepassing).

Functiereferentie

Live stream preview (berichtbewerkingen)
OpenClaw kan deelantwoorden in realtime streamen:

- directe chats: preview-bericht + `editMessageText`
- groepen/topics: preview-bericht + `editMessageText`

Vereiste:

- `channels.telegram.streaming` is `off | partial | block | progress` (standaard: `partial`)
- `progress` mapt naar `partial` op Telegram (compatibiliteit met kanaaloverschrijdende naamgeving)
- verouderde `channels.telegram.streamMode` en boolean `streaming`-waarden worden automatisch gemapt

Voor alleen-tekst-antwoorden:

- DM: OpenClaw houdt hetzelfde preview-bericht en voert een definitieve bewerking ter plaatse uit (geen tweede bericht)
- groep/topic: OpenClaw houdt hetzelfde preview-bericht en voert een definitieve bewerking ter plaatse uit (geen tweede bericht)

Voor complexe antwoorden (bijvoorbeeld mediapayloads) valt OpenClaw terug op normale definitieve aflevering en ruimt vervolgens het preview-bericht op.

Preview-streaming is apart van blokstreaming. Wanneer blokstreaming expliciet is ingeschakeld voor Telegram, slaat OpenClaw de preview-stream over om dubbel streamen te voorkomen.

Als native draft-transport niet beschikbaar/geweigerd is, valt OpenClaw automatisch terug op `sendMessage` + `editMessageText`.

Telegram-only reasoning-stream:

- `/reasoning stream` stuurt reasoning naar de live preview tijdens het genereren
- het uiteindelijke antwoord wordt verstuurd zonder reasoning-tekst
Opmaak en HTML-terugval
Uitgaande tekst gebruikt Telegram `parse_mode: "HTML"`.

- Markdown-achtige tekst wordt gerenderd naar Telegram-veilige HTML.
- Onbewerkte model-HTML wordt ge-escaped om Telegram-parsefouten te verminderen.
- Als Telegram geparsede HTML afwijst, probeert OpenClaw opnieuw als platte tekst.

Linkpreviews zijn standaard ingeschakeld en kunnen worden uitgeschakeld met `channels.telegram.linkPreview: false`.
Native commando's en aangepaste commando's
Telegram-commandomenuregistratie wordt bij opstart afgehandeld met `setMyCommands`.

Native commando-standaarden:

- `commands.native: "auto"` schakelt native commando's in voor Telegram

Voeg aangepaste commandomenuvermeldingen toe:
{
  channels: {
    telegram: {
      customCommands: [
        { command: "backup", description: "Git backup" },
        { command: "generate", description: "Create an image" },
      ],
    },
  },
}
Regels:

- namen worden genormaliseerd (strip voorafgaande `/`, kleine letters)
- geldig patroon: `a-z`, `0-9`, `_`, lengte `1..32`
- aangepaste commando's kunnen geen native commando's overschrijven
- conflicten/duplicaten worden overgeslagen en gelogd

Opmerkingen:

- aangepaste commando's zijn alleen menuvermeldingen; ze implementeren niet automatisch gedrag
- plugin-/skillcommando's kunnen nog steeds werken wanneer getypt, zelfs als ze niet in het Telegram-menu worden getoond

Als native commando's zijn uitgeschakeld, worden ingebouwde commando's verwijderd. Aangepaste/plugincommando's kunnen nog steeds worden geregistreerd indien geconfigureerd.

Veelvoorkomende setupfouten:

- `setMyCommands failed` met `BOT_COMMANDS_TOO_MUCH` betekent dat het Telegram-menu na trimming nog steeds te vol was; verminder plugin-/skill-/aangepaste commando's of schakel `channels.telegram.commands.native` uit.
- `setMyCommands failed` met netwerk-/fetchfouten betekent meestal dat uitgaande DNS/HTTPS naar `api.telegram.org` wordt geblokkeerd.

### Apparaatkoppelingscommando's (`device-pair`-plugin)

Wanneer de `device-pair`-plugin is geïnstalleerd:

1. `/pair` genereert een setupcode
2. plak de code in de iOS-app
3. `/pair approve` keurt het laatste openstaande verzoek goed

Meer details: [Koppeling](/docs/channels/pairing#pair-via-telegram-recommended-for-ios).
Inline knoppen
Configureer inline keyboard-bereik:
{
  channels: {
    telegram: {
      capabilities: {
        inlineButtons: "allowlist",
      },
    },
  },
}
Per-account-overschrijving:
{
  channels: {
    telegram: {
      accounts: {
        main: {
          capabilities: {
            inlineButtons: "allowlist",
          },
        },
      },
    },
  },
}
Bereiken:

- `off`
- `dm`
- `group`
- `all`
- `allowlist` (standaard)

Verouderde `capabilities: ["inlineButtons"]` mapt naar `inlineButtons: "all"`.

Berichtactie-voorbeeld:
{
  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-klikken worden als tekst aan de agent doorgegeven:
`callback_data: <value>`
Telegram-berichtacties voor agents en automatisering
Telegram-toolacties omvatten:

- `sendMessage` (`to`, `content`, optioneel `mediaUrl`, `replyToMessageId`, `messageThreadId`)
- `react` (`chatId`, `messageId`, `emoji`)
- `deleteMessage` (`chatId`, `messageId`)
- `editMessage` (`chatId`, `messageId`, `content`)
- `createForumTopic` (`chatId`, `name`, optioneel `iconColor`, `iconCustomEmojiId`)

Kanaalberichtacties bieden ergonomische aliassen (`send`, `react`, `delete`, `edit`, `sticker`, `sticker-search`, `topic-create`).

Gating-controles:

- `channels.telegram.actions.sendMessage`
- `channels.telegram.actions.deleteMessage`
- `channels.telegram.actions.reactions`
- `channels.telegram.actions.sticker` (standaard: uitgeschakeld)

Opmerking: `edit` en `topic-create` zijn momenteel standaard ingeschakeld en hebben geen aparte `channels.telegram.actions.*`-schakelaars.
Runtime-verzendingen gebruiken de actieve config-/secretssnapshot (opstart/herladen), dus actiepaden voeren geen ad-hoc SecretRef-herresolutie per verzending uit.

Reactieverwijderingssemantiek: [/tools/reactions](/docs/tools/reactions)
Reply-threading-tags
Telegram ondersteunt expliciete reply-threading-tags in gegenereerde uitvoer:

- `[[reply_to_current]]` antwoordt op het triggerende bericht
- `[[reply_to:<id>]]` antwoordt op een specifiek Telegram-bericht-ID

`channels.telegram.replyToMode` beheert de afhandeling:

- `off` (standaard)
- `first`
- `all`

Opmerking: `off` schakelt impliciete reply-threading uit. Expliciete `[[reply_to_*]]`-tags worden nog steeds gehonoreerd.
Forum-topics en threadgedrag
Forum-supergroepen:

- topic-sessiesleutels voegen `:topic:<threadId>` toe
- antwoorden en typen targeten de topic-thread
- topic-configuratiepad:
  `channels.telegram.groups.<chatId>.topics.<threadId>`

Algemeen topic (`threadId=1`) speciale gevallen:

- berichtverzendingen laten `message_thread_id` weg (Telegram wijst `sendMessage(...thread_id=1)` af)
- typacties bevatten nog steeds `message_thread_id`

Topic-overerving: topicvermeldingen erven groepsinstellingen tenzij overschreven (`requireMention`, `allowFrom`, `skills`, `systemPrompt`, `enabled`, `groupPolicy`).
`agentId` is topic-only en erft niet van groepsstandaarden.

**Per-topic-agentroutering**: Elk topic kan naar een andere agent routeren door `agentId` in de topicconfiguratie in te stellen. Dit geeft elk topic zijn eigen geïsoleerde werkruimte, geheugen en sessie. Voorbeeld:

```json5
{
  channels: {
    telegram: {
      groups: {
        "-1001234567890": {
          topics: {
            "1": { agentId: "main" },      // Algemeen topic → main agent
            "3": { agentId: "zu" },        // Dev topic → zu agent
            "5": { agentId: "coder" }      // Code review → coder agent
          }
        }
      }
    }
  }
}
```

Elk topic heeft dan zijn eigen sessiesleutel: `agent:zu:telegram:group:-1001234567890:topic:3`

**Persistent ACP-topicbinding**: Forum-topics kunnen ACP-harness-sessies vastpinnen via top-level getypte ACP-bindings:

- `bindings[]` met `type: "acp"` en `match.channel: "telegram"`

Voorbeeld:

```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,
            },
          },
        },
      },
    },
  },
}
```

Dit is momenteel beperkt tot forum-topics in groepen en supergroepen.

**Thread-gebonden ACP-spawn vanuit chat**:

- `/acp spawn <agent> --thread here|auto` kan het huidige Telegram-topic binden aan een nieuwe ACP-sessie.
- Vervolgberichten in het topic routeren direct naar de gebonden ACP-sessie (geen `/acp steer` vereist).
- OpenClaw pint het spawn-bevestigingsbericht in het topic na een succesvolle binding.
- Vereist `channels.telegram.threadBindings.spawnAcpSessions=true`.

Templatecontext bevat:

- `MessageThreadId`
- `IsForum`

DM-threadgedrag:

- privéchats met `message_thread_id` behouden DM-routering maar gebruiken thread-bewuste sessiesleutels/antwoorddoelen.
Audio, video en stickers
### Audioberichten

Telegram maakt onderscheid tussen voicenotities en audiobestanden.

- standaard: audiobestandgedrag
- tag `[[audio_as_voice]]` in agentantwoord om verzending als voicenotitie te forceren

Berichtactie-voorbeeld:
{
  action: "send",
  channel: "telegram",
  to: "123456789",
  media: "https://example.com/voice.ogg",
  asVoice: true,
}
### Videoberichten

Telegram maakt onderscheid tussen videobestanden en videonotities.

Berichtactie-voorbeeld:
{
  action: "send",
  channel: "telegram",
  to: "123456789",
  media: "https://example.com/video.mp4",
  asVideoNote: true,
}
Videonotities ondersteunen geen bijschriften; verstrekte berichttekst wordt apart verstuurd.

### Stickers

Inkomende stickerafhandeling:

- statische WEBP: gedownload en verwerkt (placeholder `<media:sticker>`)
- geanimeerde TGS: overgeslagen
- video WEBM: overgeslagen

Stickercontextvelden:

- `Sticker.emoji`
- `Sticker.setName`
- `Sticker.fileId`
- `Sticker.fileUniqueId`
- `Sticker.cachedDescription`

Sticker-cachebestand:

- `~/.openclaw/telegram/sticker-cache.json`

Stickers worden eenmalig beschreven (wanneer mogelijk) en gecachet om herhaalde vision-aanroepen te verminderen.

Stickeracties inschakelen:
{
  channels: {
    telegram: {
      actions: {
        sticker: true,
      },
    },
  },
}
Sticker-verzendactie:
{
  action: "sticker",
  channel: "telegram",
  to: "123456789",
  fileId: "CAACAgIAAxkBAAI...",
}
Gecachete stickers zoeken:
{
  action: "sticker-search",
  channel: "telegram",
  query: "cat waving",
  limit: 5,
}
Reactienotificaties
Telegram-reacties komen aan als `message_reaction`-updates (apart van berichtpayloads).

Wanneer ingeschakeld, plaatst OpenClaw systeemevents in de wachtrij zoals:

- `Telegram reaction added: 👍 by Alice (@alice) on msg 42`

Configuratie:

- `channels.telegram.reactionNotifications`: `off | own | all` (standaard: `own`)
- `channels.telegram.reactionLevel`: `off | ack | minimal | extensive` (standaard: `minimal`)

Opmerkingen:

- `own` betekent gebruikersreacties op alleen door de bot verzonden berichten (best-effort via verzonden-bericht-cache).
- Reactie-events respecteren nog steeds Telegram-toegangscontroles (`dmPolicy`, `allowFrom`, `groupPolicy`, `groupAllowFrom`); ongeautoriseerde afzenders worden verworpen.
- Telegram verstrekt geen thread-ID's in reactie-updates.
  - niet-forum-groepen routeren naar groepschatsessie
  - forum-groepen routeren naar de groeps-algemeen-topic-sessie (`:topic:1`), niet het exacte oorspronkelijke topic

`allowed_updates` voor polling/webhook bevatten automatisch `message_reaction`.
Bevestigingsreacties
`ackReaction` stuurt een bevestigingsemoji terwijl OpenClaw een inkomend bericht verwerkt.

Resolutievolgorde:

- `channels.telegram.accounts.<accountId>.ackReaction`
- `channels.telegram.ackReaction`
- `messages.ackReaction`
- agent-identiteitsemoji-terugval (`agents.list[].identity.emoji`, anders "👀")

Opmerkingen:

- Telegram verwacht unicode-emoji (bijvoorbeeld "👀").
- Gebruik `""` om de reactie voor een kanaal of account uit te schakelen.
Configschrijfacties vanuit Telegram-events en -commando's
Kanaalconfigschrijfacties zijn standaard ingeschakeld (`configWrites !== false`).

Telegram-getriggerde schrijfacties omvatten:

- groepsmigratieevents (`migrate_to_chat_id`) om `channels.telegram.groups` bij te werken
- `/config set` en `/config unset` (vereist commando-inschakeling)

Uitschakelen:
{
  channels: {
    telegram: {
      configWrites: false,
    },
  },
}
Long polling vs webhook
Standaard: long polling.

Webhookmodus:

- stel `channels.telegram.webhookUrl` in
- stel `channels.telegram.webhookSecret` in (vereist wanneer webhook-URL is ingesteld)
- optioneel `channels.telegram.webhookPath` (standaard `/telegram-webhook`)
- optioneel `channels.telegram.webhookHost` (standaard `127.0.0.1`)
- optioneel `channels.telegram.webhookPort` (standaard `8787`)

Standaard lokale luisteraar voor webhookmodus bindt aan `127.0.0.1:8787`.

Als je publieke eindpunt verschilt, plaats een reverse proxy ervoor en wijs `webhookUrl` naar de publieke URL.
Stel `webhookHost` in (bijvoorbeeld `0.0.0.0`) wanneer je bewust externe ingress nodig hebt.
Limieten, retry en CLI-doelen
- `channels.telegram.textChunkLimit` standaard is 4000.
- `channels.telegram.chunkMode="newline"` geeft voorkeur aan alineagrenzen (lege regels) voor lengteopsplitsing.
- `channels.telegram.mediaMaxMb` (standaard 100) beperkt inkomende en uitgaande Telegram-mediagrootte.
- `channels.telegram.timeoutSeconds` overschrijft Telegram API-clienttimeout (indien niet ingesteld, geldt grammY-standaard).
- groepscontextgeschiedenis gebruikt `channels.telegram.historyLimit` of `messages.groupChat.historyLimit` (standaard 50); `0` schakelt uit.
- DM-geschiedeniscontroles:
  - `channels.telegram.dmHistoryLimit`
  - `channels.telegram.dms["<user_id>"].historyLimit`
- `channels.telegram.retry`-configuratie geldt voor Telegram-verzendhelpers (CLI/tools/acties) voor herstelbare uitgaande API-fouten.

CLI-verzenddoel kan een numerieke chat-ID of gebruikersnaam zijn:
openclaw message send --channel telegram --target 123456789 --message "hi"
openclaw message send --channel telegram --target @name --message "hi"
Telegram-polls gebruiken `openclaw message poll` en ondersteunen 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-public
Telegram-specifieke poll-vlaggen:

- `--poll-duration-seconds` (5-600)
- `--poll-anonymous`
- `--poll-public`
- `--thread-id` voor forum-topics (of gebruik een `:topic:`-doel)

Actie-gating:

- `channels.telegram.actions.sendMessage=false` schakelt uitgaande Telegram-berichten uit, inclusief polls
- `channels.telegram.actions.poll=false` schakelt Telegram-pollaanmaak uit terwijl gewone verzendingen ingeschakeld blijven
Exec-goedkeuringen in Telegram
Telegram ondersteunt exec-goedkeuringen in goedkeurder-DM's en kan optioneel goedkeuringsprompts posten in de oorspronkelijke chat of het oorspronkelijke topic.

Configuratiepad:

- `channels.telegram.execApprovals.enabled`
- `channels.telegram.execApprovals.approvers`
- `channels.telegram.execApprovals.target` (`dm` | `channel` | `both`, standaard: `dm`)
- `agentFilter`, `sessionFilter`

Goedkeurders moeten numerieke Telegram-gebruikers-ID's zijn. Wanneer `enabled` false is of `approvers` leeg is, fungeert Telegram niet als exec-goedkeuringsclient. Goedkeuringsverzoeken vallen terug op andere geconfigureerde goedkeuringsroutes of het exec-goedkeuringsterugvalbeleid.

Afleveringsregels:

- `target: "dm"` stuurt goedkeuringsprompts alleen naar geconfigureerde goedkeurder-DM's
- `target: "channel"` stuurt de prompt terug naar de oorspronkelijke Telegram-chat/het oorspronkelijke topic
- `target: "both"` stuurt naar goedkeurder-DM's en de oorspronkelijke chat/het oorspronkelijke topic

Alleen geconfigureerde goedkeurders kunnen goedkeuren of weigeren. Niet-goedkeurders kunnen `/approve` niet gebruiken en kunnen geen Telegram-goedkeuringsknoppen gebruiken.

Kanaalaflevering toont de commandotekst in de chat, dus schakel `channel` of `both` alleen in in vertrouwde groepen/topics. Wanneer de prompt in een forum-topic belandt, bewaart OpenClaw het topic voor zowel de goedkeuringsprompt als de post-goedkeuring-opvolging.

Inline goedkeuringsknoppen zijn ook afhankelijk van `channels.telegram.capabilities.inlineButtons` die het doeloppervlak toestaat (`dm`, `group` of `all`).

Gerelateerde documentatie: [Exec-goedkeuringen](/docs/tools/exec-approvals)

Probleemoplossing

Bot reageert niet op niet-vermeldingsgroepsberichten
- Als `requireMention=false`, moet de Telegram-privacymodus volledige zichtbaarheid toestaan.
  - BotFather: `/setprivacy` -> Disable
  - verwijder dan de bot en voeg opnieuw toe aan de groep
- `openclaw channels status` waarschuwt wanneer de configuratie onvermelde groepsberichten verwacht.
- `openclaw channels status --probe` kan expliciete numerieke groeps-ID's controleren; wildcard `"*"` kan niet op lidmaatschap worden geprobed.
- snelle sessietest: `/activation always`.
Bot ziet helemaal geen groepsberichten
- wanneer `channels.telegram.groups` bestaat, moet de groep zijn vermeld (of `"*"` bevatten)
- verifieer botlidmaatschap in de groep
- bekijk logs: `openclaw logs --follow` voor overslaan-redenen
Commando's werken gedeeltelijk of helemaal niet
- autoriseer je afzenderidentiteit (koppeling en/of numerieke `allowFrom`)
- commando-autorisatie geldt nog steeds zelfs wanneer groepsbeleid `open` is
- `setMyCommands failed` met `BOT_COMMANDS_TOO_MUCH` betekent dat het native menu te veel vermeldingen heeft; verminder plugin-/skill-/aangepaste commando's of schakel native menu's uit
- `setMyCommands failed` met netwerk-/fetchfouten duidt meestal op DNS/HTTPS-bereikbaarheidsproblemen naar `api.telegram.org`
Polling of netwerkinstabiliteit
- Node 22+ + aangepaste fetch/proxy kan direct-afbreekgedrag triggeren als AbortSignal-typen niet overeenkomen.
- Sommige hosts resolven `api.telegram.org` eerst naar IPv6; kapotte IPv6-egress kan intermitterende Telegram API-fouten veroorzaken.
- Als logs `TypeError: fetch failed` of `Network request for 'getUpdates' failed!` bevatten, probeert OpenClaw deze nu opnieuw als herstelbare netwerkfouten.
- Op VPS-hosts met instabiele directe egress/TLS, routeer Telegram API-oproepen via `channels.telegram.proxy`:
channels:
  telegram:
    proxy: socks5://<user>:<password>@proxy-host:1080
- Node 22+ staat standaard op `autoSelectFamily=true` (behalve WSL2) en `dnsResultOrder=ipv4first`.
- Als je host WSL2 is of expliciet beter werkt met IPv4-only gedrag, forceer familieselectie:
channels:
  telegram:
    network:
      autoSelectFamily: false
- Omgevingsoverschrijvingen (tijdelijk):
  - `OPENCLAW_TELEGRAM_DISABLE_AUTO_SELECT_FAMILY=1`
  - `OPENCLAW_TELEGRAM_ENABLE_AUTO_SELECT_FAMILY=1`
  - `OPENCLAW_TELEGRAM_DNS_RESULT_ORDER=ipv4first`
- DNS-antwoorden valideren:
dig +short api.telegram.org A
dig +short api.telegram.org AAAA

Meer hulp: Kanaalprobleemoplossing.

Telegram-configuratiereferentie-verwijzingen

Primaire referentie:

  • channels.telegram.enabled: kanaalopstart in-/uitschakelen.

  • channels.telegram.botToken: bot-token (BotFather).

  • channels.telegram.tokenFile: token lezen vanuit een regulier bestandspad. Symlinks worden geweigerd.

  • channels.telegram.dmPolicy: pairing | allowlist | open | disabled (standaard: pairing).

  • channels.telegram.allowFrom: DM-allowlist (numerieke Telegram-gebruikers-ID’s). allowlist vereist minstens een afzender-ID. open vereist "*". openclaw doctor --fix kan verouderde @username-vermeldingen oplossen naar ID’s en kan allowlist-vermeldingen herstellen uit pairing-store-bestanden in allowlist-migratieflows.

  • channels.telegram.actions.poll: Telegram-pollaanmaak in-/uitschakelen (standaard: ingeschakeld; vereist nog steeds sendMessage).

  • channels.telegram.defaultTo: standaard Telegram-doel gebruikt door CLI --deliver wanneer geen expliciet --reply-to is opgegeven.

  • channels.telegram.groupPolicy: open | allowlist | disabled (standaard: allowlist).

  • channels.telegram.groupAllowFrom: groepsafzender-allowlist (numerieke Telegram-gebruikers-ID’s). openclaw doctor --fix kan verouderde @username-vermeldingen oplossen naar ID’s. Niet-numerieke vermeldingen worden genegeerd bij autorisatie. Groepsauth gebruikt geen DM-pairing-store-terugval (2026.2.25+).

  • Multi-account-voorrang:

    • Wanneer twee of meer account-ID’s zijn geconfigureerd, stel channels.telegram.defaultAccount in (of neem channels.telegram.accounts.default op) om standaardroutering expliciet te maken.
    • Als geen van beide is ingesteld, valt OpenClaw terug op de eerste genormaliseerde account-ID en openclaw doctor waarschuwt.
    • channels.telegram.accounts.default.allowFrom en channels.telegram.accounts.default.groupAllowFrom gelden alleen voor het default-account.
    • Benoemde accounts erven channels.telegram.allowFrom en channels.telegram.groupAllowFrom wanneer account-niveauwaarden niet zijn ingesteld.
    • Benoemde accounts erven niet channels.telegram.accounts.default.allowFrom / groupAllowFrom.
  • channels.telegram.groups: per-groep-standaarden + allowlist (gebruik "*" voor globale standaarden).

    • channels.telegram.groups.<id>.groupPolicy: per-groep-overschrijving voor groupPolicy (open | allowlist | disabled).
    • channels.telegram.groups.<id>.requireMention: mention-gating-standaard.
    • channels.telegram.groups.<id>.skills: skillfilter (weglaten = alle skills, leeg = geen).
    • channels.telegram.groups.<id>.allowFrom: per-groep-afzender-allowlist-overschrijving.
    • channels.telegram.groups.<id>.systemPrompt: extra systeemprompt voor de groep.
    • channels.telegram.groups.<id>.enabled: groep uitschakelen wanneer false.
    • channels.telegram.groups.<id>.topics.<threadId>.*: per-topic-overschrijvingen (groepsvelden + topic-only agentId).
    • channels.telegram.groups.<id>.topics.<threadId>.agentId: routeer dit topic naar een specifieke agent (overschrijft groepsniveau- en bindingroutering).
  • channels.telegram.groups.<id>.topics.<threadId>.groupPolicy: per-topic-overschrijving voor groupPolicy (open | allowlist | disabled).

  • channels.telegram.groups.<id>.topics.<threadId>.requireMention: per-topic mention-gating-overschrijving.

  • top-level bindings[] met type: "acp" en canonieke topic-ID chatId:topic:topicId in match.peer.id: persistent ACP-topicbindingvelden (zie ACP Agents).

  • channels.telegram.direct.<id>.topics.<threadId>.agentId: routeer DM-topics naar een specifieke agent (zelfde gedrag als forum-topics).

  • channels.telegram.execApprovals.enabled: schakel Telegram in als chatgebaseerde exec-goedkeuringsclient voor dit account.

  • channels.telegram.execApprovals.approvers: Telegram-gebruikers-ID’s die exec-verzoeken mogen goedkeuren of weigeren. Vereist wanneer exec-goedkeuringen zijn ingeschakeld.

  • channels.telegram.execApprovals.target: dm | channel | both (standaard: dm). channel en both bewaren het oorspronkelijke Telegram-topic wanneer aanwezig.

  • channels.telegram.execApprovals.agentFilter: optioneel agent-ID-filter voor doorgestuurde goedkeuringsprompts.

  • channels.telegram.execApprovals.sessionFilter: optioneel sessiesleutelfilter (substring of regex) voor doorgestuurde goedkeuringsprompts.

  • channels.telegram.accounts.<account>.execApprovals: per-account-overschrijving voor Telegram exec-goedkeuringsroutering en goedkeurdersautorisatie.

  • channels.telegram.capabilities.inlineButtons: off | dm | group | all | allowlist (standaard: allowlist).

  • channels.telegram.accounts.<account>.capabilities.inlineButtons: per-account-overschrijving.

  • channels.telegram.commands.nativeSkills: native skills-commando’s in-/uitschakelen voor Telegram.

  • channels.telegram.replyToMode: off | first | all (standaard: off).

  • channels.telegram.textChunkLimit: uitgaande chunkgrootte (tekens).

  • channels.telegram.chunkMode: length (standaard) of newline om te splitsen op lege regels (alineagrenzen) voor lengteopsplitsing.

  • channels.telegram.linkPreview: linkpreviews schakelen voor uitgaande berichten (standaard: true).

  • channels.telegram.streaming: off | partial | block | progress (live stream preview; standaard: partial; progress mapt naar partial; block is verouderde preview-moduscompatibiliteit). Telegram-preview-streaming gebruikt een enkel preview-bericht dat ter plaatse wordt bewerkt.

  • channels.telegram.mediaMaxMb: inkomende/uitgaande Telegram-medialimiet (MB, standaard: 100).

  • channels.telegram.retry: retry-beleid voor Telegram-verzendhelpers (CLI/tools/acties) bij herstelbare uitgaande API-fouten (attempts, minDelayMs, maxDelayMs, jitter).

  • channels.telegram.network.autoSelectFamily: overschrijf Node autoSelectFamily (true=inschakelen, false=uitschakelen). Standaard ingeschakeld op Node 22+, met WSL2 standaard uitgeschakeld.

  • channels.telegram.network.dnsResultOrder: overschrijf DNS-resultaatvolgorde (ipv4first of verbatim). Standaard ipv4first op Node 22+.

  • channels.telegram.proxy: proxy-URL voor Bot API-oproepen (SOCKS/HTTP).

  • channels.telegram.webhookUrl: webhookmodus inschakelen (vereist channels.telegram.webhookSecret).

  • channels.telegram.webhookSecret: webhooksecret (vereist wanneer webhookUrl is ingesteld).

  • channels.telegram.webhookPath: lokaal webhookpad (standaard /telegram-webhook).

  • channels.telegram.webhookHost: lokale webhook-bindhost (standaard 127.0.0.1).

  • channels.telegram.webhookPort: lokale webhook-bindpoort (standaard 8787).

  • channels.telegram.actions.reactions: Telegram-toolreacties gaten.

  • channels.telegram.actions.sendMessage: Telegram-toolberichtverzendingen gaten.

  • channels.telegram.actions.deleteMessage: Telegram-toolberichtverwijderingen gaten.

  • channels.telegram.actions.sticker: Telegram-stickeracties gaten — versturen en zoeken (standaard: false).

  • channels.telegram.reactionNotifications: off | own | all — bepaal welke reacties systeemevents triggeren (standaard: own wanneer niet ingesteld).

  • channels.telegram.reactionLevel: off | ack | minimal | extensive — bepaal de reactiemogelijkheid van de agent (standaard: minimal wanneer niet ingesteld).

  • Configuratiereferentie - Telegram

Telegram-specifieke belangrijke velden:

  • opstart/auth: enabled, botToken, tokenFile, accounts.* (tokenFile moet naar een regulier bestand wijzen; symlinks worden geweigerd)
  • toegangscontrole: dmPolicy, allowFrom, groupPolicy, groupAllowFrom, groups, groups.*.topics.*, top-level bindings[] (type: "acp")
  • exec-goedkeuringen: execApprovals, accounts.*.execApprovals
  • commando/menu: commands.native, commands.nativeSkills, customCommands
  • threading/antwoorden: replyToMode
  • streaming: streaming (preview), blockStreaming
  • opmaak/aflevering: textChunkLimit, chunkMode, linkPreview, responsePrefix
  • media/netwerk: mediaMaxMb, timeoutSeconds, retry, network.autoSelectFamily, proxy
  • webhook: webhookUrl, webhookSecret, webhookPath, webhookHost
  • acties/mogelijkheden: capabilities.inlineButtons, actions.sendMessage|editMessage|deleteMessage|reactions|sticker
  • reacties: reactionNotifications, reactionLevel
  • schrijfacties/geschiedenis: configWrites, historyLimit, dmHistoryLimit, dms.*.historyLimit

Gerelateerd