Telegram (Bot API)

Status: pronto para produção em DMs + grupos de bot via grammY. Long polling é o modo padrão; modo webhook é opcional.

Configuração rápida

Passo 1: Crie o token do bot no BotFather

Abra o Telegram e converse com **@BotFather** (confirme que o handle é exatamente `@BotFather`).

Execute `/newbot`, siga os prompts e salve o token.

Passo 2: Configure o token e a política de DM

{
  channels: {
    telegram: {
      enabled: true,
      botToken: "123:abc",
      dmPolicy: "pairing",
      groups: { "*": { requireMention: true } },
    },
  },
}
Fallback por env: `TELEGRAM_BOT_TOKEN=...` (apenas conta padrão).
O Telegram **não** usa `openclaw channels login telegram`; configure o token na config/env e depois inicie o gateway.

Passo 3: Inicie o gateway e aprove a primeira DM

openclaw gateway
openclaw pairing list telegram
openclaw pairing approve telegram <CODE>
Códigos de pareamento expiram após 1 hora.

Passo 4: Adicione o bot a um grupo

Adicione o bot ao grupo, depois defina `channels.telegram.groups` e `groupPolicy` para corresponder ao seu modelo de acesso.

Nota: A ordem de resolução do token reconhece contas. Na prática, valores da config têm prioridade sobre o fallback por env, e TELEGRAM_BOT_TOKEN se aplica apenas à conta padrão.

Configurações do lado do Telegram

Modo de privacidade e visibilidade em grupos
Bots do Telegram usam **Modo de Privacidade** por padrão, o que limita quais mensagens de grupo eles recebem.

Se o bot precisar ver todas as mensagens do grupo, faça uma das opções:

- desative o modo de privacidade via `/setprivacy`, ou
- torne o bot um administrador do grupo.

Ao alterar o modo de privacidade, remova + re-adicione o bot em cada grupo para que o Telegram aplique a mudança.
Permissões de grupo
O status de administrador é controlado nas configurações do grupo do Telegram.

Bots administradores recebem todas as mensagens do grupo, o que é útil para comportamento always-on.
Toggles úteis do BotFather
- `/setjoingroups` para permitir/negar adição a grupos
- `/setprivacy` para comportamento de visibilidade em grupos

Controle de acesso e ativação

Política de DM

`channels.telegram.dmPolicy` controla o acesso a mensagens diretas:

- `pairing` (padrão)
- `allowlist` (requer pelo menos um ID de remetente em `allowFrom`)
- `open` (requer que `allowFrom` inclua `"*"`)
- `disabled`

`channels.telegram.allowFrom` aceita IDs numéricos de usuário do Telegram. Prefixos `telegram:` / `tg:` são aceitos e normalizados.
`dmPolicy: "allowlist"` com `allowFrom` vazio bloqueia todas as DMs e é rejeitado pela validação de config.
O assistente de onboarding aceita entrada `@username` e resolve para IDs numéricos.
Se você atualizou e sua config contém entradas `@username` na lista de permitidos, execute `openclaw doctor --fix` para resolvê-las (best-effort; requer um token de bot do Telegram).
Se você dependia anteriormente de arquivos de lista de permitidos do pairing-store, `openclaw doctor --fix` pode recuperar entradas em `channels.telegram.allowFrom` em fluxos de lista de permitidos (por exemplo quando `dmPolicy: "allowlist"` não tem IDs explícitos ainda).

Para bots de um único proprietário, prefira `dmPolicy: "allowlist"` com IDs numéricos explícitos em `allowFrom` para manter a política de acesso durável na config (em vez de depender de aprovações de pareamento anteriores).

### Encontrando seu ID de usuário do Telegram

Mais seguro (sem bot de terceiros):

1. Envie uma DM para o bot.
2. Execute `openclaw logs --follow`.
3. Leia `from.id`.

Método oficial da Bot API:
curl "https://api.telegram.org/bot<bot_token>/getUpdates"
Método de terceiros (menos privado): `@userinfobot` ou `@getidsbot`.

Política de grupo e listas de permitidos

Dois controles se aplicam juntos:

1. **Quais grupos são permitidos** (`channels.telegram.groups`)
   - sem config `groups`:
     - com `groupPolicy: "open"`: qualquer grupo pode passar verificações de ID de grupo
     - com `groupPolicy: "allowlist"` (padrão): grupos são bloqueados até você adicionar entradas em `groups` (ou `"*"`)
   - `groups` configurado: funciona como lista de permitidos (IDs explícitos ou `"*"`)

