Entrega, reportes DLR y estados
Qué significa realmente 'entregado' y cómo modelar la máquina de estados de un mensaje.
Un DLR (Delivery Receipt) es el acuse que la red genera cuando un mensaje cambia de estado. El proveedor lo recibe del operador vía SMPP y te lo reenvía a tu webhook. Es la única fuente de verdad sobre si el mensaje llegó.
La máquina de estados
Cada proveedor usa nombres ligeramente distintos, pero el modelo es estable. Un mensaje nace queued, pasa a sent cuando sale hacia el operador, y termina en un estado final: delivered, undelivered, failed o expired.
queued ──▶ sent ──▶ delivered
│ ├──▶ undelivered (el operador lo rechazó)
│ └──▶ expired (venció la validez)
└──▶ failed (rechazado antes de salir)Cómo guardar los estados
Persiste cada evento en una tabla de historial y calcula el estado actual como el más avanzado recibido. Así resistes desorden, duplicados y reintentos del webhook.
+const RANK = { queued: 0, sent: 1, delivered: 2, undelivered: 2, failed: 2, expired: 2 };+function onStatus(evt) {− db.messages.update(evt.id, {− status: evt.status,− });+ db.events.insert(evt); // historial completo+ const current = db.messages.get(evt.id);+ if (RANK[evt.status] >= RANK[current.status]) {+ db.messages.update(evt.id, { status: evt.status });+ }}
Códigos de error
Junto al estado, los DLR traen un código de error del operador: número inexistente, terminal bloqueado, spam detectado. Agrúpalos en categorías accionables —permanente o temporal— y deja de enviar a números con errores permanentes repetidos. Tu tasa de entrega y tu reputación con los operadores lo agradecerán.
Una máquina de estados honesta
Modela los estados como una máquina con transiciones permitidas: accepted → sent → delivered, o sent → failed, o sent → expired. Nunca permitas que un estado final retroceda. Los webhooks llegan desordenados con más frecuencia de la que crees, y un sent tardío no debe sobrescribir un delivered que ya registraste.
Cuando no recibes DLR alguno, no asumas éxito ni fracaso: el estado correcto es desconocido. Algunos operadores no reportan acuses para ciertos rangos de numeración, y tu panel debe mostrarlo así en lugar de inflar la tasa de entrega.