Lifecycle webhooks¶
Cuando una instancia tiene events_webhook_url configurado, qrsgen
POSTea cambios de estado a esa URL.
Esquema común¶
{
"instance": "whatsapp-main",
"event": "connected",
"occurred_at": "2026-05-26T11:30:00Z",
"jid": "34650367855:28@s.whatsapp.net"
}
Algunos eventos llevan campos extra (extras). Catálogo completo:
| Event | Descripción | Extras |
|---|---|---|
qr_generated |
Hay un QR nuevo listo en /qr. |
last_qr_msg_id (si lo configuraste vía PATCH) |
paired |
Usuario escaneó. Esperando primer Connected. |
– |
connected |
Sesión activa, listo para enviar/recibir. | – |
reconnected |
Sesión vuelve tras un unreachable. Sólo se emite tras 5s de estabilidad. |
– |
unreachable |
Disconnected silencioso 60s. Si vuelve antes → blip silencioso (no se emite). | – |
disconnected |
Confirmación de desconexión prolongada. | – |
logged_out |
Sesión invalidada server-side. Necesita nuevo QR. | – |
strike |
WhatsApp emitió ConnectFailure o TemporaryBan. Acción inmediata recomendada. | – |
spam_blocked |
El spamguard descartó un outgoing duplicado. | count, preview |
ban_risk |
Detector cruzó un threshold (velocity / diversity / delivery_ratio). | alert, score, level, velocity, diversity, delivery_ratio |
outgoing_expired |
Un mensaje en el outbox no se pudo entregar antes del TTL. | queue_id, remote_jid, preview |
backend_restarting |
Emitido al SIGTERM, antes del shutdown. | – |
backend_started |
Emitido por instancia tras Bootstrap (8s post-boot). |
– |
Comportamiento¶
- Los webhooks salen en goroutines independientes — qrsgen no bloquea cuando el orquestador tarda en responder.
- Si el POST falla (timeout 10s, 4xx, 5xx), se loguea y se sigue (no hay retry queue del lifecycle). Diseño intencional: WhatsApp seguirá emitiendo eventos según evolucione la conexión.
unreachablese emite tras 60s de silencio: blips cortos no generan ruido en el panel del agente.reconnectedse emite tras 5s de estabilidad tras ununreachable: evita flapping.
Idempotencia¶
No hay deduplicación a nivel lifecycle — si el mismo evento se emite dos
veces (por ejemplo, dos transiciones Connected cercanas), tu orquestador
debe ser idempotente. La identidad práctica de un evento es (instance,
event, occurred_at).
Glosario¶
Lifecycle event: notificación HTTP que qrsgen POSTea cuando hay un
cambio relevante en una instancia. La URL destino se configura
per-instancia via el campo events_webhook_url.
Rising-edge alert: alerta que se emite solo cuando se cruza un
umbral (no cuando se sostiene). Usado por ban_risk y spam_blocked
para evitar inundar al integrador.
Grace period: tiempo de espera silencioso tras un evento antes de emitir su pill al usuario. Sirve para filtrar blips cortos (transitorios) y evitar ruido visual.
Blip silencioso: cuando una desconexión se resuelve sola antes de
expirar el grace period (60s para unreachable). qrsgen NO emite pill
en ese caso — el agente humano no se entera.
Stabilize delay: tiempo de espera con la conexión estable antes de
emitir reconnected tras un unreachable. Default 5s. Evita flapping
visual entre connected y disconnected durante reconexiones inestables.
Bootstrap window: ventana de 15s al arrancar el proceso durante la
cual qrsgen suprime los eventos connected (avalancha de reconexión).
En su lugar emite backend_started por instancia al cumplir 8s post-boot.
Strike: evento crítico — WhatsApp tomó una acción sancionatoria
(TemporaryBan o ConnectFailure 4xx). Requiere intervención manual:
puede indicar que el número está siendo penalizado por uso indebido.
Spam blocked: el filtro spamguard descartó un duplicado outgoing.
Lleva count (cuántos van bloqueados en la sesión) y preview del
contenido descartado.
Ban risk: el detector proactivo cruzó al menos un threshold. Lleva
alert (cuál de las 3 señales), score 0-1 y level
(ok/low/moderate/high).
Outgoing expired: un mensaje en el outbox no se entregó antes del
TTL (5 min). qrsgen lo marca como expired y avisa al integrador con
el preview para que decida (notificar agente, re-postear, archivar).
Backend restarting / started: eventos emitidos al SIGTERM (12s antes del shutdown) y tras el bootstrap completo (8s post-boot). El integrador los usa para mostrar pills "buscando conexión" / "conexión restaurada".