Mainstream messaging
Status: pronto para produção via WhatsApp Web (Baileys). O Gateway gerencia a(s) sessão(ões) vinculada(s).
Instalação (sob demanda)
- O onboarding (
openclaw onboard) eopenclaw channels add --channel whatsappsolicitam a instalação do Plugin do WhatsApp na primeira vez que você o seleciona. openclaw channels login --channel whatsapptambém oferece o fluxo de instalação quando o Plugin ainda não está presente.- Canal de desenvolvimento + checkout do git: usa por padrão o caminho do Plugin local.
- Stable/Beta: instala primeiro o Plugin oficial
@openclaw/whatsappdo ClawHub, com npm como fallback. - O runtime do WhatsApp é distribuído fora do pacote npm principal do OpenClaw para que as dependências de runtime específicas do WhatsApp permaneçam com o Plugin externo.
A instalação manual continua disponível:
openclaw plugins install clawhub:@openclaw/whatsappUse o pacote npm simples (@openclaw/whatsapp) apenas quando precisar do fallback do registro.
Fixe uma versão exata apenas quando precisar de uma instalação reproduzível.
A política padrão de DM é pareamento para remetentes desconhecidos.
Diagnósticos entre canais e playbooks de reparo.
Padrões e exemplos completos de configuração de canal.
Configuração rápida
Configure a política de acesso do WhatsApp
{channels: {whatsapp: { dmPolicy: "pairing", allowFrom: ["+15551234567"], groupPolicy: "allowlist", groupAllowFrom: ["+15551234567"],},},}Vincule o WhatsApp (QR)
openclaw channels login --channel whatsappO login atual é baseado em QR. Em ambientes remotos ou sem interface gráfica, garanta que você tenha um caminho confiável para entregar o código QR ativo ao telefone que fará a leitura antes de iniciar o login.
Para uma conta específica:
openclaw channels login --channel whatsapp --account workPara anexar um diretório de autenticação existente/personalizado do WhatsApp Web antes do login:
openclaw channels add --channel whatsapp --account work --auth-dir /path/to/wa-authopenclaw channels login --channel whatsapp --account workInicie o Gateway
openclaw gatewayAprove a primeira solicitação de pareamento (se estiver usando o modo de pareamento)
openclaw pairing list whatsappopenclaw pairing approve whatsapp <CODE>As solicitações de pareamento expiram após 1 hora. As solicitações pendentes são limitadas a 3 por canal.
Ligue para o solicitante atual com MeowCaller (experimental)
O Plugin do WhatsApp pode expor whatsapp_call em turnos de agente originados do WhatsApp. A ferramenta
usa MeowCaller para fazer uma chamada de voz do WhatsApp para
o solicitante autorizado atual e reproduz uma mensagem TTS da OpenClaw depois que ele atende. A ferramenta
não aceita um número de destino, portanto um prompt não pode redirecionar a chamada para terceiros.
Este recurso experimental fica desabilitado por padrão.
Habilite chamadas experimentais
Adicione actions.calls: true ao canal do WhatsApp em openclaw.json:
{"channels": {"whatsapp": { "actions": { "calls": true }}}}Mescle isso à sua configuração existente do WhatsApp e reinicie o Gateway. Quando a
configuração estiver ausente ou for false, a OpenClaw não expõe a ferramenta whatsapp_call ao agente.
Instale a CLI MeowCaller revisada
O adaptador espera um executável chamado meowcaller no PATH do host do Gateway.
Até que MeowCaller PR #7 seja mesclado, compile
a branch revisada no commit 752050471fc2bf7a8cdfbf7dbd3cd4e865d85d3f:
git clone --branch feat/send-only-notify https://github.com/steipete/meowcaller.gitcd meowcallergit checkout 752050471fc2bf7a8cdfbf7dbd3cd4e865d85d3fmkdir -p "$HOME/.local/bin"go build -o "$HOME/.local/bin/meowcaller" ./cmd/meowcallerGaranta que $HOME/.local/bin também esteja no PATH do serviço do Gateway. Esta revisão fornece
comandos explícitos pair e notify somente de envio. notify não abre microfone, alto-falante,
dispositivo de vídeo, coletor de áudio de entrada nem captura de diagnóstico. Não substitua pelo comando
play da CLI de exemplo.
Pareie o dispositivo vinculado do MeowCaller
Peça ao agente do WhatsApp para verificar a configuração de chamada. A ação de status whatsapp_call informa o
diretório de estado específico da conta e o comando de pareamento. Para a conta padrão:
state_dir="$HOME/.openclaw/credentials/whatsapp-calls/default"mkdir -p "$state_dir"chmod 700 "$state_dir"meowcaller pair --store "$state_dir/wa-voip.db"Execute o comando em um terminal interativo. Leia o QR em WhatsApp > Dispositivos vinculados
e aguarde MeowCaller linked device ready. Em seguida, o comando termina. Mantenha wa-voip.db
privado; ele é a sessão de dispositivo vinculado do MeowCaller. A ação de status whatsapp_call
retorna o comando e o shell específicos da conta quando você usa uma conta não padrão. No
Windows, execute o comando PowerShell dele; o MeowCaller cria o diretório de armazenamento.
Configure TTS e faça a chamada pelo WhatsApp
Configure um provedor de TTS compatível com telefonia, reinicie o Gateway e envie uma
solicitação do WhatsApp como Call me and say the build finished. A ferramenta resolve o remetente
a partir do contexto de entrada confiável, sintetiza um arquivo WAV temporário privado, executa o MeowCaller por uma
janela de chamada limitada e exclui o arquivo de áudio depois. A OpenClaw passa explicitamente o armazenamento da conta,
aguarda um status de saída zero após atendimento, reprodução e encerramento da chamada, e trata
timeout ou saída diferente de zero como uma chamada de ferramenta com falha.
Limites atuais:
- apenas chamadas de áudio de saída um para um
- sem números de destino arbitrários
- sem autenticação compartilhada com a conexão de chat
- sem chamadas para si mesmo no modo número pessoal/self-chat
- áudio sintetizado limitado a 60 segundos
- sem confirmação de audibilidade no aparelho além da conclusão de atendimento/reprodução/encerramento do MeowCaller
- a OpenClaw interrompe o processo auxiliar após uma janela limitada de 115 a 175 segundos, incluindo as fases de conexão, atendimento, reprodução e desligamento do MeowCaller
Padrões de implantação
Número dedicado (recomendado)
Este é o modo operacional mais limpo:
- identidade do WhatsApp separada para a OpenClaw
- allowlists de DM e limites de roteamento mais claros
- menor chance de confusão com self-chat
Padrão mínimo de política:
{ channels: { whatsapp: { dmPolicy: "allowlist", allowFrom: ["+15551234567"], }, },}Fallback com número pessoal
O onboarding oferece suporte ao modo número pessoal e grava uma base compatível com self-chat:
dmPolicy: "allowlist"allowFrominclui seu número pessoalselfChatMode: true
No runtime, as proteções de self-chat usam o número próprio vinculado e allowFrom.
Escopo de canal somente WhatsApp Web
O canal da plataforma de mensagens é baseado no WhatsApp Web (Baileys) na arquitetura atual de canais da OpenClaw.
Não há um canal de mensagens separado do Twilio WhatsApp no registro integrado de canais de chat.
Modelo de runtime
- O Gateway gerencia o socket do WhatsApp e o loop de reconexão.
- O watchdog de reconexão usa a atividade do transporte do WhatsApp Web, não apenas o volume de mensagens de app de entrada, portanto uma sessão silenciosa de dispositivo vinculado não é reiniciada somente porque ninguém enviou uma mensagem recentemente. Um limite mais longo de silêncio da aplicação ainda força uma reconexão se frames de transporte continuarem chegando, mas nenhuma mensagem de aplicação for tratada durante a janela do watchdog; após uma reconexão transitória para uma sessão ativa recentemente, essa verificação de silêncio da aplicação usa o timeout normal de mensagens na primeira janela de recuperação.
- Os tempos do socket Baileys são explícitos em
web.whatsapp.*:keepAliveIntervalMscontrola pings de aplicação do WhatsApp Web,connectTimeoutMscontrola o timeout do handshake de abertura, edefaultQueryTimeoutMscontrola esperas de consulta do Baileys mais os limites locais da OpenClaw para envio/presença de saída e operações de confirmação de leitura de entrada. - Envios de saída exigem um listener ativo do WhatsApp para a conta de destino.
- Envios de grupo anexam metadados nativos de menção para tokens
@+<digits>e@<digits>em texto e legendas de mídia quando o token corresponde aos metadados atuais de participante do WhatsApp, incluindo grupos com suporte a LID. - Chats de status e broadcast são ignorados (
@status,@broadcast). - O watchdog de reconexão segue a atividade do transporte do WhatsApp Web, não apenas o volume de mensagens de app de entrada: sessões silenciosas de dispositivos vinculados permanecem ativas enquanto frames de transporte continuam, mas uma interrupção do transporte força reconexão bem antes do caminho posterior de desconexão remota.
- Chats diretos usam regras de sessão de DM (
session.dmScope; o padrãomaincolapsa DMs para a sessão principal do agente). - Sessões de grupo são isoladas (
agent:<agentId>:whatsapp:group:<jid>). - WhatsApp Channels/Newsletters podem ser destinos explícitos de saída com seu JID nativo
@newsletter. Envios de newsletter de saída usam metadados de sessão de canal (agent:<agentId>:whatsapp:channel:<jid>) em vez de semântica de sessão de DM. - O transporte WhatsApp Web respeita variáveis de ambiente de proxy padrão no host do Gateway (
HTTPS_PROXY,HTTP_PROXY,NO_PROXY/ variantes em minúsculas). Prefira configuração de proxy em nível de host em vez de configurações de proxy específicas do canal do WhatsApp. - Quando
messages.removeAckAfterReplyestá habilitado, a OpenClaw limpa a reação de confirmação do WhatsApp depois que uma resposta visível é entregue.
Prompts de aprovação
O WhatsApp pode renderizar prompts de aprovação de exec e Plugin com reações 👍 / 👎. A entrega é
controlada pela configuração de encaminhamento de aprovação de nível superior:
{ approvals: { exec: { enabled: true, mode: "session", }, plugin: { enabled: true, mode: "targets", targets: [{ channel: "whatsapp", to: "+15551234567" }], }, },}approvals.exec e approvals.plugin são independentes. Habilitar o WhatsApp como canal apenas vincula
o transporte; isso não envia prompts de aprovação a menos que a família de aprovação correspondente esteja habilitada
e roteie para o WhatsApp. O modo de sessão entrega aprovações nativas por emoji somente para aprovações que
se originam do WhatsApp. O modo de destino usa o pipeline de encaminhamento compartilhado para destinos explícitos do WhatsApp
e não cria fanout separado de DM para aprovadores.
Reações de aprovação do WhatsApp exigem aprovadores explícitos do WhatsApp de allowFrom ou "*".
defaultTo controla destinos padrão comuns de mensagens; ele não é um aprovador de aprovação. Comandos manuais
/approve ainda passam pelo caminho normal de autorização de remetente do WhatsApp antes da
resolução da aprovação.
Hooks de Plugin e privacidade
Mensagens recebidas do WhatsApp podem conter conteúdo pessoal de mensagens, números de telefone,
identificadores de grupos, nomes de remetentes e campos de correlação de sessão. Por esse motivo,
o WhatsApp não transmite payloads de hook message_received recebidos para plugins
a menos que você habilite isso explicitamente:
{ channels: { whatsapp: { pluginHooks: { messageReceived: true, }, }, },}Você pode limitar a habilitação a uma conta:
{ channels: { whatsapp: { accounts: { work: { pluginHooks: { messageReceived: true, }, }, }, }, },}Habilite isso apenas para plugins nos quais você confia para receber conteúdo e identificadores de mensagens recebidas do WhatsApp.
Controle de acesso e ativação
DM policy
channels.whatsapp.dmPolicy controla o acesso a chats diretos:
pairing(padrão)allowlistopen(exige queallowFrominclua"*")disabled
allowFrom aceita números no estilo E.164 (normalizados internamente).
allowFrom é uma lista de controle de acesso de remetentes de DM. Ela não controla envios explícitos de saída para JIDs de grupos do WhatsApp ou JIDs de canais @newsletter.
Substituição para várias contas: channels.whatsapp.accounts.<id>.dmPolicy (e allowFrom) têm precedência sobre os padrões no nível do canal para essa conta.
Detalhes do comportamento em runtime:
- emparelhamentos são persistidos no armazenamento de permissões do canal e mesclados com o
allowFromconfigurado - automações agendadas e fallback de destinatário de Heartbeat usam destinos de entrega explícitos ou
allowFromconfigurado; aprovações de emparelhamento de DM não são destinatários implícitos de Cron ou Heartbeat - se nenhuma allowlist estiver configurada, o próprio número vinculado é permitido por padrão
- o OpenClaw nunca emparelha automaticamente DMs de saída
fromMe(mensagens que você envia para si mesmo a partir do dispositivo vinculado)
Group policy + allowlists
O acesso a grupos tem duas camadas:
-
Allowlist de participação em grupos (
channels.whatsapp.groups)- se
groupsfor omitido, todos os grupos são elegíveis - se
groupsestiver presente, ele atua como uma allowlist de grupos ("*"permitido)
- se
-
Política de remetente de grupo (
channels.whatsapp.groupPolicy+groupAllowFrom)open: allowlist de remetentes ignoradaallowlist: o remetente deve corresponder agroupAllowFrom(ou*)disabled: bloqueia todas as entradas de grupos
Fallback da allowlist de remetentes:
- se
groupAllowFromnão estiver definido, o runtime recorre aallowFromquando disponível - allowlists de remetentes são avaliadas antes da ativação por menção/resposta
Observação: se nenhum bloco channels.whatsapp existir, o fallback de política de grupos em runtime será allowlist (com um log de aviso), mesmo que channels.defaults.groupPolicy esteja definido.
Mentions + /activation
Respostas em grupo exigem menção por padrão.
A detecção de menções inclui:
- menções explícitas do WhatsApp à identidade do bot
- padrões regex de menção configurados (
agents.list[].groupChat.mentionPatterns, fallbackmessages.groupChat.mentionPatterns) - transcrições de notas de voz recebidas para mensagens de grupo autorizadas
- detecção implícita de resposta ao bot (o remetente da resposta corresponde à identidade do bot)
Observação de segurança:
- citação/resposta satisfaz apenas o controle por menção; ela não concede autorização ao remetente
- com
groupPolicy: "allowlist", remetentes fora da allowlist continuam bloqueados mesmo que respondam à mensagem de um usuário na allowlist
Comando de ativação em nível de sessão:
/activation mention/activation always
activation atualiza o estado da sessão (não a configuração global). Ele é controlado pelo proprietário.
Vinculações ACP configuradas
O WhatsApp é compatível com vinculações ACP persistentes com entradas bindings[] de nível superior:
{ bindings: [ { type: "acp", agentId: "codex", match: { channel: "whatsapp", accountId: "work", peer: { kind: "direct", id: "+15555550123" }, }, }, { type: "acp", agentId: "codex", match: { channel: "whatsapp", accountId: "work", peer: { kind: "group", id: "120363424282127706@g.us" }, }, }, ],}- Chats diretos correspondem a números E.164, como
+15555550123. - Grupos correspondem a JIDs de grupos do WhatsApp, como
120363424282127706@g.us. - Allowlists de grupos, política de remetente e controle por menção ou ativação são executados antes de o OpenClaw garantir que a sessão ACP configurada exista.
- Uma vinculação ACP configurada correspondente é dona da rota. Grupos de broadcast do WhatsApp não distribuem esse turno para sessões comuns do WhatsApp.
Comportamento de número pessoal e chat consigo mesmo
Quando o próprio número vinculado também está presente em allowFrom, as proteções de chat consigo mesmo do WhatsApp são ativadas:
- ignora confirmações de leitura para turnos de chat consigo mesmo
- ignora comportamento de acionamento automático por JID de menção que, caso contrário, mencionaria você mesmo
- se
messages.responsePrefixnão estiver definido, respostas de chat consigo mesmo usam por padrão[{identity.name}]ou[openclaw]
Normalização de mensagens e contexto
Inbound envelope + reply context
Mensagens recebidas do WhatsApp são encapsuladas no envelope de entrada compartilhado.
Se existir uma resposta citada, o contexto é anexado neste formato:
[Replying to <sender> id:<stanzaId>]<quoted body or media placeholder>[/Replying]Campos de metadados de resposta também são preenchidos quando disponíveis (ReplyToId, ReplyToBody, ReplyToSender, JID/E.164 do remetente).
Quando o alvo da resposta citada é mídia baixável, o OpenClaw a salva por meio
do armazenamento normal de mídia recebida e a expõe como MediaPath/MediaType para que
o agente possa inspecionar a imagem referenciada em vez de ver apenas
<media:image>.
Media placeholders and location/contact extraction
Mensagens recebidas somente com mídia são normalizadas com placeholders como:
<media:image><media:video><media:audio><media:document><media:sticker>
Notas de voz de grupos autorizados são transcritas antes do controle por menção quando o
corpo contém apenas <media:audio>, então dizer a menção ao bot na nota de voz pode
acionar a resposta. Se a transcrição ainda não mencionar o bot, a
transcrição é mantida no histórico pendente do grupo em vez do placeholder bruto.
Corpos de localização usam texto conciso de coordenadas. Rótulos/comentários de localização e detalhes de contato/vCard são renderizados como metadados não confiáveis em bloco cercado, não como texto inline no prompt.
Pending group history injection
Para grupos, mensagens não processadas podem ser armazenadas em buffer e injetadas como contexto quando o bot finalmente for acionado.
- limite padrão:
50 - configuração:
channels.whatsapp.historyLimit - fallback:
messages.groupChat.historyLimit 0desabilita
Marcadores de injeção:
[Chat messages since your last reply - for context][Current message - respond to this]
Read receipts
Confirmações de leitura são habilitadas por padrão para mensagens recebidas aceitas do WhatsApp.
Desabilitar globalmente:
{ channels: { whatsapp: { sendReadReceipts: false, }, },}Substituição por conta:
{ channels: { whatsapp: { accounts: { work: { sendReadReceipts: false, }, }, }, },}Turnos de chat consigo mesmo ignoram confirmações de leitura mesmo quando habilitadas globalmente.
Entrega, divisão em partes e mídia
Text chunking
- limite padrão de parte:
channels.whatsapp.textChunkLimit = 4000 channels.whatsapp.chunkMode = "length" | "newline"- o modo
newlineprefere limites de parágrafo (linhas em branco) e, em seguida, recorre à divisão em partes segura por comprimento
Outbound media behavior
- oferece suporte a payloads de imagem, vídeo, áudio (nota de voz PTT) e documento
- mídia de áudio é enviada pelo payload
audiodo Baileys comptt: true, então clientes do WhatsApp a renderizam como nota de voz push-to-talk - payloads de resposta preservam
audioAsVoice; a saída de nota de voz TTS para WhatsApp permanece nesse caminho PTT mesmo quando o provedor retorna MP3 ou WebM - áudio Ogg/Opus nativo é enviado como
audio/ogg; codecs=opuspara compatibilidade com nota de voz - áudio que não seja Ogg, incluindo a saída MP3/WebM do TTS do Microsoft Edge, é transcodificado com
ffmpegpara Ogg/Opus mono de 48 kHz antes da entrega PTT /tts latestenvia a resposta mais recente do assistente como uma nota de voz e suprime reenvios para a mesma resposta;/tts chat on|off|defaultcontrola o TTS automático para o chat atual do WhatsApp- reprodução de GIF animado é compatível via
gifPlayback: trueem envios de vídeo forceDocument/asDocumentenvia imagens, GIFs e vídeos de saída pelo payload de documento do Baileys para evitar compressão de mídia do WhatsApp, preservando o nome de arquivo resolvido e o tipo MIME- legendas são aplicadas ao primeiro item de mídia ao enviar payloads de resposta com várias mídias, exceto que notas de voz PTT enviam o áudio primeiro e o texto visível separadamente porque clientes do WhatsApp não renderizam legendas de notas de voz de forma consistente
- a origem da mídia pode ser HTTP(S),
file://ou caminhos locais
Media size limits and fallback behavior
- limite de salvamento de mídia recebida:
channels.whatsapp.mediaMaxMb(padrão50) - limite de envio de mídia de saída:
channels.whatsapp.mediaMaxMb(padrão50) - substituições por conta usam
channels.whatsapp.accounts.<accountId>.mediaMaxMb - imagens são otimizadas automaticamente (varredura de redimensionamento/qualidade) para se ajustar aos limites, a menos que
forceDocument/asDocumentsolicite entrega como documento - em falha de envio de mídia, o fallback do primeiro item envia aviso em texto em vez de descartar a resposta silenciosamente
Citação de respostas
O WhatsApp é compatível com citação nativa de respostas, em que respostas de saída citam visivelmente a mensagem recebida. Controle isso com channels.whatsapp.replyToMode.
| Valor | Comportamento |
|---|---|
"off" |
Nunca cita; envia como mensagem simples |
"first" |
Cita apenas a primeira parte da resposta de saída |
"all" |
Cita todas as partes da resposta de saída |
"batched" |
Cita respostas em lote enfileiradas, deixando respostas imediatas sem citação |
O padrão é "off". Substituições por conta usam channels.whatsapp.accounts.<id>.replyToMode.
{ channels: { whatsapp: { replyToMode: "first", }, },}Nível de reação
channels.whatsapp.reactionLevel controla a amplitude com que o agente usa reações de emoji no WhatsApp:
| Nível | Reações de confirmação | Reações iniciadas pelo agente | Descrição |
|---|---|---|---|
"off" |
Não | Não | Nenhuma reação |
"ack" |
Sim | Não | Apenas reações de confirmação (recibo pré-resposta) |
"minimal" |
Sim | Sim (conservador) | Confirmação + reações do agente com orientação conservadora |
"extensive" |
Sim | Sim (incentivado) | Confirmação + reações do agente com orientação incentivada |
Padrão: "minimal".
Substituições por conta usam channels.whatsapp.accounts.<id>.reactionLevel.
{ channels: { whatsapp: { reactionLevel: "ack", }, },}Reações de confirmação
O WhatsApp é compatível com reações de confirmação imediatas no recebimento de entrada via channels.whatsapp.ackReaction.
Reações de confirmação são controladas por reactionLevel — elas são suprimidas quando reactionLevel é "off".
{ channels: { whatsapp: { ackReaction: { emoji: "👀", direct: true, group: "mentions", // always | mentions | never }, }, },}Notas de comportamento:
- enviada imediatamente depois que a entrada é aceita (antes da resposta)
- se
ackReactionestiver presente sememoji, o WhatsApp usa o emoji de identidade do agente roteado, recorrendo a "👀"; omitaackReactionou definaemoji: ""para não enviar nenhuma reação de confirmação - falhas são registradas, mas não bloqueiam a entrega normal da resposta
- o modo de grupo
mentionsreage em turnos acionados por menção; a ativação de grupoalwaysatua como bypass para essa verificação - o WhatsApp usa
channels.whatsapp.ackReaction(messages.ackReactionlegado não é usado aqui)
Reações de status do ciclo de vida
Defina messages.statusReactions.enabled: true para permitir que o WhatsApp substitua a reação de confirmação durante um turno em vez de deixar um emoji de recibo estático. Quando ativado, o OpenClaw usa o mesmo slot de reação da mensagem de entrada para estados do ciclo de vida, como enfileirado, pensando, atividade de ferramenta, Compaction, concluído e erro.
{ messages: { statusReactions: { enabled: true, emojis: { deploy: "🛫", build: "🏗️", concierge: "💁", }, }, },}Notas de comportamento:
channels.whatsapp.ackReactionainda controla se as reações de status são elegíveis para mensagens diretas e grupos.- A reação de status enfileirado usa o mesmo emoji de confirmação efetivo das reações de confirmação simples.
- O WhatsApp tem um slot de reação de bot por mensagem, portanto as atualizações de ciclo de vida substituem a reação atual no mesmo lugar.
messages.removeAckAfterReply: truelimpa a reação de status final após a retenção configurada de concluído/erro.- As categorias de emoji de ferramenta incluem
tool,coding,web,deploy,buildeconcierge.
Várias contas e credenciais
Seleção de conta e padrões
- os ids de conta vêm de
channels.whatsapp.accounts - seleção de conta padrão:
default, se presente; caso contrário, o primeiro id de conta configurado (ordenado) - os ids de conta são normalizados internamente para consulta
Caminhos de credenciais e compatibilidade legada
- caminho de autenticação atual:
~/.openclaw/credentials/whatsapp/<accountId>/creds.json - arquivo de backup:
creds.json.bak - a autenticação padrão legada em
~/.openclaw/credentials/ainda é reconhecida/migrada para fluxos de conta padrão
Comportamento de logout
openclaw channels logout --channel whatsapp [--account <id>] limpa o estado de autenticação do WhatsApp para essa conta.
Quando um Gateway está acessível, o logout primeiro interrompe o listener ativo do WhatsApp para a conta selecionada, para que a sessão vinculada não continue recebendo mensagens até a próxima reinicialização. openclaw channels remove --channel whatsapp também interrompe o listener ativo antes de desabilitar ou excluir a configuração da conta.
Em diretórios de autenticação legados, oauth.json é preservado enquanto os arquivos de autenticação do Baileys são removidos.
Ferramentas, ações e gravações de configuração
- O suporte a ferramentas do agente inclui a ação de reação do WhatsApp (
react). - Portões de ação:
channels.whatsapp.actions.reactionschannels.whatsapp.actions.polls
- Gravações de configuração iniciadas pelo canal são ativadas por padrão (desative via
channels.whatsapp.configWrites=false).
Solução de problemas
Não vinculado (QR necessário)
Sintoma: o status do canal informa que não está vinculado.
Correção:
openclaw channels login --channel whatsappopenclaw channels statusVinculado, mas desconectado / loop de reconexão
Sintoma: conta vinculada com desconexões repetidas ou tentativas de reconexão.
Contas silenciosas podem permanecer conectadas além do tempo limite normal de mensagens; o monitoramento reinicia quando a atividade do transporte WhatsApp Web para, o socket fecha ou a atividade no nível da aplicação permanece silenciosa além da janela de segurança mais longa.
Se os logs mostrarem repetidamente status=408 Request Time-out Connection was lost, ajuste
os tempos de socket do Baileys em web.whatsapp. Comece reduzindo
keepAliveIntervalMs para abaixo do tempo limite ocioso da sua rede e aumentando
connectTimeoutMs em links lentos ou com perdas:
{ web: { whatsapp: { keepAliveIntervalMs: 15000, connectTimeoutMs: 60000, defaultQueryTimeoutMs: 60000, }, },}Correção:
openclaw channels status --probeopenclaw doctoropenclaw logs --followopenclaw gateway statusSe o loop persistir depois que a conectividade do host e os tempos forem corrigidos, faça backup do diretório de autenticação da conta e vincule essa conta novamente:
cp -a ~/.openclaw/credentials/whatsapp/<accountId> \ ~/.openclaw/credentials/whatsapp/<accountId>.bakopenclaw channels logout --channel whatsapp --account <accountId>openclaw channels login --channel whatsapp --account <accountId>Se ~/.openclaw/logs/whatsapp-health.log disser Gateway inactive, mas
openclaw gateway status e openclaw channels status --probe mostrarem que o
gateway e o WhatsApp estão íntegros, execute openclaw doctor. No Linux, o doctor
alerta sobre entradas legadas do crontab que ainda invocam
~/.openclaw/bin/ensure-whatsapp.sh; remova essas entradas obsoletas com
crontab -e, porque o cron pode não ter o ambiente de barramento de usuário do systemd e
fazer esse script antigo relatar incorretamente a integridade do gateway.
Se necessário, vincule novamente com channels login.
Login por QR expira atrás de um proxy
Sintoma: openclaw channels login --channel whatsapp falha antes de mostrar um código QR utilizável com status=408 Request Time-out ou uma desconexão de socket TLS.
O login do WhatsApp Web usa o ambiente de proxy padrão do host do gateway (HTTPS_PROXY, HTTP_PROXY, variantes em minúsculas e NO_PROXY). Verifique se o processo do gateway herda o env do proxy e se NO_PROXY não corresponde a mmg.whatsapp.net.
Nenhum listener ativo ao enviar
Envios de saída falham rapidamente quando não existe listener de gateway ativo para a conta de destino.
Certifique-se de que o gateway esteja em execução e que a conta esteja vinculada.
A resposta aparece na transcrição, mas não no WhatsApp
As linhas da transcrição registram o que o agente gerou. A entrega pelo WhatsApp é verificada separadamente: o OpenClaw só trata uma resposta automática como enviada depois que o Baileys retorna um id de mensagem de saída para pelo menos um envio visível de texto ou mídia.
Reações de confirmação são recibos independentes anteriores à resposta. Uma reação bem-sucedida não prova que a resposta posterior de texto ou mídia foi aceita pelo WhatsApp.
Verifique os logs do gateway por auto-reply delivery failed ou auto-reply was not accepted by WhatsApp provider.
Mensagens de grupo ignoradas inesperadamente
Verifique nesta ordem:
groupPolicygroupAllowFrom/allowFrom- entradas da lista de permissões
groups - controle por menção (
requireMention+ padrões de menção) - chaves duplicadas em
openclaw.json(JSON5): entradas posteriores substituem as anteriores, então mantenha um únicogroupPolicypor escopo
Se channels.whatsapp.groups estiver presente, o WhatsApp ainda poderá observar mensagens de outros grupos, mas o OpenClaw as descarta antes do roteamento de sessão. Adicione o JID do grupo a channels.whatsapp.groups ou adicione groups["*"] para admitir todos os grupos, mantendo a autorização de remetente em groupPolicy e groupAllowFrom.
Aviso do runtime Bun
O runtime do gateway do WhatsApp deve usar Node. Bun é sinalizado como incompatível para operação estável do gateway WhatsApp/Telegram.
Prompts de sistema
O WhatsApp oferece suporte a prompts de sistema no estilo Telegram para grupos e chats diretos por meio dos mapas groups e direct.
Hierarquia de resolução para mensagens de grupo:
O mapa groups efetivo é determinado primeiro: se a conta define seus próprios groups, ele substitui completamente o mapa groups raiz (sem mesclagem profunda). A consulta do prompt então é executada no mapa único resultante:
- Prompt de sistema específico do grupo (
groups["<groupId>"].systemPrompt): usado quando a entrada específica do grupo existe no mapa e sua chavesystemPromptestá definida. SesystemPromptfor uma string vazia (""), o curinga é suprimido e nenhum prompt de sistema é aplicado. - Prompt de sistema curinga do grupo (
groups["*"].systemPrompt): usado quando a entrada específica do grupo está totalmente ausente do mapa ou quando ela existe, mas não define nenhuma chavesystemPrompt.
Hierarquia de resolução para mensagens diretas:
O mapa direct efetivo é determinado primeiro: se a conta define seu próprio direct, ele substitui completamente o mapa direct raiz (sem mesclagem profunda). A consulta do prompt então é executada no mapa único resultante:
- Prompt de sistema específico do direto (
direct["<peerId>"].systemPrompt): usado quando a entrada específica do par existe no mapa e sua chavesystemPromptestá definida. SesystemPromptfor uma string vazia (""), o curinga é suprimido e nenhum prompt de sistema é aplicado. - Prompt de sistema curinga do direto (
direct["*"].systemPrompt): usado quando a entrada específica do par está totalmente ausente do mapa ou quando ela existe, mas não define nenhuma chavesystemPrompt.
Diferença em relação ao comportamento de várias contas do Telegram: No Telegram, groups raiz é suprimido intencionalmente para todas as contas em uma configuração de várias contas — até mesmo contas que não definem nenhum groups próprio — para impedir que um bot receba mensagens de grupo para grupos aos quais ele não pertence. O WhatsApp não aplica essa proteção: groups raiz e direct raiz são sempre herdados por contas que não definem substituição no nível da conta, independentemente de quantas contas estejam configuradas. Em uma configuração do WhatsApp com várias contas, se você quiser prompts de grupo ou diretos por conta, defina explicitamente o mapa completo em cada conta em vez de depender de padrões no nível raiz.
Comportamento importante:
channels.whatsapp.groupsé tanto um mapa de configuração por grupo quanto a lista de permissões de grupo no nível do chat. No escopo raiz ou da conta,groups["*"]significa "todos os grupos são admitidos" para esse escopo.- Só adicione um
systemPromptde grupo curinga quando você já quiser que esse escopo admita todos os grupos. Se você ainda quiser que apenas um conjunto fixo de IDs de grupo seja elegível, não usegroups["*"]para o padrão do prompt. Em vez disso, repita o prompt em cada entrada de grupo explicitamente permitida. - Admissão de grupo e autorização de remetente são verificações separadas.
groups["*"]amplia o conjunto de grupos que podem chegar ao tratamento de grupos, mas por si só não autoriza todos os remetentes desses grupos. O acesso de remetente ainda é controlado separadamente porchannels.whatsapp.groupPolicyechannels.whatsapp.groupAllowFrom. channels.whatsapp.directnão tem o mesmo efeito colateral para DMs.direct["*"]fornece apenas uma configuração padrão de chat direto depois que uma DM já foi admitida pordmPolicymaisallowFromou regras do armazenamento de pareamento.
Exemplo:
{ channels: { whatsapp: { groups: { // Use only if all groups should be admitted at the root scope. // Applies to all accounts that do not define their own groups map. "*": { systemPrompt: "Default prompt for all groups." }, }, direct: { // Applies to all accounts that do not define their own direct map. "*": { systemPrompt: "Default prompt for all direct chats." }, }, accounts: { work: { groups: { // This account defines its own groups, so root groups are fully // replaced. To keep a wildcard, define "*" explicitly here too. "120363406415684625@g.us": { requireMention: false, systemPrompt: "Focus on project management.", }, // Use only if all groups should be admitted in this account. "*": { systemPrompt: "Default prompt for work groups." }, }, direct: { // This account defines its own direct map, so root direct entries are // fully replaced. To keep a wildcard, define "*" explicitly here too. "+15551234567": { systemPrompt: "Prompt for a specific work direct chat." }, "*": { systemPrompt: "Default prompt for work direct chats." }, }, }, }, }, },}Indicadores da referência de configuração
Referência principal:
Campos de alto sinal do WhatsApp:
- acesso:
dmPolicy,allowFrom,groupPolicy,groupAllowFrom,groups - entrega:
textChunkLimit,chunkMode,mediaMaxMb,sendReadReceipts,ackReaction,reactionLevel - várias contas:
accounts.<id>.enabled,accounts.<id>.authDir, substituições no nível da conta - operações:
configWrites,debounceMs,web.enabled,web.heartbeatSeconds,web.reconnect.*,web.whatsapp.* - comportamento da sessão:
session.dmScope,historyLimit,dmHistoryLimit,dms.<id>.historyLimit - prompts:
groups.<id>.systemPrompt,groups["*"].systemPrompt,direct.<id>.systemPrompt,direct["*"].systemPrompt