Responda rápido
Responda2xx em até 10 segundos e faça o trabalho de verdade depois — coloque o
evento numa fila sua e retorne. Um endpoint lento estoura o tempo, é reentregue e
recebe o mesmo evento de novo.
Deduplique
A entrega é at-least-once: o mesmo evento pode chegar mais de uma vez. O jeito mais simples de deixar isso inofensivo é guardar as mensagens pelomessageId e
sempre gravar com upsert.
Mensagens
data.text ?? null vira NULL na sua tabela, e if (data.quotedMessageId) diz se a
mensagem é uma resposta. O sender só existe quando outra pessoa escreveu: com
fromMe true não há sender, então data.sender?.phone é a leitura segura.
Status
messageIds e status: a conversa e o destinatário vêm do
MESSAGE.SENT da mesma mensagem, que já está na sua tabela.
Use upsert aqui também, não UPDATE: um DELIVERED pode chegar antes do
MESSAGE.SENT da mesma mensagem, e até antes de o seu sistema guardar a resposta do
envio. Um UPDATE não encontraria a linha e perderia o status.
O rank faz o status só avançar: um DELIVERED repetido, ou um DELIVERED que chega
depois do READ, não muda nada.
Pelo id do evento
Todo evento também tem um id (o header
webhook-id) que é idêntico em toda reentrega. Para deduplicar de forma genérica —
por exemplo, antes de colocar os eventos na sua fila — guarde os ids processados por
24 horas e descarte os repetidos.
O id identifica o evento, não a mensagem: o DELIVERED e o READ da mesma
mensagem têm ids diferentes. Não use o messageId para descartar eventos, ou você
vai descartar status.
Ordem
Não há garantia de ordem. Mensagens enviadas em rajada (várias fotos de uma vez) e eventos reentregues depois de uma falha podem chegar fora de ordem.- Para ordenar mensagens, use o
timestamp. - Status só avançam (
MESSAGE.SENT→DELIVERED→READ): ignore um status anterior ao que você já tem, como no upsert acima.
Grupos
chat.typeéGROUP,chat.ididentifica o grupo (…@g.us) esenderé o participante que escreveu. As suas próprias mensagens no grupo vêm comfromMe: truee semsender.- Um status significa que a mensagem chegou a ele para pelo menos um participante: o
READé “alguém leu”, não “todos leram”. ODELIVEREDe oREADchegam uma vez cada por mensagem, não uma vez por participante.
Filtrando
Para não receber mensagens de grupo ou status de jeito nenhum, ligue
ignoreGroups ou ignoreStatus nas configurações da instância:
Conexão
Se você monta a sua própria tela de pareamento: mostre o QR Code de cada
QRCODE.UPDATED com status: GENERATED (sempre o mais recente), ofereça tentar de
novo no EXPIRED e feche a tela no CONNECTION.UPDATED com status: CONNECTED.
Envio e duplicatas
Os endpoints de envio devolvem omessageId; é ele que liga o seu envio aos eventos
MESSAGE.SENT e MESSAGE.STATUS_UPDATED que vêm depois. Guarde-o.
A Zapfy não deduplica requisições de envio. Se uma requisição de envio falhar sem
resposta (timeout, conexão caída), repeti-la pode enviar a mensagem duas vezes. Antes
de repetir, confira os eventos MESSAGE.SENT daquela conversa para ver o que de fato
saiu do seu número.