2. **Quais remetentes são permitidos nos grupos** (`channels.telegram.groupPolicy`)
   - `open`
   - `allowlist` (padrão)
   - `disabled`

`groupAllowFrom` é usado para filtragem de remetentes em grupos. Se não definido, o Telegram recorre a `allowFrom`.
Entradas de `groupAllowFrom` devem ser IDs numéricos de usuário do Telegram (prefixos `telegram:` / `tg:` são normalizados).
Não coloque IDs de chat de grupo ou supergrupo do Telegram em `groupAllowFrom`. IDs negativos de chat pertencem a `channels.telegram.groups`.
Entradas não numéricas são ignoradas para autorização de remetente.
Limite de segurança (`2026.2.25+`): a autenticação de remetente de grupo **não** herda aprovações do DM pairing-store.
O pareamento permanece apenas para DMs. Para grupos, defina `groupAllowFrom` ou `allowFrom` por grupo/tópico.
Observação de runtime: se `channels.telegram` estiver completamente ausente, o runtime tem como padrão `groupPolicy="allowlist"` fail-closed, a menos que `channels.defaults.groupPolicy` esteja explicitamente definido.

Exemplo: permitir qualquer membro em um grupo específico:
{
  channels: {
    telegram: {
      groups: {
        "-1001234567890": {
          groupPolicy: "open",
          requireMention: false,
        },
      },
    },
  },
}
Exemplo: permitir apenas usuários específicos dentro de um grupo:
{
  channels: {
    telegram: {
      groups: {
        "-1001234567890": {
          requireMention: true,
          allowFrom: ["8734062810", "745123456"],
        },
      },
    },
  },
}
> **Aviso:**

Erro comum: groupAllowFrom não é uma lista de permitidos de grupos do Telegram.

  - Coloque IDs negativos de chat de grupo ou supergrupo do Telegram como `-1001234567890` em `channels.telegram.groups`.
  - Coloque IDs de usuário do Telegram como `8734062810` em `groupAllowFrom` quando quiser limitar quais pessoas dentro de um grupo permitido podem acionar o bot.
  - Use `groupAllowFrom: ["*"]` apenas quando quiser que qualquer membro de um grupo permitido possa conversar com o bot.

Comportamento de menção

Respostas em grupo exigem menção por padrão.

A menção pode vir de:

- menção nativa `@botusername`, ou
- padrões de menção em:
  - `agents.list[].groupChat.mentionPatterns`
  - `messages.groupChat.mentionPatterns`

Toggles de comando por sessão:

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

Estes atualizam apenas o estado da sessão. Use config para persistência.

Exemplo de config persistente:
{
  channels: {
    telegram: {
      groups: {
        "*": { requireMention: false },
      },
    },
  },
}
Obtendo o ID do chat do grupo:

- encaminhe uma mensagem do grupo para `@userinfobot` / `@getidsbot`
- ou leia `chat.id` de `openclaw logs --follow`
- ou inspecione `getUpdates` da Bot API

Comportamento de runtime

  • O Telegram é gerenciado pelo processo do gateway.
  • O roteamento é determinístico: mensagens recebidas pelo Telegram respondem pelo Telegram (o modelo não escolhe canais).
  • Mensagens de entrada são normalizadas no envelope de canal compartilhado com metadados de resposta e placeholders de mídia.
  • Sessões de grupo são isoladas por ID de grupo. Tópicos de fórum adicionam :topic:<threadId> para manter tópicos isolados.
  • Mensagens de DM podem carregar message_thread_id; o OpenClaw as roteia com chaves de sessão thread-aware e preserva o ID da thread para respostas.
  • Long polling usa o runner grammY com sequenciamento por chat/thread. A concorrência geral do sink do runner usa agents.defaults.maxConcurrent.
  • A Telegram Bot API não tem suporte a confirmações de leitura (sendReadReceipts não se aplica).

Referência de recursos

Preview de streaming ao vivo (edições de mensagem)
O OpenClaw pode transmitir respostas parciais em tempo real:

- chats diretos: mensagem de preview + `editMessageText`
- grupos/tópicos: mensagem de preview + `editMessageText`

Requisito:

- `channels.telegram.streaming` é `off | partial | block | progress` (padrão: `partial`)
- `progress` mapeia para `partial` no Telegram (compatibilidade com nomeação entre canais)
- `channels.telegram.streamMode` legado e valores booleanos de `streaming` são mapeados automaticamente

