Códigos de estado DLR: estados de mensagem SMPP e o que realmente afirmam
Os recibos de entrega são o mais próximo de uma verdade absoluta que uma stack de SMS lhe dá - e mesmo assim não são a verdade absoluta. Este artigo mapeia os valores message_state do SMPP v3.4 para o que cada um afirma e não afirma, quais estados ainda podem mudar, como o texto do recibo e as famílias de erros de rede se encaixam, e como os tratar em webhooks sem confiar excessivamente num único campo de estado.
Valores message_state do SMPP v3.4: o que cada um afirma
O SMPP v3.4 define um conjunto reduzido de valores message_state usados em recibos de entrega deliver_sm e em respostas query_sm. Trate-os como classificações reportadas pela rede, não como prova forense do comportamento do telemóvel. O mesmo rótulo pode chegar de saltos diferentes com confianças diferentes. Associe sempre o estado ao texto do recibo, a qualquer código de erro de rede e aos seus próprios carimbos de data/hora de submit/done.
ENROUTE afirma que a mensagem foi aceite no caminho de entrega e ainda não está num resultado terminal conhecido do nó que reporta. Não afirma que o telemóvel foi alcançado, que a consulta HLR teve sucesso, ou que a mensagem será eventualmente entregue. DELIVRD ou DELIVERED afirma que um nó a jusante reportou entrega bem-sucedida ao telemóvel ou a um endpoint store-and-forward aceite que a rede trata como entregue. Não afirma leitura pelo utilizador, instalação de app, ou que o seu conteúdo foi apresentado corretamente. EXPIRED afirma que o período de validade terminou sem um relatório de entrega bem-sucedida que a rede considera final. Não afirma que o telemóvel esteve desligado o tempo todo - apenas que o tempo esgotou segundo as regras do caminho.
DELETED afirma que a mensagem foi removida de um centro de mensagens ou fila antes da entrega final, tipicamente por uma ação administrativa ou de limpeza da rede. Não indica quem iniciou a eliminação nem se um telemóvel alguma vez viu o SMS. UNDELIVERABLE afirma que a rede concluiu que a entrega não pode ser concluída nas condições atuais. Não marca permanentemente o MSISDN como inválido em todas as tentativas futuras; as condições mudam. ACCEPTED afirma que a mensagem foi aceite por uma entidade a jusante que não devolverá necessariamente uma entrega clássica ao telemóvel - comum em certos endpoints de aplicação ou semânticas de aceitação intermédia. Não é sinónimo de DELIVERED.
UNKNOWN afirma que o nó que reporta não consegue mapear o resultado para um estado mais específico. Não significa que a mensagem desapareceu sem registos do seu lado; significa que o recibo que recebeu não é informativo. REJECTED afirma que a mensagem foi recusada por uma política de rede ou plataforma antes ou em vez da conclusão normal da tentativa de entrega. Não significa sempre que o número é inválido - conteúdo, originador, débito ou regras de bloqueio podem produzir o mesmo estado consoante o caminho.
As contas SMSRoute incluem créditos de teste gratuitos que comprovam a entrega antes de pagar, e ferramentas de teste de entrega estão disponíveis no painel SMSRoute.
| message_state | Afirma | Não afirma |
|---|---|---|
| ENROUTE | Em trânsito num caminho que reporta | Telemóvel alcançado ou sucesso eventual |
| DELIVERED | Relatório de sucesso a jusante recebido | Recibo de leitura, sucesso de UX ou verdade imutável |
| EXPIRED | Janela de validade terminou sem sucesso | Falha permanente de telemóvel ou número |
| DELETED | Removida do MC/fila antes da entrega final | Identidade do ator ou visibilidade no telemóvel |
| UNDELIVERABLE | O caminho concluiu que a entrega não pode ser concluída agora | Invalidez permanente |
| ACCEPTED | Aceite por um endpoint com semântica DLR não clássica | Entrega ao telemóvel equivalente a DELIVERED |
| UNKNOWN | Sem classificação melhor disponível | Ausência de quaisquer registos de sistema |
| REJECTED | Recusado por política ou regras de encaminhamento | Sempre um MSISDN inválido |
Estados finais versus intermédios
Os estados intermédios ainda podem mudar. ENROUTE é o estado intermédio claro: pode seguir-se depois um DELIVERED, EXPIRED, UNDELIVERABLE, REJECTED, DELETED ou mesmo ACCEPTED. UNKNOWN deve tratar-se operacionalmente como não final, salvo se o contrato upstream disser o contrário; muitas integrações veem UNKNOWN substituído quando chega um recibo mais claro, e algumas nunca recebem atualização.
Estados finais são aqueles para os quais o tratamento deve normalmente parar as retentativas da lógica de submit: DELIVERED, EXPIRED, DELETED, UNDELIVERABLE, REJECTED e tipicamente ACCEPTED quando o caminho usa ACCEPTED como aceitação terminal da aplicação. Final significa final para essa identidade de mensagem nesse caminho, não final para o resultado de negócio. Um DLR DELIVERED ainda pode estar errado; um EXPIRED pode ser seguido de um SMS tardio visível ao utilizador só em configurações avariadas ou multi-caminho, o que deve tratar como sinal de defeito e não como comportamento SMPP esperado.
Desenhe máquinas de estados em torno da correlação do id da mensagem, não da esperança. Se receber ENROUTE, mantenha a linha aberta. Se receber um estado final, feche retentativas de saída para esse id, registe os campos state e err, e só reabra com uma política explícita de conflito de id duplicado sob o seu controlo. Não reverta DELIVERED para ENROUTE porque um segundo recibo parece mais amigável - registe a anomalia.
Convenção de texto dos recibos e famílias de códigos de erro de rede
Muitos recibos deliver_sm de SMSC incorporam um corpo de texto curto segundo uma convenção de estilo ESM de longa data. Os campos aparecem habitualmente como tokens etiquetados: id (o identificador da mensagem tal como o MC o conhece), sub (contagem de submits), dlvrd (contagem de entregues), submit date, done date, stat (estado textual como DELIVRD, EXPIRED, UNDELIV, ACCEPTD, REJECTD) e err (código de erro de rede ou do MC). O parsing deve ser defensivo: espaçamento, zeros à esquerda nas datas e ortografias de stat variam por caminho. Prefira o TLV message_state estruturado quando presente e use stat como corroboração, não como único sinal.
O campo err não é um dicionário universal. Operadoras e hubs comprimem falhas distintas em códigos sobrepostos. Trabalhe com famílias qualitativas em vez de inventar tabelas por operadora. Família de subscritor ausente: a rede não conseguiu localizar o subscritor - desligado, fora de cobertura ou temporariamente desanexado, consoante o hop. Família de memória do terminal: o dispositivo ou o caminho de armazenamento do SIM recusou ou adiou a receção. Família de barramento: barramento de originador, destino, classe de conteúdo ou subscritor impediu a conclusão. Família de falha de encaminhamento: sem rota viável, rede de destino inalcançável a partir dessa interligação, ou formatação de endereço rejeitada antes da entrega profunda. Estas famílias orientam retentativas e mensagens ao utilizador; não justificam mitos codificados de que um único código numérico significa sempre uma causa raiz.
Mapeie famílias para o comportamento do produto com moderação. Resultados de subscritor ausente e memória do terminal justificam frequentemente retentativa limitada e consciente da validade, ou um seguimento mais lento. Barramento e muitas falhas de encaminhamento geralmente não devem ser martelados com reenvios rápidos do mesmo payload. Quando err falta ou é zero e stat indica falha, acredite na classe de falha e retenha o recibo em bruto para escalamento de suporte.
A ferramenta de consulta de códigos de erro da SMSRoute cobre os mesmos estados de forma interativa.
EXPIRED versus REJECTED na prática
EXPIRED e REJECTED são ambos tipicamente finais, mas respondem a perguntas diferentes. EXPIRED significa que a mensagem foi autorizada a tentar dentro de um período de validade e essa janela terminou sem um sucesso que o nó de reporte aceite. As causas concentram-se em indisponibilidade do terminal, entrega diferida que nunca se desbloqueou, ou latência do caminho além do TTL definido por si ou pelo MC. REJECTED significa recusa - política, triagem, tratamento de endereço inválido ou não encaminhável no hop que rejeita, bloqueio comercial ou negação semelhante imediata ou quase imediata - em vez de um simples esgotamento do tempo.
Nos handlers, EXPIRED convida à inspeção da configuração do período de validade, hora de submit versus hora de done, e se ENROUTE persistiu até ao timeout. REJECTED convida à inspeção do formato do destino (E.164 até 15 dígitos), permissões do originador, regras de conteúdo e se a rejeição ocorreu imediatamente após o submit. Um REJECTED imediato com latência quase nula é uma história operacional diferente de um ENROUTE longo que se torna EXPIRED no limite da validade. Nenhum estado é sinónimo educado do outro; colapsá-los num único booleano de falha deita fora o sinal de retentativa e de conformidade.
Sinais de alerta de DLR falsos
Como os DLR têm valor reputacional, trate recibos implausíveis como incidentes de primeira ordem. Sinais de alerta incluem DELIVERED uniforme em grandes conjuntos mistos de destinos sem variação nas famílias de resultado que sabe que deveriam aparecer no tráfego real, e latência implausível — datas de conclusão iguais ou dentro do ruído de medição do submit com sucesso perfeito, ou latências fixas que não mudam com a região de destino ou a hora do dia. Outro sinal é texto de stat que nunca discorda de um err sempre a zero em rotas propensas a falhas, ou ids de mensagem que não correlacionam com as suas respostas de submit.
Quando surgirem sinais de alerta, congele assunções automatizadas que equacionam DELIVERED com alcançabilidade do utilizador, retenha PDUs ou payloads de webhook em bruto e verifique com remetentes controlados que opera. As contas SMSRoute incluem créditos de teste gratuitos que provam a entrega antes de pagar, e ferramentas de teste de entrega estão disponíveis no dashboard da SMSRoute. Use-as para estabelecer uma linha de base de mistura realista de estados e temporização antes de confiar numa nova rota na lógica de produção.
O guia de DLR da SMSRoute explica a mecânica de webhook por onde estes estados chegam.
Como usar isto em handlers de webhook
Estruture o webhook como um correlacionador, não como um comutador de campo único. Baseie-se no message id do fornecedor devolvido no submit; armazene os timestamps de submit; ingira message_state ou stat, err e done date; depois transicione o seu registo interno com uma máquina de estados explícita. Aceite HTTP 200 apenas após persistência duradoura do recibo para evitar que as retentativas do fornecedor dupliquem efeitos secundários; responda com HTTP 429 ou HTTP 500 apenas quando precisar genuinamente de uma retentativa, e mantenha esses caminhos idempotentes.
Normalize os estados de entrada no seu próprio enum que preserve as distinções SMPP - no mínimo separe delivered, expired, rejected, undeliverable, accepted, deleted, enroute e unknown. Associe etiquetas de família de erro de forma qualitativa sem reivindicar dicionários oficiais de operadoras que não mantém. Para ENROUTE e UNKNOWN não resolvido, agende observação, não sucesso visível ao utilizador. Para DELIVERED, marque sucesso de transporte e continue a condicionar ações críticas de negócio nos seus próprios reconhecimentos de aplicação onde o domínio o exija.
Por fim, registe o p50 e o p95 da latência submit-to-done por classe de rota para que padrões de DLR falsos ou degradados apareçam como desvios de distribuição em vez de anedotas. Tenha em mente a disciplina do tamanho do payload no momento do envio - as regras de segmentação 160/153 GSM-7 e 70/67 UCS-2 ainda moldam como as divisões e falhas parciais aparecem a jusante - mas não invente percentagens de entrega. A incerteza faz parte da superfície do protocolo; os handlers precisos registam o que foi afirmado, o que não foi, e o que fará a seguir.
Perguntas frequentes
- Quais são os valores message_state do SMPP v3.4 e quais são finais?
- O conjunto v3.4 inclui ENROUTE, DELIVERED, EXPIRED, DELETED, UNDELIVERABLE, ACCEPTED, UNKNOWN e REJECTED. ENROUTE é intermédio e ainda pode mudar; UNKNOWN é operacionalmente não final a menos que o seu contrato a montante diga o contrário. DELIVERED, EXPIRED, DELETED, UNDELIVERABLE, REJECTED e tipicamente ACCEPTED são tratados como finais para esse message id nesse caminho.
- Em que difere EXPIRED de REJECTED num DLR de SMS?
- EXPIRED significa que o período de validade esgotou sem um sucesso que o nó de reporte aceite depois de a mensagem ter sido autorizada a tentar a entrega. REJECTED significa que a mensagem foi recusada sob regras de política, encaminhamento ou filtragem em vez de expirar por tempo. Rejeições imediatas e caminhos longos enroute-depois-expired não devem ser colapsados num único balde de falha se se preocupar com retentativas e correções de configuração.
- Que campos aparecem no corpo de texto clássico de um recibo de entrega SMPP?
- Os tokens etiquetados comuns incluem id, sub, dlvrd, submit date, done date, stat e err. Use message_state estruturado quando disponível e trate stat/err como corroboração; os códigos err devem ser agrupados em famílias qualitativas como subscritor ausente, memória do terminal, barramento e falhas de encaminhamento em vez de serem confiados como uma tabela universal por operadora.