Aviso de risco: esta integração usa biblioteca não oficial. A Meta proíbe automação não-oficial em seus termos.
Para uso comercial em escala, considere a WhatsApp Cloud API oficial — ou avise seu cliente do risco de banimento por contrato.
Boas práticas obrigatórias
Throttle entre envios.
Já configurado: SEND_THROTTLE_MIN_MS/SEND_THROTTLE_MAX_MS (padrão 2-5s com jitter). Para disparo, eleve para 10-30s.
Aqueça números novos.
Use o número 2+ semanas com tráfego natural (foto, status, conversas reais) antes de qualquer disparo. Volume inicial: 50-100 msg/dia, escalar gradualmente.
Varie o conteúdo.
Mesma mensagem para 100+ destinatários é o sinal nº 1 de spam. Personalize com nome e mude pequenas palavras (use templates com variáveis).
Prefira contatos opt-in.
Reportes de "spam" pelos destinatários é o gatilho mais forte. Só envie pra quem aceitou receber. Lista fria de cold-mailing → ban quase certo.
Respeite horário comercial.
Disparos de madrugada multiplicam reportes. Use 9h-18h, dias úteis.
Evite mensagens só com link/promoção.
Texto curto + URL é detectado pelos filtros do WhatsApp. Acrescente contexto humano antes do link.
Não desligue o celular pareado.
O whatsapp-web.js depende do celular. Manter o aparelho off por dias degrada a sessão.
Reaja a sinais de bloqueio.
Se receber erro Rate limit ou as mensagens pararem de chegar, pare imediatamente e deixe descansar 24h. Insistir = ban definitivo.
Múltiplos números, não um só.
Distribua disparos entre várias sessões (cada uma com seu chip). Concentrar volume em 1 número = ban garantido.
Monitore o delivery rate.
Queda repentina nas confirmações de entrega = você foi shadow-banned. Reduza volume na hora.
Todo envio passa por uma fila Redis (BullMQ). Isso garante ordem, retries automáticos e que mensagens não são perdidas em caso de crash.
Estados do job
waiting
Aguardando worker. Se a sessão estiver desconectada, fica aqui até reconectar.
active
Worker processando o envio agora.
completed
Mensagem entregue ao WhatsApp. Retorna messageId.
failed
Esgotou tentativas (3x com backoff exponencial). Ver no Bull Board.
delayed
Aguardando backoff antes do próximo retry.
Como funciona o aguardando envio
Você chama POST /sessions/:id/send-message → job entra em waiting.
O worker da sessão (1 por sessão, concurrency=1) puxa o próximo job.
Se a sessão estiver connected, o envio acontece. Se não, o job fica em waiting até a sessão reconectar.
Após o envio, o worker dorme entre SEND_THROTTLE_MIN_MS e SEND_THROTTLE_MAX_MS (jitter randômico) antes de pegar o próximo.
Falhas com backoff exponencial (2s, 4s, 8s) e até 3 tentativas. Erros marcados como permanentes (ex: número inválido) não retentam.
Default = fire-and-forget.
Toda chamada enfileira o job e responde 202 com jobId em milissegundos — o throttle anti-ban roda no worker, não na sua chamada HTTP.
Acompanhe o resultado pelo Bull Board ( Filas).
Use wait:true apenas em testes pra bloquear até concluir (limite SEND_JOB_TIMEOUT_MS).
Marcar chat como lido — útil pra esconder o "não-lido" do celular do cliente.
curl -X POST http://localhost:9002/sessions/<ID>/chats/<CHAT_ID>/mark-read \
-H "X-API-Key: $API_KEY"
Verificar assinatura do webhook — quando WEBHOOK_SECRET está setado, todo payload vem com header X-Whatshd-Signature: sha256=<hex>. Compare com HMAC do body pra garantir autenticidade.