Mainstream messaging

Telegram

Pronto para produção para DMs de bots e grupos via grammY. Long polling é o modo padrão; o modo webhook é opcional.

Configuração rápida

  • Crie o token do bot no BotFather

    Abra o Telegram e converse com @BotFather (confirme que o identificador é exatamente @BotFather).

    Execute /newbot, siga as instruções e salve o token.

  • Configure o token e a política de DM

    {
    channels: {
    telegram: {
      enabled: true,
      botToken: "123:abc",
      dmPolicy: "pairing",
      groups: { "*": { requireMention: true } },
    },
    },
    }
    

    Fallback de env: TELEGRAM_BOT_TOKEN=... (somente conta padrão). Telegram não usa openclaw channels login telegram; configure o token em config/env e então inicie o Gateway.

  • Inicie o Gateway e aprove a primeira DM

    openclaw gateway
    openclaw pairing list telegram
    openclaw pairing approve telegram <CODE>
    

    Códigos de emparelhamento expiram após 1 hora.

  • Adicione o bot a um grupo

    Adicione o bot ao seu grupo e então defina channels.telegram.groups e groupPolicy para corresponder ao seu modelo de acesso.

  • 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 de grupo:

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

    Ao alternar o modo de privacidade, remova e adicione novamente o bot em cada grupo para que o Telegram aplique a alteração.

    Permissões de grupo

    O status de administrador é controlado nas configurações do grupo do Telegram.

    Bots administradores recebem todas as mensagens de grupo, o que é útil para comportamento de grupo sempre ativo.

    Alternâncias úteis do BotFather
    • /setjoingroups para permitir/negar adições a grupos
    • /setprivacy para o comportamento de visibilidade em grupos

    Controle de acesso e ativação

    Política de DM

    channels.telegram.dmPolicy controla o acesso por mensagem direta:

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

    dmPolicy: "open" com allowFrom: ["*"] permite que qualquer conta do Telegram que encontre ou adivinhe o nome de usuário do bot comande o bot. Use isso apenas para bots intencionalmente públicos com ferramentas fortemente restritas; bots de um único proprietário devem usar allowlist com IDs numéricos de usuários.

    channels.telegram.allowFrom aceita IDs numéricos de usuários do Telegram. Os prefixos telegram: / tg: são aceitos e normalizados. Em configurações com várias contas, um channels.telegram.allowFrom restritivo de nível superior é tratado como um limite de segurança: entradas allowFrom: ["*"] no nível da conta não tornam essa conta pública, a menos que a allowlist efetiva da conta ainda contenha um curinga explícito após a mesclagem. dmPolicy: "allowlist" com allowFrom vazio bloqueia todas as DMs e é rejeitado pela validação de configuração. A configuração pede apenas IDs numéricos de usuários. Se você fez upgrade e sua configuração contém entradas @username na allowlist, execute openclaw doctor --fix para resolvê-las (melhor esforço; exige um token de bot do Telegram). Se você antes dependia de arquivos de allowlist do armazenamento de emparelhamento, openclaw doctor --fix pode recuperar entradas para channels.telegram.allowFrom em fluxos de allowlist (por exemplo, quando dmPolicy: "allowlist" ainda não tem IDs explícitos).

    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 configuração (em vez de depender de aprovações de emparelhamento anteriores).

    Confusão comum: a aprovação de emparelhamento por DM não significa "este remetente está autorizado em todos os lugares". O emparelhamento concede acesso por DM. Se ainda não existir um proprietário de comandos, o primeiro emparelhamento aprovado também define commands.ownerAllowFrom para que comandos exclusivos do proprietário e aprovações de exec tenham uma conta de operador explícita. A autorização de remetente em grupos ainda vem de allowlists explícitas na configuração. Se você quer "sou autorizado uma vez e tanto DMs quanto comandos de grupo funcionam", coloque seu ID numérico de usuário do Telegram em channels.telegram.allowFrom; para comandos exclusivos do proprietário, garanta que commands.ownerAllowFrom contenha telegram:<your user id>.

    Encontrando seu ID de usuário do Telegram

    Mais seguro (sem bot de terceiros):

    1. Envie uma DM para seu 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 allowlists

    Dois controles se aplicam juntos:

    1. Quais grupos são permitidos (channels.telegram.groups)

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

      • open
      • allowlist (padrão)
      • disabled

    groupAllowFrom é usado para filtragem de remetentes em grupos. Se não definido, Telegram recorre a allowFrom. Entradas groupAllowFrom devem ser IDs numéricos de usuários do Telegram (os prefixos telegram: / tg: são normalizados). Não coloque IDs de chat de grupos ou supergrupos do Telegram em groupAllowFrom. IDs de chat negativos 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 em grupo não herda aprovações do armazenamento de emparelhamento de DM. O emparelhamento permanece somente para DM. Para grupos, defina groupAllowFrom ou allowFrom por grupo/por tópico. Se groupAllowFrom não estiver definido, Telegram recorre a allowFrom da configuração, não ao armazenamento de emparelhamento. Padrão prático para bots de um único proprietário: defina seu ID de usuário em channels.telegram.allowFrom, deixe groupAllowFrom indefinido e permita os grupos de destino em channels.telegram.groups. Nota de runtime: se channels.telegram estiver completamente ausente, o runtime usa como padrão groupPolicy="allowlist" com falha fechada, a menos que channels.defaults.groupPolicy esteja definido explicitamente.

    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 específico:

    {
    channels: {
    telegram: {
      groups: {
        "-1001234567890": {
          requireMention: true,
          allowFrom: ["8734062810", "745123456"],
        },
      },
    },
    },
    }
    

    Comportamento de menção

    Respostas em grupos 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

    Alternâncias de comando no nível da sessão:

    • /activation always
    • /activation mention

    Elas atualizam apenas o estado da sessão. Use a configuração para persistência.

    Exemplo de configuração 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 em openclaw logs --follow
    • ou inspecione getUpdates da Bot API

    Comportamento de runtime

    • Telegram pertence ao processo do Gateway.
    • O roteamento é determinístico: entradas do Telegram respondem de volta ao 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 acrescentam :topic:<threadId> para manter os tópicos isolados.
    • Mensagens de DM podem carregar message_thread_id; OpenClaw preserva o ID da thread para respostas, mas mantém DMs na sessão plana por padrão. Configure channels.telegram.dm.threadReplies: "inbound", channels.telegram.direct.<chatId>.threadReplies: "inbound", requireTopic: true ou uma configuração de tópico correspondente quando você quiser intencionalmente isolamento de sessão de tópico em DM.
    • Long polling usa o runner do grammY com sequenciamento por chat/por thread. A concorrência geral do sink do runner usa agents.defaults.maxConcurrent.
    • Long polling é protegido dentro de cada processo do Gateway para que apenas um poller ativo possa usar um token de bot por vez. Se você ainda vir conflitos 409 de getUpdates, provavelmente outro Gateway do OpenClaw, script ou poller externo está usando o mesmo token.
    • Reinícios do watchdog de long polling são acionados após 120 segundos sem liveness de getUpdates concluído por padrão. Aumente channels.telegram.pollingStallThresholdMs apenas se sua implantação ainda vir reinícios falsos por travamento de polling durante trabalho de longa duração. O valor fica em milissegundos e é permitido de 30000 a 600000; substituições por conta são compatíveis.
    • A Bot API do Telegram não tem suporte a confirmação de leitura (sendReadReceipts não se aplica).

    Referência de recursos

    Prévia de stream ao vivo (edições de mensagem)

    OpenClaw pode transmitir respostas parciais em tempo real:

    • chats diretos: mensagem de prévia + editMessageText
    • grupos/tópicos: mensagem de prévia + editMessageText

    Requisito:

    • channels.telegram.streaming é off | partial | block | progress (padrão: partial)
    • progress mantém um rascunho de status editável para progresso de ferramentas, limpa-o na conclusão e envia a resposta final como uma mensagem normal
    • streaming.preview.toolProgress controla se atualizações de ferramenta/progresso reutilizam a mesma mensagem de prévia editada (padrão: true quando o streaming de prévia está ativo)
    • streaming.preview.commandText controla detalhes de comando/exec dentro dessas linhas de progresso de ferramentas: raw (padrão, preserva o comportamento lançado) ou status (somente rótulo da ferramenta)
    • channels.telegram.streamMode legado e valores booleanos de streaming são detectados; execute openclaw doctor --fix para migrá-los para channels.telegram.streaming.mode

    Atualizações de prévia de progresso de ferramentas são as linhas curtas de status mostradas enquanto ferramentas executam, por exemplo execução de comando, leituras de arquivo, atualizações de planejamento ou resumos de patch. Telegram mantém isso habilitado por padrão para corresponder ao comportamento lançado do OpenClaw a partir de v2026.4.22. Para manter a prévia editada para o texto da resposta, mas ocultar linhas de progresso de ferramentas, defina:

    {
      "channels": {
        "telegram": {
          "streaming": {
            "mode": "partial",
            "preview": {
              "toolProgress": false
            }
          }
        }
      }
    }
    

    Para manter o progresso de ferramentas visível, mas ocultar texto de comando/exec, defina:

    {
      "channels": {
        "telegram": {
          "streaming": {
            "mode": "partial",
            "preview": {
              "commandText": "status"
            }
          }
        }
      }
    }
    

    Use o modo progress quando quiser progresso visível das ferramentas sem editar a resposta final nessa mesma mensagem. Coloque a política de texto do comando em streaming.progress:

    {
      "channels": {
        "telegram": {
          "streaming": {
            "mode": "progress",
            "progress": {
              "toolProgress": true,
              "commandText": "status"
            }
          }
        }
      }
    }
    

    Use streaming.mode: "off" somente quando quiser entrega apenas final: as edições de prévia do Telegram são desativadas e conversas genéricas de ferramenta/progresso são suprimidas em vez de serem enviadas como mensagens de status avulsas. Solicitações de aprovação, payloads de mídia e erros ainda seguem pela entrega final normal. Use streaming.preview.toolProgress: false quando quiser manter apenas as edições de prévia da resposta e ocultar as linhas de status de progresso da ferramenta.

    Para respostas somente de texto:

    • prévias curtas em DM/grupo/tópico: o OpenClaw mantém a mesma mensagem de prévia e faz a edição final no local
    • finais de texto longos que são divididos em várias mensagens do Telegram reutilizam a prévia existente como o primeiro trecho final quando possível, depois enviam apenas os trechos restantes
    • finais em modo de progresso limpam o rascunho de status e usam a entrega final normal em vez de editar o rascunho para virar a resposta
    • se a edição final falhar antes de o texto concluído ser confirmado, o OpenClaw usa a entrega final normal e limpa a prévia obsoleta

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

    O streaming de prévia é separado do streaming de blocos. Quando o streaming de blocos está explicitamente habilitado para o Telegram, o OpenClaw ignora o fluxo de prévia para evitar streaming duplicado.

    Fluxo de raciocínio exclusivo do Telegram:

    • /reasoning stream envia o raciocínio para a prévia ao vivo durante a geração
    • a prévia de raciocínio é excluída após a entrega final; use /reasoning on quando o raciocínio deve permanecer visível
    • a resposta final é enviada sem texto de raciocínio
    Formatação e fallback de 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 analisado, o OpenClaw tenta novamente como texto simples.

    Pré-visualizações de links são habilitadas por padrão e podem ser desabilitadas com channels.telegram.linkPreview: false.

    Comandos nativos e comandos personalizados

    O registro do menu de comandos do Telegram é feito na inicialização com setMyCommands.

    Padrões de comandos nativos:

    • commands.native: "auto" habilita comandos nativos para o Telegram

    Adicione entradas personalizadas 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, coloca em minúsculas)
    • padrão válido: a-z, 0-9, _, comprimento 1..32
    • comandos personalizados não podem substituir comandos nativos
    • conflitos/duplicatas são ignorados e registrados em log

    Observações:

    • comandos personalizados são apenas entradas de menu; eles 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 desabilitados, os embutidos serão removidos. Comandos personalizados/de plugin ainda poderão ser registrados se configurados.

    Falhas comuns de configuração:

    • setMyCommands failed com BOT_COMMANDS_TOO_MUCH significa que o menu do Telegram ainda excedeu o limite após o corte; reduza comandos de plugin/skill/personalizados ou desabilite channels.telegram.commands.native.
    • falha em deleteWebhook, deleteMyCommands ou setMyCommands com 404: Not Found enquanto comandos curl diretos da Bot API funcionam pode significar que channels.telegram.apiRoot foi definido como o endpoint completo /bot&lt;TOKEN&gt;. apiRoot deve ser apenas a raiz da Bot API, e openclaw doctor --fix remove um /bot&lt;TOKEN&gt; final acidental.
    • getMe returned 401 significa que o Telegram rejeitou o token de bot configurado. Atualize botToken, tokenFile ou TELEGRAM_BOT_TOKEN com o token atual do BotFather; o OpenClaw para antes do polling, então isso não é relatado como falha de limpeza de Webhook.
    • 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 pending lista solicitações pendentes (incluindo função/escopos)
    4. aprove a solicitação:
      • /pair approve <requestId> para aprovação explícita
      • /pair approve quando houver apenas uma solicitação pendente
      • /pair approve latest para a mais recente

    O código de configuração carrega um token de bootstrap de curta duração. A transferência de bootstrap embutida mantém o token do nó primário em scopes: []; qualquer token de operador transferido permanece limitado a operator.approvals, operator.read, operator.talk.secrets e operator.write. As verificações de escopo de bootstrap têm prefixo de função, portanto essa allowlist de operador só satisfaz solicitações de operador; funções que não são de operador ainda precisam de escopos sob seu próprio prefixo de função.

    Se um dispositivo tentar novamente com detalhes de autenticação alterados (por exemplo, função/escopos/chave pública), a solicitação pendente anterior será substituída e a nova solicitação usará um requestId diferente. Execute /pair pending novamente antes de aprovar.

    Mais detalhes: Pareamento.

    Botões inline

    Configure o escopo do teclado inline:

    {
    channels: {
    telegram: {
      capabilities: {
        inlineButtons: "allowlist",
      },
    },
    },
    }
    

    Substituição 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)

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

    Controles de bloqueio:

    • channels.telegram.actions.sendMessage
    • channels.telegram.actions.deleteMessage
    • channels.telegram.actions.reactions
    • channels.telegram.actions.sticker (padrão: desabilitado)

    Observação: edit e topic-create atualmente são habilitados por padrão e não têm alternâncias channels.telegram.actions.* separadas. Envios em runtime usam o snapshot ativo de configuração/segredos (inicialização/recarga), portanto caminhos de ação não fazem nova resolução SecretRef ad hoc por envio.

    Semântica de remoção de reação: /tools/reactions

    Tags de encadeamento de resposta

    O Telegram aceita tags explícitas de encadeamento de resposta na saída gerada:

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

    channels.telegram.replyToMode controla o tratamento:

    • off (padrão)
    • first
    • all

    Quando o encadeamento de resposta está habilitado e o texto ou legenda original do Telegram está disponível, o OpenClaw inclui automaticamente um trecho de citação nativo do Telegram. O Telegram limita o texto de citação nativo a 1024 unidades de código UTF-16, portanto mensagens mais longas são citadas a partir do início e recorrem a uma resposta simples se o Telegram rejeitar a citação.

    Observação: off desabilita o encadeamento implícito de resposta. Tags explícitas [[reply_to_*]] ainda são respeitadas.

    Tópicos de fórum e comportamento de thread

    Supergrupos de fórum:

    • chaves de sessão de tópico acrescentam :topic:<threadId>
    • respostas e digitação têm como alvo a thread do tópico
    • caminho de configuração 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 sejam 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 rotear para um agente diferente definindo agentId na configuração do tópico. Isso dá a cada tópico seu próprio workspace, memória e sessão isolados. Exemplo:

    {
      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 persistente de tópico ACP: Tópicos de fórum podem fixar sessões de harness ACP por meio de vinculações ACP tipadas de nível superior (bindings[] com type: "acp" e match.channel: "telegram", peer.kind: "group" e um id qualificado por tópico como -1001234567890:topic:42). Atualmente limitado a tópicos de fórum em grupos/supergrupos. Veja Agentes ACP.

    Spawn ACP vinculado à thread a partir do chat: /acp spawn <agent> --thread here|auto vincula o tópico atual a uma nova sessão ACP; acompanhamentos são roteados diretamente para lá. O OpenClaw fixa a confirmação de spawn no tópico. Exige que channels.telegram.threadBindings.spawnSessions permaneça habilitado (padrão: true).

    O contexto do template expõe MessageThreadId e IsForum. Chats de MD com message_thread_id mantêm o roteamento de MD e os metadados de resposta em sessões planas por padrão; eles só usam chaves de sessão cientes de thread quando configurados com threadReplies: "inbound", threadReplies: "always", requireTopic: true ou uma configuração de tópico correspondente. Use channels.telegram.dm.threadReplies no nível superior para o padrão da conta, ou direct.<chatId>.threadReplies para uma MD.

    Á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 o envio como nota de voz
    • transcrições de notas de voz recebidas são enquadradas como texto gerado por máquina e não confiável no contexto do agente; a detecção de menções ainda usa a transcrição bruta, para que mensagens de voz controladas por menção continuem funcionando.

    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 oferecem suporte a legendas; o texto de mensagem fornecido é enviado separadamente.

    Stickers

    Tratamento de stickers recebidos:

    • WEBP estático: baixado e processado (placeholder <media:sticker>)
    • TGS animado: ignorado
    • WEBM em vídeo: ignorado

    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 repetidas de visão.

    Habilite ações de sticker:

    {
    channels: {
    telegram: {
      actions: {
        sticker: true,
      },
    },
    },
    }
    

    Enviar ação de sticker:

    {
    action: "sticker",
    channel: "telegram",
    to: "123456789",
    fileId: "CAACAgIAAxkBAAI...",
    }
    

    Pesquisar 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 habilitado, o OpenClaw enfileira eventos de sistema como:

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

    Configuração:

    • 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 (melhor esforço via cache de mensagens enviadas).
    • Eventos de reação ainda respeitam 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 que não são fórum roteiam para a sessão de chat do grupo
      • grupos de fórum roteiam para a sessão de tópico geral do grupo (:topic:1), não para o tópico exato de origem

    allowed_updates para polling/webhook inclui message_reaction automaticamente.

    Reações de confirmação

    ackReaction envia um emoji de confirmação enquanto o OpenClaw está processando uma mensagem recebida.

    Ordem de resolução:

    • channels.telegram.accounts.<accountId>.ackReaction
    • channels.telegram.ackReaction
    • messages.ackReaction
    • fallback de emoji de identidade do agente (agents.list[].identity.emoji, caso contrário "👀")

    Observações:

    • O Telegram espera emoji unicode (por exemplo "👀").
    • Use "" para desabilitar a reação para um canal ou conta.
    Gravações de configuração a partir de eventos e comandos do Telegram

    Gravações de configuração de canal são habilitadas por padrão (configWrites !== false).

    Gravações 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 habilitação de comando)

    Desabilitar:

    {
    channels: {
    telegram: {
      configWrites: false,
    },
    },
    }
    
    Long polling vs webhook

    O padrão é long polling. Para modo webhook, defina channels.telegram.webhookUrl e channels.telegram.webhookSecret; opcionais webhookPath, webhookHost, webhookPort (padrões /telegram-webhook, 127.0.0.1, 8787).

    No modo long polling, o OpenClaw persiste seu marcador de reinício somente depois que uma atualização é despachada com sucesso. Se um handler falhar, essa atualização permanece retentável no mesmo processo e não é gravada como concluída para desduplicação de reinício.

    O listener local faz bind em 127.0.0.1:8787. Para ingresso público, coloque um proxy reverso na frente da porta local ou defina webhookHost: "0.0.0.0" intencionalmente.

    O modo webhook valida os guards de requisição, o token secreto do Telegram e o corpo JSON antes de retornar 200 ao Telegram. Em seguida, o OpenClaw processa a atualização de forma assíncrona pelas mesmas lanes de bot por chat/por tópico usadas pelo long polling, para que turnos lentos do agente não segurem o ACK de entrega do Telegram.

    Limites, nova tentativa e destinos da CLI
    • O padrão de channels.telegram.textChunkLimit é 4000.
    • channels.telegram.chunkMode="newline" prefere limites de parágrafo (linhas em branco) antes da divisão por comprimento.
    • channels.telegram.mediaMaxMb (padrão 100) limita o tamanho de mídia recebida e enviada do Telegram.
    • channels.telegram.mediaGroupFlushMs (padrão 500) controla por quanto tempo álbuns/grupos de mídia do Telegram são armazenados em buffer antes que o OpenClaw os despache como uma única mensagem recebida. Aumente se partes do álbum chegarem tarde; diminua para reduzir a latência da resposta ao álbum.
    • channels.telegram.timeoutSeconds substitui o timeout do cliente da API do Telegram (se não definido, aplica-se o padrão do grammY). Clientes de bot limitam valores configurados abaixo do guard de requisição de texto/typing de saída de 60 segundos, para que o grammY não aborte a entrega de resposta visível antes que o guard de transporte e o fallback do OpenClaw possam executar. Long polling ainda usa um guard de requisição getUpdates de 45 segundos, para que polls ociosos não sejam abandonados indefinidamente.
    • channels.telegram.pollingStallThresholdMs usa 120000 por padrão; ajuste entre 30000 e 600000 apenas para reinícios de polling travado falso-positivos.
    • o histórico de contexto de grupo usa channels.telegram.historyLimit ou messages.groupChat.historyLimit (padrão 50); 0 desabilita.
    • contexto suplementar de resposta/citação/encaminhamento atualmente é passado como recebido.
    • allowlists do Telegram controlam principalmente quem pode acionar o agente, não um limite completo de redação de contexto suplementar.
    • Controles de histórico de MD:
      • channels.telegram.dmHistoryLimit
      • channels.telegram.dms["<user_id>"].historyLimit
    • a configuração channels.telegram.retry se aplica aos helpers de envio do Telegram (CLI/ferramentas/ações) para erros recuperáveis da API de saída. A entrega de resposta final recebida também usa uma nova tentativa bounded safe-send para falhas de pré-conexão do Telegram, mas não tenta novamente envelopes de rede ambíguos pós-envio que poderiam duplicar mensagens visíveis.

    Destinos de envio da CLI e da ferramenta de mensagem podem ser ID numérico de chat, username ou um destino de tópico de fórum:

    openclaw message send --channel telegram --target 123456789 --message "hi"
    openclaw message send --channel telegram --target @name --message "hi"
    openclaw message send --channel telegram --target -1001234567890:topic:42 --message "hi topic"
    

    Polls do Telegram usam openclaw message poll e oferecem suporte a 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 poll exclusivas do Telegram:

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

    O envio do Telegram também oferece suporte a:

    • --presentation com blocos buttons para teclados inline quando channels.telegram.capabilities.inlineButtons permite
    • --pin ou --delivery '{"pin":true}' para solicitar entrega fixada quando o bot pode fixar nesse chat
    • --force-document para enviar imagens e GIFs de saída como documentos em vez de uploads de foto compactada ou mídia animada

    Controle de ações:

    • channels.telegram.actions.sendMessage=false desabilita mensagens de saída do Telegram, incluindo polls
    • channels.telegram.actions.poll=false desabilita a criação de polls do Telegram enquanto mantém envios regulares habilitados
    Aprovações de execução no Telegram

    O Telegram oferece suporte a aprovações de execução em MDs de aprovadores e pode, opcionalmente, postar prompts no chat ou tópico de origem. Aprovadores devem ser IDs numéricos de usuário do Telegram.

    Caminho de configuração:

    • channels.telegram.execApprovals.enabled (habilita automaticamente quando pelo menos um aprovador pode ser resolvido)
    • channels.telegram.execApprovals.approvers (usa como fallback IDs numéricos de owners de commands.ownerAllowFrom)
    • channels.telegram.execApprovals.target: dm (padrão) | channel | both
    • agentFilter, sessionFilter

    channels.telegram.allowFrom, groupAllowFrom e defaultTo controlam quem pode falar com o bot e para onde ele envia respostas normais. Eles não tornam alguém um aprovador de execução. O primeiro pareamento de MD aprovado inicializa commands.ownerAllowFrom quando ainda não existe owner de comando, então a configuração de um owner ainda funciona sem duplicar IDs em execApprovals.approvers.

    A entrega no canal mostra o texto do comando no chat; habilite channel ou both apenas em grupos/tópicos confiáveis. Quando o prompt chega a um tópico de fórum, o OpenClaw preserva o tópico para o prompt de aprovação e o acompanhamento. Aprovações de execução expiram após 30 minutos por padrão.

    Botões de aprovação inline também exigem que channels.telegram.capabilities.inlineButtons permita a superfície de destino (dm, group ou all). IDs de aprovação prefixados com plugin: são resolvidos por aprovações de plugin; outros são resolvidos primeiro por aprovações de execução.

    Consulte Aprovações de execução.

    Controles de resposta de erro

    Quando o agente encontra um erro de entrega ou provedor, o Telegram pode responder com o texto do erro ou suprimi-lo. Duas chaves de configuração controlam esse comportamento:

    Chave Valores Padrão Descrição
    channels.telegram.errorPolicy reply, silent reply reply envia uma mensagem de erro amigável ao chat. silent suprime respostas de erro por completo.
    channels.telegram.errorCooldownMs number (ms) 60000 Tempo mínimo entre respostas de erro ao mesmo chat. Evita spam de erro durante indisponibilidades.

    Há suporte a substituições por conta, por grupo e por tópico (mesma herança de outras chaves de configuração do Telegram).

    {
      channels: {
        telegram: {
          errorPolicy: "reply",
          errorCooldownMs: 120000,
          groups: {
            "-1001234567890": {
              errorPolicy: "silent", // suppress errors in this group
            },
          },
        },
      },
    }
    

    Solução de problemas

    O bot não responde a mensagens de grupo sem menção
    • Se requireMention=false, o modo de privacidade do Telegram deve permitir visibilidade completa.
      • BotFather: /setprivacy -> Desativar
      • então remova + adicione novamente o bot ao grupo
    • openclaw channels status avisa quando a configuração espera mensagens de grupo sem menção.
    • openclaw channels status --probe pode verificar IDs numéricos explícitos de grupos; o curinga "*" não pode ter a associação verificada por sondagem.
    • 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 ver motivos de ignorar mensagens
    Comandos funcionam parcialmente ou não funcionam de forma alguma
    • autorize sua identidade de remetente (emparelhamento e/ou allowFrom numérico)
    • a autorização de comando ainda se aplica mesmo quando a política do grupo é open
    • setMyCommands failed com BOT_COMMANDS_TOO_MUCH significa que o menu nativo tem entradas demais; reduza comandos de Plugin/Skills/personalizados ou desative menus nativos
    • chamadas de inicialização deleteMyCommands / setMyCommands e chamadas de digitação sendChatAction são limitadas e tentam novamente uma vez pelo fallback de transporte do Telegram em caso de tempo limite da solicitação. Erros persistentes de rede/fetch geralmente indicam problemas de alcance DNS/HTTPS para api.telegram.org
    Inicialização relata token não autorizado
    • getMe returned 401 é uma falha de autenticação do Telegram para o token de bot configurado.
    • Copie novamente ou gere novamente o token do bot no BotFather e atualize channels.telegram.botToken, channels.telegram.tokenFile, channels.telegram.accounts.<id>.botToken ou TELEGRAM_BOT_TOKEN para a conta padrão.
    • deleteWebhook 401 Unauthorized durante a inicialização também é uma falha de autenticação; tratá-la como "nenhum Webhook existe" apenas adiaria a mesma falha de token inválido para chamadas de API posteriores.
    Instabilidade de polling ou rede
    • Node 22+ + fetch/proxy personalizado pode acionar comportamento de abortar imediatamente se os tipos de AbortSignal não corresponderem.
    • Alguns hosts resolvem api.telegram.org primeiro para IPv6; saída IPv6 com defeito pode causar falhas intermitentes da API do Telegram.
    • Se os logs incluírem TypeError: fetch failed ou Network request for 'getUpdates' failed!, o OpenClaw agora tenta novamente esses erros como erros de rede recuperáveis.
    • Durante a inicialização do polling, o OpenClaw reutiliza a sondagem getMe bem-sucedida da inicialização para o grammY, então o runner não precisa de um segundo getMe antes do primeiro getUpdates.
    • Se deleteWebhook falhar com um erro de rede transitório durante a inicialização do polling, o OpenClaw continua para long polling em vez de fazer outra chamada de plano de controle antes do polling. Um Webhook ainda ativo aparece como um conflito de getUpdates; o OpenClaw então reconstrói o transporte do Telegram e tenta novamente a limpeza do Webhook.
    • Se os sockets do Telegram forem reciclados em uma cadência fixa curta, verifique se há um channels.telegram.timeoutSeconds baixo; clientes de bot limitam valores configurados abaixo dos guardas de solicitações de saída e getUpdates, mas versões mais antigas podiam abortar cada polling ou resposta quando isso era definido abaixo desses guardas.
    • Se os logs incluírem Polling stall detected, o OpenClaw reinicia o polling e reconstrói o transporte do Telegram após 120 segundos sem liveness de long-poll concluído por padrão.
    • openclaw channels status --probe e openclaw doctor avisam quando uma conta de polling em execução não concluiu getUpdates após a tolerância de inicialização, quando uma conta de Webhook em execução não concluiu setWebhook após a tolerância de inicialização, ou quando a última atividade bem-sucedida do transporte de polling está obsoleta.
    • Aumente channels.telegram.pollingStallThresholdMs apenas quando chamadas getUpdates de longa duração estiverem saudáveis, mas seu host ainda relatar reinicializações falsas por travamento de polling. Travamentos persistentes geralmente apontam para problemas de proxy, DNS, IPv6 ou saída TLS entre o host e api.telegram.org.
    • O Telegram também respeita env de proxy do processo para o transporte da API de Bot, incluindo HTTP_PROXY, HTTPS_PROXY, ALL_PROXY e suas variantes em minúsculas. NO_PROXY / no_proxy ainda pode ignorar api.telegram.org.
    • Se o proxy gerenciado do OpenClaw estiver configurado por OPENCLAW_PROXY_URL para um ambiente de serviço e nenhum env de proxy padrão estiver presente, o Telegram também usa essa URL para o transporte da API de Bot.
    • Em hosts VPS com saída direta/TLS instável, roteie chamadas da API do Telegram por channels.telegram.proxy:
    channels:
    telegram:
    proxy: socks5://<user>:<password>@proxy-host:1080
    
    • Node 22+ usa autoSelectFamily=true por padrão (exceto WSL2). A ordem dos resultados DNS do Telegram respeita OPENCLAW_TELEGRAM_DNS_RESULT_ORDER, depois channels.telegram.network.dnsResultOrder, depois o padrão do processo, como NODE_OPTIONS=--dns-result-order=ipv4first; se nada se aplicar, Node 22+ volta para ipv4first.
    • Se seu host for WSL2 ou funcionar explicitamente melhor com comportamento somente IPv4, force a seleção de família:
    channels:
    telegram:
    network:
      autoSelectFamily: false
    
    • Respostas do intervalo de benchmark RFC 2544 (198.18.0.0/15) já são permitidas para downloads de mídia do Telegram por padrão. Se um fake-IP confiável ou proxy transparente reescrever api.telegram.org para algum outro endereço privado/interno/de uso especial durante downloads de mídia, você pode optar pelo bypass somente do Telegram:
    channels:
    telegram:
    network:
      dangerouslyAllowPrivateNetwork: true
    
    • A mesma adesão está disponível por conta em channels.telegram.accounts.<accountId>.network.dangerouslyAllowPrivateNetwork.
    • Se seu proxy resolver hosts de mídia do Telegram para 198.18.x.x, deixe a flag perigosa desativada primeiro. Mídia do Telegram já permite o intervalo de benchmark RFC 2544 por padrão.
    • Substituições de ambiente (temporárias):
      • 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

    Referência principal: Referência de configuração - Telegram.

    Campos de alto sinal 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 superior (type: "acp")
    • aprovações de execução: execApprovals, accounts.*.execApprovals
    • comando/menu: commands.native, commands.nativeSkills, customCommands
    • conversas/respostas: replyToMode, dm.threadReplies, direct.*.threadReplies
    • streaming: streaming (prévia), streaming.preview.toolProgress, blockStreaming
    • formatação/entrega: textChunkLimit, chunkMode, linkPreview, responsePrefix
    • mídia/rede: mediaMaxMb, mediaGroupFlushMs, timeoutSeconds, pollingStallThresholdMs, retry, network.autoSelectFamily, network.dangerouslyAllowPrivateNetwork, proxy
    • raiz de API personalizada: apiRoot (somente raiz da API de Bot; não inclua /bot&lt;TOKEN&gt;)
    • Webhook: webhookUrl, webhookSecret, webhookPath, webhookHost
    • ações/capacidades: capabilities.inlineButtons, actions.sendMessage|editMessage|deleteMessage|reactions|sticker
    • reações: reactionNotifications, reactionLevel
    • erros: errorPolicy, errorCooldownMs
    • gravações/histórico: configWrites, historyLimit, dmHistoryLimit, dms.*.historyLimit

    Relacionados