Todo webhook entregado por Waspy comparte el mismo envelope:
Headers HTTP en cada delivery:
message.received
Llega cada vez que un contacto te envía un mensaje (texto, media, ubicación, etc).
Para mensajes con media (imagen, audio, video, documento), mediaId y mediaKey se completan cuando termina la descarga interna desde Meta. Resolvé mediaId a una URL firmada con GET /media/:id. Ver Media.
message.status_changed
Llega cuando cambia el estado de un mensaje saliente que vos enviaste.
Ciclo de estados: queued → sent → delivered → read o failed.
clientRef se devuelve verbatim si lo enviaste al crear el mensaje (en POST /messages o POST /messages/batch). Es la forma recomendada de reconciliar envíos masivos contra tus propios IDs sin guardar un mapping: matcheás data.clientRef y aplicás data.newStatus. Si no enviaste clientRef, llega como null.
Cuando un mensaje rebota (newStatus: "failed"), el motivo viene en data.errorCode (código de Meta, ej. 131049, 131026) y data.errorMessage.
Los eventos pueden llegar fuera de orden (raro, pero posible). No asumas la secuencia sent → delivered → read: por cada clientRef/id quedate con el estado más avanzado (read > delivered > sent) y tratá failed como terminal.
conversation.created
Llega cuando se crea una conversación nueva (primer mensaje de un contacto).
Llega cuando se crea un contacto nuevo (vía API o porque escribió por primera vez).
Idempotencia y orden
- Un mismo evento puede entregarse más de una vez (por ejemplo si tu URL responde 200 pero la conexión se corta antes de que Waspy lo registre). Deduplicá por
data.id + event.
- Para
message.received y conversation.created, contact.created se entrega primero (cuando aplica).
- No garantizamos orden estricto entre suscripciones distintas.