21. Identificadores e Correlação de Eventos#
Está seção explica como JIDs e números de telefone fluem pelo sistema, e como correlacionar eventos a conversas e mensagens.
Glossario de Identificadores#
| Termo | Formato | Exemplo | O que e |
|---|---|---|---|
| Phone JID | <phone>@s.whatsapp.net |
554196332719@s.whatsapp.net |
Identificador de contato individual |
| RemoteJID | Phone JID | — | Campo no banco que identifica a conversa |
| WhatsAppID | string alfanumerica | 3EB0A1B2C3D4E5F6 |
ID único da mensagem atribuido pelo WhatsApp |
| ExternalID | UUID v4 | a1b2c3d4-e5f6-... |
ID da mensagem na API Catcher (exposto em message_ids) |
| InstanceID | UUID v4 | 84c2e480-... |
Qual instância WhatsApp (número conectado) |
| SenderJID | Phone JID | 554196332719@s.whatsapp.net |
Quem enviou a mensagem |
Normalizacao automática#
A API normaliza automaticamente os identificadores:
- BR 13→12 digitos: Números brasileiros com 13 digitos (
55XX9XXXXXXXX) são normalizados para 12 digitos (55XXXXXXXXXX), removendo o 9 extra. Isso e aplicado em todas as direcoes (inbound e outbound). - Formato consistente: O campo
chatem todos os eventos e identico ao camporemote_jidno banco. Você pode agrupar eventos em conversas usandoinstance_id + chat.
O campo phone sempre traz o número puro (sem sufixo) e o message_ids sempre traz o UUID Catcher da mensagem.
Modelo de dados da mensagem#
A tabela messages no banco de cada tenant armazena todas as mensagens (inbound e outbound):
| Campo | Tipo | Descricao |
|---|---|---|
id (UUID) |
UUID | ID público na API (exposto como elemento de message_ids nos eventos) |
instance_id |
string | Qual instância WhatsApp |
direction |
string | "inbound" ou "outbound" |
remote_jid |
string | A conversa. Phone JID (<phone>@s.whatsapp.net) |
sender_jid |
string | Quem enviou. Phone JID do remetente |
message_type |
string | text, image, video, audio, document, sticker, location, contact, reaction |
content |
string | Texto ou caption |
status |
string | queued → sent → delivered → read / failed |
whatsapp_id |
string | ID da mensagem no WhatsApp (chave de correlação para status updates) |
source |
string | "api" (fila Catcher), "external" (enviado por outra origem no mesmo número) |
media_id |
string | Referência a mídia no S3 |
Não existe tabela
Chat. Conversas são derivadas agrupando mensagens porremote_jid. O endpointGET /v1/instances/{instanceId}/chatsfaz isso automaticamente.
Correlação: como agrupar eventos em conversas#
Chave primaria da conversa: instance_id + campo chat do evento (ou remote_jid no banco).
Todos os eventos de mensagem incluem o campo chat, que corresponde exatamente ao remote_jid no banco:
| Evento | Campo de conversa | Campo de mensagem (UUID Catcher) |
|---|---|---|
message.received |
chat |
message_ids (array) |
message.sent |
chat |
message_ids (array) |
message.delivered |
chat |
message_ids (array) |
message.read |
chat |
message_ids (array) |
message.played |
chat |
message_ids (array) |
Padronizacao: todos os eventos de mensagem usam
message_ids(array). Para a maioria, o array tem exatamente 1 elemento; apenasmessage.delivered,message.reademessage.playedpodem trazer multiplos quando o WhatsApp agrega confirmacoes em batch. Consumers leemevent.data.message_ids[0]na maioria dos casos e iteram o array nos eventos de status.
Correlação: como rastrear o lifecycle de uma mensagem#
O ciclo de vida de uma mensagem outbound e rastreado pelo message_ids[0] (UUID do Catcher):
message.sent (message_ids = ["550e8400-e29b-41d4-a716-..."])
↓
message.delivered (message_ids = ["550e8400-e29b-41d4-a716-..."])
↓
message.read (message_ids = ["550e8400-e29b-41d4-a716-..."])
↓
message.played (message_ids = ["550e8400-e29b-41d4-a716-..."])
No banco, os timestamps são atualizados conforme os eventos chegam:
queued_at → sent_at → delivered_at → read_at → played_at
message_ids — UUIDs do Catcher#
O campo message_ids em todos os eventos de mensagem contem um array de UUIDs internos do Catcher (v4, 36 chars cada). Este identificador e:
- Garantido único — nunca reciclado, mesmo quando o WhatsApp reutiliza IDs
- Estável — o mesmo UUID persiste em todos os eventos do ciclo de vida da mensagem (received → delivered → read → played)
- Aceito nos endpoints da API — os endpoints que operam sobre uma mensagem (react, mark-read) aceitam tanto o UUID do Catcher quanto o ID do WhatsApp (hex)
Para a maioria dos eventos (message.received, message.sent), o array tem exatamente 1 elemento — leia event.data.message_ids[0]. Apenas message.delivered, message.read e message.played podem trazer multiplos elementos quando o WhatsApp agrega receipts.
O campo whatsapp_message_ids aparece nos eventos de mensagem como trilha forense: ele carrega o(s) ID(s) bruto(s) do WhatsApp. Para operações da API e integrações de negócio, continue usando message_ids.
Endpoints de busca por identificador#
| Preciso de... | Endpoint | Parametro |
|---|---|---|
| Listar conversas | GET /v1/instances/{id}/chats |
— |
| Mensagens de uma conversa | GET /v1/instances/{id}/chats/{chatJID}/messages |
chatJID = remote_jid = chat dos eventos |
| Uma mensagem especifica | GET /v1/instances/{id}/message/{messageId} |
messageId = UUID do BiaZap (elemento de message_ids do evento) ou ID do WhatsApp (hex) |
| Mídias de uma conversa | GET /v1/instances/{id}/media?remote_jid={chatJID} |
remote_jid = chat dos eventos |