whatsmeow-gateway multi-instância runtime Go, 1 binário navegador headless nenhum webhook HMAC ROI Labs

Gateway de WhatsApp sobre a whatsmeow

Várias contas, uma API.

Cada cliente do CRM tem o próprio número pareado. O gateway segura todas as sessões no mesmo processo e entrega uma API HTTP igual para todas.

Sem Chrome headless segurando uma aba por conta, sem sessão única que derruba todo mundo quando cai. É a biblioteca whatsmeow falando o protocolo multi-device direto, num binário Go que sobe em qualquer lugar.

Instâncias · organização roilabs limite por org · 5
Todo evento recebido vira um POST assinado para o CRM. eventos entregues: 0

Ciclo de vida

Do QR ao primeiro evento

Uma instância é criada vazia e sobe sozinha até ficar utilizável. Cada estado é consultável em GET /instances/:id/status, então quem chama nunca precisa adivinhar.

  1. Criada

    POST /instances reserva a instância e checa o teto por organização antes de alocar qualquer coisa.

  2. QR disponível

    GET /instances/:id/qr devolve o código a ser lido no celular. O par é feito uma vez; a sessão persiste no Postgres.

  3. Sincronizando

    Contatos e grupos entram em segundo plano. GET /sync/status mostra o progresso em vez de deixar a chamada pendurada.

  4. Online

    A instância envia, recebe e reage. Se cair, POST /instances/:id/restart reconecta sem novo pareamento.

API

O que dá para fazer com uma instância

Tudo passa por uma API key no header. As rotas de instância são as mesmas para uma conta ou para cinquenta.

RotaMétodoPara quê
/instancesPOSTCria uma instância, respeitando o teto da organização.
/instances/:id/qrGETQR de pareamento.
/instances/:id/statusGETEstado da conexão, sem adivinhação.
/messages/textPOSTEnvia texto.
/messages/mediaPOSTEnvia mídia por upload, com o mimetype lido do próprio arquivo.
/messages/readPOSTMarca como lida.
/messages/reactionPOSTReage a uma mensagem.
/contacts · /groupsGETO que veio da sincronização, incluindo dados de grupo e foto de perfil.
/health · /metricsGETHealth check e métricas para o monitoramento.

Detalhes que doem

Três coisas que só aparecem em produção

Nenhuma delas é visível num teste com um número só. As três estão no código porque apareceram com tráfego real.

LID → PN

O WhatsApp passou a entregar identificadores @lid em vez do número em @s.whatsapp.net.

O gateway resolve o LID para o número canônico antes de repassar — e, quando não consegue, loga e devolve o original em vez de inventar um contato novo.

IDs monotônicos

Evento de mensagem chega fora de ordem e sem chave estável entre instâncias.

Cada evento recebe um ID snowflake gerado no gateway, então ordenar e deduplicar do lado do CRM não depende de nada que venha de fora.

Buffer na entrega

Rajada de mensagens não pode virar rajada de POST no CRM.

Os eventos passam por um buffer antes de sair, e o webhook vai assinado com HMAC usando CRM_WEBHOOK_SECRET — quem recebe consegue provar a origem.

Rodar

Um Postgres e seis variáveis

A sessão de cada instância vive no banco, não em disco local — por isso o container pode ser recriado sem pedir QR de novo.

PORT=8080
API_KEY=sua-chave
DATABASE_URL=postgres://postgres:postgres@localhost:5432/whatsmeow?sslmode=disable
CRM_WEBHOOK_URL=https://sirius.roilabs.com.br/api/webhooks/whatsmeow
CRM_WEBHOOK_SECRET=segredo-do-hmac
LOG_LEVEL=info

# subir
docker compose up -d
Ler o código no GitHub