Para respostas apenas texto:

- DM: o OpenClaw mantém a mesma mensagem de preview e faz uma edição final no local (sem segunda mensagem)
- grupo/tópico: o OpenClaw mantém a mesma mensagem de preview e faz uma edição final no local (sem segunda mensagem)

Para respostas complexas (por exemplo payloads de mídia), o OpenClaw recorre à entrega final normal e depois limpa a mensagem de preview.

O streaming de preview é separado do block streaming. Quando o block streaming é explicitamente ativado para o Telegram, o OpenClaw pula o preview stream para evitar streaming duplicado.

Se o transporte nativo de rascunho não estiver disponível/for rejeitado, o OpenClaw recorre automaticamente a `sendMessage` + `editMessageText`.

Stream de raciocínio exclusivo do Telegram:

- `/reasoning stream` envia o raciocínio para o preview ao vivo enquanto gera
- a resposta final é enviada sem o texto de raciocínio
Formatação e fallback HTML
O texto de saída usa `parse_mode: "HTML"` do Telegram.

- Texto estilo Markdown é renderizado em HTML seguro para o Telegram.
- HTML bruto do modelo é escapado para reduzir falhas de parse do Telegram.
- Se o Telegram rejeitar o HTML parseado, o OpenClaw tenta novamente como texto puro.

Previews de links são ativados por padrão e podem ser desativados com `channels.telegram.linkPreview: false`.
Comandos nativos e comandos customizados
O registro do menu de comandos do Telegram é feito na inicialização com `setMyCommands`.

Padrões de comandos nativos:

- `commands.native: "auto"` ativa comandos nativos para o Telegram

Adicione entradas customizadas ao menu de comandos:
{
  channels: {
    telegram: {
      customCommands: [
        { command: "backup", description: "Git backup" },
        { command: "generate", description: "Create an image" },
      ],
    },
  },
}
Regras:

- nomes são normalizados (remove `/` inicial, minúsculas)
- padrão válido: `a-z`, `0-9`, `_`, comprimento `1..32`
- comandos customizados não podem sobrescrever comandos nativos
- conflitos/duplicatas são pulados e registrados

Observações:

- comandos customizados são apenas entradas de menu; não implementam comportamento automaticamente
- comandos de plugin/skill ainda podem funcionar quando digitados mesmo que não apareçam no menu do Telegram

Se comandos nativos estiverem desativados, os integrados são removidos. Comandos customizados/de plugin ainda podem ser registrados se configurados.

Falhas comuns de configuração:

- `setMyCommands failed` com `BOT_COMMANDS_TOO_MUCH` significa que o menu do Telegram ainda estourou após o trim; reduza comandos de plugin/skill/customizados ou desative `channels.telegram.commands.native`.
- `setMyCommands failed` com erros de rede/fetch geralmente significa que DNS/HTTPS de saída para `api.telegram.org` está bloqueado.

### Comandos de pareamento de dispositivo (plugin `device-pair`)

Quando o plugin `device-pair` está instalado:

1. `/pair` gera o código de configuração
2. cole o código no app iOS
3. `/pair approve` aprova a solicitação pendente mais recente

Mais detalhes: [Pareamento](/docs/channels/pairing#pair-via-telegram-recommended-for-ios).
Botões inline
Configure o escopo do teclado inline:
{
  channels: {
    telegram: {
      capabilities: {
        inlineButtons: "allowlist",
      },
    },
  },
}
Override por conta:
{
  channels: {
    telegram: {
      accounts: {
        main: {
          capabilities: {
            inlineButtons: "allowlist",
          },
        },
      },
    },
  },
}
Escopos:

- `off`
- `dm`
- `group`
- `all`
- `allowlist` (padrão)

`capabilities: ["inlineButtons"]` legado mapeia para `inlineButtons: "all"`.

Exemplo de ação de mensagem:
{
  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" }],
  ],
}
Cliques de callback são passados ao agente como texto:
`callback_data: <value>`
Ações de mensagem do Telegram para agentes e automação
As ações de ferramenta do Telegram incluem:

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

As ações de mensagem do canal expõem aliases ergonômicos (`send`, `react`, `delete`, `edit`, `sticker`, `sticker-search`, `topic-create`).

Controles de gate:

- `channels.telegram.actions.sendMessage`
- `channels.telegram.actions.deleteMessage`
- `channels.telegram.actions.reactions`
- `channels.telegram.actions.sticker` (padrão: desativado)

