Você migrou o OpenClaw para um VPS novo. Tudo subiu: Docker rodando, agente respondendo no terminal, canal WhatsApp conectado com QR code lido. Mandou uma mensagem de teste. Dois tiques azuis — entregue. Resposta do bot: nenhuma. Silêncio.
Esse bug é invisível porque tudo parece funcionar. O WhatsApp confirma entrega, os logs do agente não mostram erro, e o canal aparece como “connected” (conectado). O problema está uma camada abaixo: no formato do número que o Baileys (a biblioteca que conecta o OpenClaw ao WhatsApp) usa internamente.
| Sintoma | Causa | Solução |
|---|---|---|
| Mensagem entregue (dois tiques), bot não responde | Baileys envia JID com 8 dígitos; allowFrom só tem formato de 9 dígitos | Incluir ambos os formatos no allowFrom, ou usar regex de normalização |
O que aconteceu
Dois tiques azuis significam que o servidor do WhatsApp entregou a mensagem ao dispositivo de destino. Não significa que o aplicativo (ou bot) processou essa mensagem. Entrega é protocolo de rede; processamento é lógica de aplicação.
O OpenClaw recebeu a mensagem. Mas antes de processá-la, ele verifica se o remetente está na lista allowFrom (a lista de números autorizados a falar com o bot). Essa verificação usa o JID (o identificador interno que o WhatsApp usa para cada número) — não o número que aparece na tela do celular.
E aqui mora o problema: o JID que o Baileys gera nem sempre corresponde ao formato que você colocou no allowFrom.
Como números brasileiros funcionam no WhatsApp
Números brasileiros de celular têm 9 dígitos locais desde 2012 (o “nono dígito”). Mas o WhatsApp, internamente, às vezes usa o formato antigo de 8 dígitos para a parte do JID. O Baileys herda esse comportamento.
Exemplo com número fictício:
número exibido no celular: +55 11 90000-1234
──────────
9 dígitos locais
formato "moderno" (9 dígitos):
JID = 5511900001234@s.whatsapp.net
──┬─ ──┬──────
│ └─ 9 dígitos (com o 9 na frente)
└─ código país + DDD
formato "legado" (8 dígitos):
JID = 551100001234@s.whatsapp.net
──┬─ ──┬─────
│ └─ 8 dígitos (sem o 9 na frente)
└─ código país + DDD
Qual formato o Baileys usa depende do estado interno da sessão. Uma instância antiga que já tinha o contato salvo pode ter normalizado para 9 dígitos. Uma instância nova — como a que você criou ao migrar de VPS — pode receber o JID legado de 8 dígitos diretamente do servidor do WhatsApp.
Por que funcionava antes
Na VPS antiga, a sessão do Baileys já existia há semanas ou meses. Durante esse tempo, o WhatsApp sincronizou os contatos e normalizou os JIDs para o formato de 9 dígitos. Seu allowFrom tinha 5511900001234 e tudo batia.
Ao migrar, você criou uma sessão nova. Sessão nova = sem histórico de contatos = sem normalização automática. O WhatsApp envia o JID no formato que bem entender — e para números brasileiros, frequentemente é o legado de 8 dígitos.
VPS antiga (sessão madura):
mensagem chega → JID: 5511900001234 → allowFrom match → bot responde
VPS nova (sessão fresca):
mensagem chega → JID: 551100001234 → allowFrom não encontra → descarta
─────────────
8 dígitos — sem o 9
O log do agente não mostra erro porque descartar mensagens de números não autorizados é comportamento esperado. Do ponto de vista do bot, ele fez a coisa certa: ignorou um número desconhecido.
A solução
Opção 1: incluir ambos os formatos
A forma mais direta. No seu config.json (ou equivalente), liste o número com e sem o nono dígito:
{
"allowFrom": [
"5511900001234",
"551100001234",
"5521900005678",
"552100005678"
]
}
Funciona imediatamente, sem dependência de código. Desvantagem: cada número ocupa duas linhas.
Opção 2: normalizar na chegada
Uma função que converte qualquer JID brasileiro para um formato canônico antes da verificação. Assim o allowFrom precisa de uma entrada só por número:
function normalizarJidBR(jid) {
// Remove o sufixo do WhatsApp, ficando só com os dígitos
const numero = jid.replace(/@s\.whatsapp\.net$/, '')
// Padrão brasileiro: 55 + DDD(2) + número
// Se tem 12 dígitos (55 + 2 + 8), é formato legado — insere o 9
if (/^55\d{2}\d{8}$/.test(numero)) {
const pais = numero.slice(0, 2) // "55"
const ddd = numero.slice(2, 4) // "11", "21", etc.
const local = numero.slice(4) // 8 dígitos
return `${pais}${ddd}9${local}` // insere o 9 → 13 dígitos
}
// Já tem 13 dígitos (55 + 2 + 9) ou não é BR — retorna como está
return numero
}
No ponto onde o OpenClaw verifica o allowFrom, normalize antes de comparar:
// Antes (quebra com JID legado):
const autorizado = config.allowFrom.includes(remetente)
// Depois (funciona com qualquer formato):
const remetenteNormalizado = normalizarJidBR(remetente)
const autorizado = config.allowFrom.includes(remetenteNormalizado)
Com essa abordagem, o allowFrom sempre usa o formato de 9 dígitos e a normalização cuida do resto.
Diagnóstico rápido
Se o bot parou de responder após qualquer mudança de infra (migração, reinstalação, troca de número), siga essa árvore:
Bot não responde?
│
▼
openclaw channels status ← canal está "connected"?
│ NÃO → reconectar QR code
▼
openclaw logs --since 1h ← mensagem aparece nos logs?
│ NÃO → problema de rede/firewall
▼
Procure "message received" ← log mostra o JID do remetente?
│ SIM → anote o JID
▼
Compare com allowFrom ← JID bate com alguma entrada?
│ NÃO → problema de formato (este post)
▼
Verifique qtd de dígitos ← 12 dígitos = legado, 13 = moderno
Troubleshooting
O problema só acontece com números brasileiros? Sim. A dualidade 8/9 dígitos é específica do Brasil (o “nono dígito” adicionado entre 2012-2016). Números de outros países têm formato fixo e o JID corresponde ao número exibido.
Posso forçar o Baileys a sempre usar 9 dígitos? Não diretamente. O formato do JID vem do servidor do WhatsApp durante o handshake da sessão. O Baileys repassa o que recebe. A normalização precisa acontecer no seu código, não na biblioteca.
Isso pode acontecer de novo sem migração? Pode. Qualquer evento que recrie a sessão do Baileys — logout/login, corrupção do arquivo de sessão, atualização do Baileys que limpa cache — pode mudar o formato do JID. A normalização (opção 2) é a solução definitiva porque não depende do estado da sessão.
Próximo passo
- Como instalar o OpenClaw no WhatsApp (passo a passo) — se você ainda não conectou o canal
- OpenClaw 24/7 na Hostinger VPS: guia completo — setup completo de VPS com Docker e SSH
- Segurança no OpenClaw: 5 regras para não vazar suas chaves de API — proteja o agente antes de expor ao WhatsApp
- Cron Jobs no OpenClaw: por que param de rodar e como resolver — outro bug silencioso comum em produção