Anatomia di una ricevuta di consegna SMPP
Quando inviate un SMS con registered_delivery impostato a 1, l'SMSC rimanda poi una PDU deliver_sm su un bind receiver o transceiver. Il bit 0x04 del suo esm_class la contrassegna come ricevuta di consegna anziché come messaggio in entrata, e il suo short_message porta una ricevuta testuale. L'Appendice B della specifica SMPP v3.4 fornisce questo formato come esempio, e quasi ogni SMSC lo segue: id:IIIIIIIIII sub:SSS dlvrd:DDD submit date:YYMMDDhhmm done date:YYMMDDhhmm stat:DDDDDDD err:E text:….
Poiché l'Appendice B è un esempio e non una regola rigida, le ricevute reali variano: chiavi in minuscolo, spazi aggiuntivi, submit_date con trattino basso, date a 12 cifre con i secondi o text mancante. Questo decodificatore accetta tutte queste varianti e vi dice quali campi mancano.
- id: l'ID del messaggio restituito dall'SMSC in submit_sm_resp. Usatelo per associare la ricevuta al vostro messaggio. L'esempio della specifica mostra 10 caratteri, ma molti SMSC usano ID più lunghi, a volte in esadecimale.
- sub e dlvrd: il numero di messaggi inizialmente inviati e consegnati, su 3 cifre. Contano soprattutto per le liste di distribuzione; per un singolo SMS sono tipicamente 001 e 001 (o 000).
- submit date e done date: quando il messaggio è stato inviato e quando ha raggiunto il suo stato finale, secondo l'orologio dell'SMSC.
- stat: lo stato finale o intermedio, come codice di 7 lettere come DELIVRD.
- err: un codice di errore di 3 caratteri, specifico della rete o dell'SMSC; 000 significa nessun errore.
- text: i primi 20 caratteri del messaggio originale, spesso troncati o vuoti.
- I TLV facoltativi possono ripetere questi dati in forma più pulita: receipted_message_id (0x001E), message_state (0x0427) e network_error_code (0x0423).
Codici stat dei DLR e loro significato
SMPP v3.4 definisce otto stati del messaggio. ENROUTE e ACCEPTD sono intermedi; gli altri sono definitivi. La nostra API normalizza ogni canale in sei stati del webhook (SUBMITTED, SENT, DELIVERED, READ, FAILED, REJECTED), e il decodificatore mostra la corrispondenza più vicina per ogni valore di stat. Considerate quella mappatura indicativa: la regola esatta per il vostro account viene confermata durante l'attivazione (onboarding).
- DELIVRD (message_state 2): consegnato al telefono. Stato del webhook più vicino: DELIVERED.
- ACCEPTD (6): formalmente 'letto manualmente per conto dell'abbonato dal servizio clienti', ma la maggior parte degli SMSC lo invia come ricevuta intermedia 'accettato dalla rete'. Più vicino: SENT.
- ENROUTE (1): ancora in transito, ad esempio in coda per un nuovo tentativo. Più vicino: SENT.
- UNDELIV (5): non consegnabile, ad esempio un numero non valido o inattivo. Più vicino: FAILED.
- EXPIRED (3): il periodo di validità è terminato prima di poter raggiungere il telefono, spesso perché era spento o fuori copertura. Più vicino: FAILED.
- DELETED (4): cancellato prima della consegna, ad esempio con cancel_sm. Più vicino: FAILED.
- REJECTD (8): rifiutato dalla rete o da un firewall, ad esempio per un Sender ID non registrato o contenuti bloccati. Più vicino: REJECTED.
- UNKNOWN (7): l'SMSC non ha uno stato finale. Trattatelo come non confermato, non come un fallimento provato.
Codici err: perché non esiste un elenco universale
Il campo err è largo tre caratteri e la specifica SMPP non ne definisce i valori. 000 significa sempre nessun errore, ma i valori diversi da zero provengono dal fornitore dell'SMSC, dall'operatore o da un aggregatore intermedio. Alcuni SMSC passano le cause di errore GSM MAP (ad esempio, l'errore MAP 1 è abbonato sconosciuto e 27 è abbonato assente), mentre altri mappano tutto sulla propria tabella.
Se la ricevuta porta il TLV network_error_code (0x0423), è più affidabile: il suo primo ottetto indica il tipo di rete (3 significa GSM) e i due successivi il codice di errore. Una ricevuta DELIVRD con un err diverso da zero è incoerente e va segnalata al vostro fornitore; il decodificatore la segnala.
Errori command_status e ricevute di consegna
SMPP segnala i problemi in due momenti. Il command_status in submit_sm_resp arriva in millisecondi e dice se l'SMSC ha accettato la vostra richiesta; 0x00000000 (ESME_ROK) significa accettato, non consegnato. La ricevuta di consegna arriva da secondi a giorni dopo e porta l'esito finale.
I valori di command_status sono definiti nella sezione 5.1.3 di SMPP v3.4. I più comuni in produzione sono 0x00000058 ESME_RTHROTTLED (avete superato i messaggi al secondo concordati: rallentate e riprovate con backoff esponenziale), 0x00000014 ESME_RMSGQFUL (coda piena: rallentate), 0x0000000A e 0x0000000B (indirizzo di origine o destinazione non valido) e 0x0000000D o 0x0000000E (bind fallito o password errata). I valori da 0x00000400 a 0x000004FF sono riservati agli errori specifici del fornitore dell'SMSC, quindi chiedete al vostro fornitore.
Date, fusi orari e latenza di consegna
Le date delle ricevute usano YYMMDDhhmm, e molti SMSC aggiungono i secondi (YYMMDDhhmmss). La ricevuta non porta alcun fuso orario: l'ora è quella dell'orologio dell'SMSC, di solito UTC. Il decodificatore mostra le date esattamente come scritte e calcola la latenza come data di completamento meno data di invio, che non risente del fuso orario finché entrambe provengono dallo stesso orologio.
La latenza è un utile segnale di qualità. Il traffico OTP sano verso un telefono raggiungibile si completa di solito in pochi secondi. Latenze lunghe seguite da EXPIRED indicano telefoni spenti o in roaming, e una data di completamento precedente alla data di invio significa che i due orologi non concordano. Le date al minuto non possono misurare latenze inferiori al minuto, quindi preferite gli SMSC che inviano i secondi.
Gestire le ricevute in modo affidabile in produzione
Rispondete a ogni deliver_sm con deliver_sm_resp, anche se la vostra elaborazione fallisce, altrimenti l'SMSC la reinvia e può limitare il bind. Conservate la ricevuta grezza, poi elaboratela in modo asincrono e idempotente per ID messaggio, perché le ricevute possono arrivare due volte o fuori ordine: un ENROUTE in ritardo non deve mai sovrascrivere un DELIVRD.
Se preferite non analizzare affatto le ricevute, la nostra API SMS REST fornisce le stesse informazioni come stati del webhook normalizzati, e le ricevute mancate possono essere reinviate con POST /sms/resendDlr. I bind SMPP su TLS sono disponibili per i mittenti ad alto volume e per i rivenditori.