Observação: `edit` e `topic-create` estão ativados por padrão e não têm toggles separados em `channels.telegram.actions.*`.
Envios em runtime usam o snapshot ativo de config/secrets (inicialização/reload), então os caminhos de ação não fazem re-resolução ad-hoc de SecretRef por envio.

Semântica de remoção de reação: [/tools/reactions](/docs/tools/reactions)
Tags de threading de resposta
O Telegram suporta tags explícitas de threading de resposta na saída gerada:

- `[[reply_to_current]]` responde à mensagem de acionamento
- `[[reply_to:<id>]]` responde a um ID de mensagem específico do Telegram

`channels.telegram.replyToMode` controla o tratamento:

- `off` (padrão)
- `first`
- `all`

Observação: `off` desativa o threading implícito de resposta. Tags explícitas `[[reply_to_*]]` continuam sendo respeitadas.
Tópicos de fórum e comportamento de threads
Supergrupos de fórum:

- chaves de sessão de tópico adicionam `:topic:<threadId>`
- respostas e indicação de digitação visam a thread do tópico
- caminho de config de tópico:
  `channels.telegram.groups.<chatId>.topics.<threadId>`

Caso especial do tópico geral (`threadId=1`):

- envios de mensagem omitem `message_thread_id` (o Telegram rejeita `sendMessage(...thread_id=1)`)
- ações de digitação ainda incluem `message_thread_id`

Herança de tópico: entradas de tópico herdam configurações do grupo a menos que sobrescritas (`requireMention`, `allowFrom`, `skills`, `systemPrompt`, `enabled`, `groupPolicy`).
`agentId` é exclusivo do tópico e não herda dos padrões do grupo.

**Roteamento de agente por tópico**: Cada tópico pode ser roteado para um agente diferente definindo `agentId` na config do tópico. Isso dá a cada tópico seu próprio workspace, memória e sessão isolados. Exemplo:

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

Cada tópico então tem sua própria chave de sessão: `agent:zu:telegram:group:-1001234567890:topic:3`

**Vinculação ACP persistente de tópico**: Tópicos de fórum podem fixar sessões de harness ACP através de vinculações ACP tipadas de nível raiz:

- `bindings[]` com `type: "acp"` e `match.channel: "telegram"`

Exemplo:

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

Isso está atualmente limitado a tópicos de fórum em grupos e supergrupos.

**Spawn de ACP vinculado a thread a partir do chat**:

- `/acp spawn <agent> --thread here|auto` pode vincular o tópico atual do Telegram a uma nova sessão ACP.
- Mensagens de acompanhamento no tópico são roteadas diretamente para a sessão ACP vinculada (sem necessidade de `/acp steer`).
- O OpenClaw fixa a mensagem de confirmação do spawn no tópico após uma vinculação bem-sucedida.
- Requer `channels.telegram.threadBindings.spawnAcpSessions=true`.

O contexto de template inclui:

- `MessageThreadId`
- `IsForum`

Comportamento de thread em DM:

- chats privados com `message_thread_id` mantêm roteamento de DM mas usam chaves de sessão/alvos de resposta thread-aware.
Áudio, vídeo e stickers
### Mensagens de áudio

O Telegram distingue notas de voz de arquivos de áudio.

- padrão: comportamento de arquivo de áudio
- tag `[[audio_as_voice]]` na resposta do agente para forçar envio como nota de voz

Exemplo de ação de mensagem:
{
  action: "send",
  channel: "telegram",
  to: "123456789",
  media: "https://example.com/voice.ogg",
  asVoice: true,
}
### Mensagens de vídeo

O Telegram distingue arquivos de vídeo de notas de vídeo.

Exemplo de ação de mensagem:
{
  action: "send",
  channel: "telegram",
  to: "123456789",
  media: "https://example.com/video.mp4",
  asVideoNote: true,
}
Notas de vídeo não suportam legendas; texto de mensagem fornecido é enviado separadamente.

### Stickers

Tratamento de stickers de entrada:

- WEBP estático: baixado e processado (placeholder `<media:sticker>`)
- TGS animado: pulado
- WEBM vídeo: pulado

Campos de contexto de sticker:

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

Arquivo de cache de stickers:

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

Stickers são descritos uma vez (quando possível) e armazenados em cache para reduzir chamadas de visão repetidas.

Ative ações de sticker:
{
  channels: {
    telegram: {
      actions: {
        sticker: true,
      },
    },
  },
}
Ação de enviar sticker:
{
  action: "sticker",
  channel: "telegram",
  to: "123456789",
  fileId: "CAACAgIAAxkBAAI...",
}
Buscar stickers em cache:
{
  action: "sticker-search",
  channel: "telegram",
  query: "cat waving",
  limit: 5,
}
Notificações de reação
Reações do Telegram chegam como atualizações `message_reaction` (separadas dos payloads de mensagem).

Quando ativado, o OpenClaw enfileira eventos de sistema como:

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

Config:

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

Observações:

- `own` significa apenas reações de usuários a mensagens enviadas pelo bot (best-effort via cache de mensagens enviadas).
- Eventos de reação ainda respeitam os controles de acesso do Telegram (`dmPolicy`, `allowFrom`, `groupPolicy`, `groupAllowFrom`); remetentes não autorizados são descartados.
- O Telegram não fornece IDs de thread em atualizações de reação.
  - grupos sem fórum roteiam para a sessão de chat do grupo
  - grupos com fórum roteiam para a sessão de tópico geral do grupo (`:topic:1`), não o tópico exato de origem

`allowed_updates` para polling/webhook incluem `message_reaction` automaticamente.
Reações de confirmação
`ackReaction` envia um emoji de confirmação enquanto o OpenClaw processa uma mensagem de entrada.

Ordem de resolução:

- `channels.telegram.accounts.<accountId>.ackReaction`
- `channels.telegram.ackReaction`
- `messages.ackReaction`
- fallback do emoji de identidade do agente (`agents.list[].identity.emoji`, senão "👀")

Observações:

- O Telegram espera emoji unicode (por exemplo "👀").
- Use `""` para desativar a reação para um canal ou conta.
Escritas de configuração a partir de eventos e comandos do Telegram
Escritas de config do canal estão ativadas por padrão (`configWrites !== false`).

Escritas acionadas pelo Telegram incluem:

- eventos de migração de grupo (`migrate_to_chat_id`) para atualizar `channels.telegram.groups`
- `/config set` e `/config unset` (requer ativação de comando)

Desativar:
{
  channels: {
    telegram: {
      configWrites: false,
    },
  },
}
Long polling vs webhook
Padrão: long polling.

Modo webhook:

- defina `channels.telegram.webhookUrl`
- defina `channels.telegram.webhookSecret` (obrigatório quando a URL de webhook está definida)
- opcional `channels.telegram.webhookPath` (padrão `/telegram-webhook`)
- opcional `channels.telegram.webhookHost` (padrão `127.0.0.1`)
- opcional `channels.telegram.webhookPort` (padrão `8787`)

O listener local padrão para modo webhook escuta em `127.0.0.1:8787`.

Se seu endpoint público for diferente, coloque um proxy reverso na frente e aponte `webhookUrl` para a URL pública.
Defina `webhookHost` (por exemplo `0.0.0.0`) quando intencionalmente precisar de ingress externo.
Limites, retry e alvos CLI
- `channels.telegram.textChunkLimit` padrão é 4000.
- `channels.telegram.chunkMode="newline"` prefere limites de parágrafo (linhas em branco) antes de divisão por tamanho.
- `channels.telegram.mediaMaxMb` (padrão 100) limita tamanho de mídia de entrada e saída do Telegram.
- `channels.telegram.timeoutSeconds` sobrescreve o timeout do cliente da API Telegram (se não definido, o padrão do grammY se aplica).
- contexto de histórico de grupo usa `channels.telegram.historyLimit` ou `messages.groupChat.historyLimit` (padrão 50); `0` desativa.
- Controles de histórico de DM:
  - `channels.telegram.dmHistoryLimit`
  - `channels.telegram.dms["<user_id>"].historyLimit`
- a config `channels.telegram.retry` se aplica aos helpers de envio do Telegram (CLI/tools/actions) para erros de API de saída recuperáveis.

O alvo de envio CLI pode ser ID de chat numérico ou username:
openclaw message send --channel telegram --target 123456789 --message "hi"
openclaw message send --channel telegram --target @name --message "hi"
Enquetes do Telegram usam `openclaw message poll` e suportam tópicos de fórum:
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
Flags de enquete exclusivas do Telegram:

- `--poll-duration-seconds` (5-600)
- `--poll-anonymous`
- `--poll-public`
- `--thread-id` para tópicos de fórum (ou use um alvo `:topic:`)

Gate de ação:

- `channels.telegram.actions.sendMessage=false` desativa mensagens de saída do Telegram, incluindo enquetes
- `channels.telegram.actions.poll=false` desativa a criação de enquetes do Telegram enquanto mantém envios regulares ativados
Aprovações de exec no Telegram
O Telegram suporta aprovações de exec nas DMs dos aprovadores e pode opcionalmente postar prompts de aprovação no chat ou tópico de origem.

Caminho de config:

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

Os aprovadores devem ser IDs numéricos de usuário do Telegram. Quando `enabled` é false ou `approvers` está vazio, o Telegram não atua como cliente de aprovação de exec. As solicitações de aprovação recorrem a outras rotas de aprovação configuradas ou à política de fallback de aprovação de exec.

Regras de entrega:

- `target: "dm"` envia prompts de aprovação apenas para DMs de aprovadores configurados
- `target: "channel"` envia o prompt de volta ao chat/tópico do Telegram de origem
- `target: "both"` envia para DMs de aprovadores e para o chat/tópico de origem

Apenas aprovadores configurados podem aprovar ou negar. Não aprovadores não podem usar `/approve` e não podem usar botões de aprovação do Telegram.

Entrega no canal mostra o texto do comando no chat, então só ative `channel` ou `both` em grupos/tópicos confiáveis. Quando o prompt chega em um tópico de fórum, o OpenClaw preserva o tópico tanto para o prompt de aprovação quanto para o follow-up pós-aprovação.

Botões de aprovação inline também dependem de `channels.telegram.capabilities.inlineButtons` permitindo a superfície alvo (`dm`, `group` ou `all`).

Documentação relacionada: [Aprovações de exec](/docs/tools/exec-approvals)

Solução de problemas

Bot não responde a mensagens de grupo sem menção
- Se `requireMention=false`, o modo de privacidade do Telegram deve permitir visibilidade total.
  - BotFather: `/setprivacy` -> Disable
  - depois remova + re-adicione o bot ao grupo
- `openclaw channels status` avisa quando a config espera mensagens de grupo sem menção.
- `openclaw channels status --probe` pode verificar IDs numéricos de grupo explícitos; wildcard `"*"` não pode ser verificado por membership.
- teste rápido de sessão: `/activation always`.
Bot não vê mensagens de grupo de forma alguma
- quando `channels.telegram.groups` existe, o grupo deve estar listado (ou incluir `"*"`)
- verifique a associação do bot ao grupo
- revise os logs: `openclaw logs --follow` para razões de skip
Comandos funcionam parcialmente ou não funcionam
- autorize sua identidade de remetente (pareamento e/ou `allowFrom` numérico)
- a autorização de comando ainda se aplica mesmo quando a política de grupo é `open`
- `setMyCommands failed` com `BOT_COMMANDS_TOO_MUCH` significa que o menu nativo tem muitas entradas; reduza comandos de plugin/skill/customizados ou desative menus nativos
- `setMyCommands failed` com erros de rede/fetch geralmente indica problemas de acessibilidade DNS/HTTPS para `api.telegram.org`
Instabilidade de polling ou rede
- Node 22+ + fetch/proxy customizados podem acionar comportamento de abort imediato se tipos de AbortSignal não corresponderem.
- Alguns hosts resolvem `api.telegram.org` para IPv6 primeiro; egress IPv6 quebrado pode causar falhas intermitentes na API do Telegram.
- Se os logs incluem `TypeError: fetch failed` ou `Network request for 'getUpdates' failed!`, o OpenClaw agora tenta novamente como erros de rede recuperáveis.
- Em hosts VPS com egress/TLS direto instável, roteie chamadas da API do Telegram através de `channels.telegram.proxy`:
channels:
  telegram:
    proxy: socks5://<user>:<password>@proxy-host:1080
- Node 22+ tem como padrão `autoSelectFamily=true` (exceto WSL2) e `dnsResultOrder=ipv4first`.
- Se seu host é WSL2 ou funciona explicitamente melhor com comportamento apenas IPv4, force a seleção de família:
channels:
  telegram:
    network:
      autoSelectFamily: false
- Overrides de ambiente (temporários):
  - `OPENCLAW_TELEGRAM_DISABLE_AUTO_SELECT_FAMILY=1`
  - `OPENCLAW_TELEGRAM_ENABLE_AUTO_SELECT_FAMILY=1`
  - `OPENCLAW_TELEGRAM_DNS_RESULT_ORDER=ipv4first`
- Valide respostas DNS:
dig +short api.telegram.org A
dig +short api.telegram.org AAAA

Mais ajuda: Solução de problemas de canais.

Referência de configuração do Telegram

Referência principal:

  • channels.telegram.enabled: ativar/desativar inicialização do canal.

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

  • channels.telegram.tokenFile: ler token de um caminho de arquivo regular. Symlinks são rejeitados.

  • channels.telegram.dmPolicy: pairing | allowlist | open | disabled (padrão: pairing).

  • channels.telegram.allowFrom: lista de permitidos de DM (IDs numéricos de usuário do Telegram). allowlist requer pelo menos um ID de remetente. open requer "*". openclaw doctor --fix pode resolver entradas legadas @username para IDs e pode recuperar entradas de lista de permitidos de arquivos pairing-store em fluxos de migração de lista de permitidos.

  • channels.telegram.actions.poll: ativar ou desativar criação de enquete do Telegram (padrão: ativado; ainda requer sendMessage).

  • channels.telegram.defaultTo: alvo padrão do Telegram usado pelo CLI --deliver quando nenhum --reply-to explícito é fornecido.

  • channels.telegram.groupPolicy: open | allowlist | disabled (padrão: allowlist).

  • channels.telegram.groupAllowFrom: lista de permitidos de remetentes de grupo (IDs numéricos de usuário do Telegram). openclaw doctor --fix pode resolver entradas legadas @username para IDs. Entradas não numéricas são ignoradas no momento da autenticação. Autenticação de grupo não usa fallback do DM pairing-store (2026.2.25+).

  • Precedência multiconta:

    • Quando dois ou mais IDs de conta estão configurados, defina channels.telegram.defaultAccount (ou inclua channels.telegram.accounts.default) para tornar o roteamento padrão explícito.
    • Se nenhum dos dois estiver definido, o OpenClaw recorre ao primeiro ID de conta normalizado e openclaw doctor avisa.
    • channels.telegram.accounts.default.allowFrom e channels.telegram.accounts.default.groupAllowFrom se aplicam apenas à conta default.
    • Contas nomeadas herdam channels.telegram.allowFrom e channels.telegram.groupAllowFrom quando valores a nível de conta não estão definidos.
    • Contas nomeadas não herdam channels.telegram.accounts.default.allowFrom / groupAllowFrom.
  • channels.telegram.groups: padrões por grupo + lista de permitidos (use "*" para padrões globais).

    • channels.telegram.groups.<id>.groupPolicy: override por grupo para groupPolicy (open | allowlist | disabled).
    • channels.telegram.groups.<id>.requireMention: padrão de filtragem por menção.
    • channels.telegram.groups.<id>.skills: filtro de skills (omitir = todas, vazio = nenhuma).
    • channels.telegram.groups.<id>.allowFrom: override de lista de permitidos de remetentes por grupo.
    • channels.telegram.groups.<id>.systemPrompt: prompt de sistema extra para o grupo.
    • channels.telegram.groups.<id>.enabled: desativa o grupo quando false.
    • channels.telegram.groups.<id>.topics.<threadId>.*: overrides por tópico (campos de grupo + agentId exclusivo do tópico).
    • channels.telegram.groups.<id>.topics.<threadId>.agentId: roteia este tópico para um agente específico (sobrescreve roteamento a nível de grupo e de binding).
  • channels.telegram.groups.<id>.topics.<threadId>.groupPolicy: override por tópico para groupPolicy (open | allowlist | disabled).

  • channels.telegram.groups.<id>.topics.<threadId>.requireMention: override de filtragem por menção por tópico.

  • bindings[] de nível raiz com type: "acp" e ID canônico de tópico chatId:topic:topicId em match.peer.id: campos de vinculação ACP persistente de tópico (veja Agentes ACP).

  • channels.telegram.direct.<id>.topics.<threadId>.agentId: roteia tópicos de DM para um agente específico (mesmo comportamento que tópicos de fórum).

  • channels.telegram.execApprovals.enabled: ativa o Telegram como cliente de aprovação de exec baseado em chat para esta conta.

  • channels.telegram.execApprovals.approvers: IDs de usuário do Telegram autorizados a aprovar ou negar solicitações de exec. Obrigatório quando aprovações de exec estão ativadas.

  • channels.telegram.execApprovals.target: dm | channel | both (padrão: dm). channel e both preservam o tópico do Telegram de origem quando presente.

  • channels.telegram.execApprovals.agentFilter: filtro opcional de ID de agente para prompts de aprovação encaminhados.

  • channels.telegram.execApprovals.sessionFilter: filtro opcional de chave de sessão (substring ou regex) para prompts de aprovação encaminhados.

  • channels.telegram.accounts.<account>.execApprovals: override por conta para roteamento de aprovação de exec do Telegram e autorização de aprovadores.

  • channels.telegram.capabilities.inlineButtons: off | dm | group | all | allowlist (padrão: allowlist).

  • channels.telegram.accounts.<account>.capabilities.inlineButtons: override por conta.

  • channels.telegram.commands.nativeSkills: ativar/desativar comandos nativos de skills do Telegram.

  • channels.telegram.replyToMode: off | first | all (padrão: off).

  • channels.telegram.textChunkLimit: tamanho do chunk de saída (caracteres).

  • channels.telegram.chunkMode: length (padrão) ou newline para dividir em linhas em branco (limites de parágrafo) antes de fragmentação por tamanho.

  • channels.telegram.linkPreview: toggle de previews de link para mensagens de saída (padrão: true).

  • channels.telegram.streaming: off | partial | block | progress (preview de streaming ao vivo; padrão: partial; progress mapeia para partial; block é compatibilidade de modo preview legado). O preview streaming do Telegram usa uma única mensagem de preview que é editada no local.

  • channels.telegram.mediaMaxMb: limite de mídia de entrada/saída do Telegram (MB, padrão: 100).

  • channels.telegram.retry: política de retry para helpers de envio do Telegram (CLI/tools/actions) em erros de API de saída recuperáveis (attempts, minDelayMs, maxDelayMs, jitter).

  • channels.telegram.network.autoSelectFamily: override de autoSelectFamily do Node (true=ativar, false=desativar). Padrão ativado em Node 22+, com WSL2 padrão desativado.

  • channels.telegram.network.dnsResultOrder: override de ordem de resultado DNS (ipv4first ou verbatim). Padrão ipv4first em Node 22+.

  • channels.telegram.proxy: URL de proxy para chamadas da Bot API (SOCKS/HTTP).

  • channels.telegram.webhookUrl: ativar modo webhook (requer channels.telegram.webhookSecret).

  • channels.telegram.webhookSecret: segredo do webhook (obrigatório quando webhookUrl está definido).

  • channels.telegram.webhookPath: caminho local do webhook (padrão /telegram-webhook).

  • channels.telegram.webhookHost: host de bind local do webhook (padrão 127.0.0.1).

  • channels.telegram.webhookPort: porta de bind local do webhook (padrão 8787).

  • channels.telegram.actions.reactions: gate de reações da ferramenta Telegram.

  • channels.telegram.actions.sendMessage: gate de envio de mensagens da ferramenta Telegram.

  • channels.telegram.actions.deleteMessage: gate de exclusão de mensagens da ferramenta Telegram.

  • channels.telegram.actions.sticker: gate de ações de sticker do Telegram — enviar e buscar (padrão: false).

  • channels.telegram.reactionNotifications: off | own | all — controla quais reações acionam eventos de sistema (padrão: own quando não definido).

  • channels.telegram.reactionLevel: off | ack | minimal | extensive — controla a capacidade de reação do agente (padrão: minimal quando não definido).

  • Referência de configuração - Telegram

Campos de alto impacto específicos do Telegram:

  • inicialização/autenticação: enabled, botToken, tokenFile, accounts.* (tokenFile deve apontar para um arquivo regular; symlinks são rejeitados)
  • controle de acesso: dmPolicy, allowFrom, groupPolicy, groupAllowFrom, groups, groups.*.topics.*, bindings[] de nível raiz (type: "acp")
  • aprovações de exec: execApprovals, accounts.*.execApprovals
  • comando/menu: commands.native, commands.nativeSkills, customCommands
  • threading/respostas: replyToMode
  • streaming: streaming (preview), blockStreaming
  • formatação/entrega: textChunkLimit, chunkMode, linkPreview, responsePrefix
  • mídia/rede: mediaMaxMb, timeoutSeconds, retry, network.autoSelectFamily, proxy
  • webhook: webhookUrl, webhookSecret, webhookPath, webhookHost
  • ações/capacidades: capabilities.inlineButtons, actions.sendMessage|editMessage|deleteMessage|reactions|sticker
  • reações: reactionNotifications, reactionLevel
  • escritas/histórico: configWrites, historyLimit, dmHistoryLimit, dms.*.historyLimit

Relacionado