Voltar ao blog Conectividade

Correlação de mensagens A2P SMS: rastreabilidade entre API, SMPP, fornecedores e DLR

Conceba uma cadeia de identificadores e eventos para investigar mensagens A2P SMS através de APIs HTTP, SMPP, fornecedores, tentativas, segmentos e recibos de entrega, sem confundir aceitação com entrega.

Diagrama de rastreabilidade de uma mensagem A2P SMS desde uma API até um DLR

Porque o identificador do fornecedor não é suficiente

Um identificador emitido por um fornecedor é necessário, mas raramente é suficiente para explicar todo o ciclo de vida de um SMS A2P. Normalmente, identifica uma aceitação específica dentro do domínio desse fornecedor. Por si só, não representa o pedido original do cliente, a decisão de rota, uma tentativa posterior, os segmentos de uma mensagem concatenada nem os eventos que possam chegar depois.

O problema surge em operações reais: um pedido pode permanecer em fila, gerar mais do que uma tentativa, mudar de rota segundo uma política interna ou receber um callback tardio. Se o sistema guardar apenas o identificador externo, será difícil responder com precisão ao que foi enviado, à tentativa que produziu um DLR e à parte da evidência que provém de cada sistema.

A regra operacional é manter um identificador interno estável para a mensagem lógica e registar, sem os substituir, os identificadores atribuídos em cada fronteira técnica. O identificador do fornecedor deve ser tratado como uma chave de correlação numa relação mais ampla, e não como a identidade global da mensagem.

  • Não equipare a aceitação pelo fornecedor à entrega no terminal.
  • Não reutilize um ID do fornecedor como ID interno de negócio.
  • Não assuma que dois fornecedores utilizarão o mesmo formato, âmbito ou duração para os seus identificadores.
  • Conserve as respostas e os eventos originais juntamente com a respetiva interpretação normalizada.
Porque o identificador do fornecedor não é suficiente

Mapa da cadeia de rastreabilidade

A rastreabilidade deve modelar estados e eventos, não apenas uma tabela final de estados. Uma cadeia mínima começa com o pedido recebido do cliente, continua com a respetiva validação e entrada em fila e regista cada tentativa de envio criada pelo sistema. Para cada tentativa aceite por um fornecedor, adiciona-se o identificador devolvido por esse fornecedor. Os DLR e callbacks posteriores são armazenados como eventos separados.

Esta abordagem evita uma perda comum de contexto: substituir o estado anterior pelo último evento recebido. Um DLR é evidência de um evento posterior; não substitui a evidência de que foi recebido um pedido, de que foi criada uma tentativa ou de que um fornecedor respondeu à apresentação.

Um mapa prático pode seguir esta sequência: pedido do cliente, mensagem lógica interna, decisão de encaminhamento, tentativa de envio, apresentação HTTP ou SMPP, aceitação ou erro do fornecedor e eventos de estado posteriores. Quando existir segmentação, cada segmento deve ficar associado à mensagem lógica e, quando aplicável, à tentativa que o gerou.

  • Pedido do cliente: regista a referência do cliente, se existir, e o momento de receção.
  • Mensagem lógica: representa a intenção de enviar um conteúdo para um destino.
  • Tentativa: representa uma apresentação específica por uma determinada rota ou fornecedor.
  • Aceitação do fornecedor: regista o ID externo e a resposta recebida.
  • Evento DLR ou callback: preserva o payload original, o momento de receção e a associação resultante.
  • Estado derivado: deve poder ser reconstruído a partir dos eventos, sem os substituir.
Mapa da cadeia de rastreabilidade

Modelo de identificadores recomendado

Um esquema robusto separa os identificadores por função e âmbito. O correlation ID liga o pedido inicial ao processamento interno. A idempotency key protege contra duplicados do mesmo pedido do cliente. O message ID interno identifica a mensagem lógica. O attempt ID identifica cada apresentação específica. O provider message ID regista o identificador que um fornecedor devolve para uma aceitação específica.

Estas chaves não são intermutáveis. Em particular, uma nova tentativa não deve receber o mesmo attempt ID, embora represente a mesma mensagem lógica. Do mesmo modo, dois pedidos repetidos não devem criar mensagens lógicas diferentes se for reconhecida a mesma idempotency key válida dentro da política definida pela plataforma.

Gere IDs internos com unicidade suficiente e mantenha-os opacos para clientes externos, salvo se o contrato de integração estabelecer o contrário. A estrutura do ID não deve revelar números de telefone, conteúdo, fornecedor, rota nem informação operacional sensível.

  • correlation ID: criado ao receber a operação ou o contexto de negócio; liga sistemas internos e registos relacionados.
  • idempotency key: fornecida pelo cliente ou definida pela integração; deteta repetições da mesma operação.
  • message ID interno: criado ao aceitar a mensagem lógica no sistema próprio; mantém-se estável durante o seu ciclo de vida.
  • attempt ID: criado para cada tentativa de apresentação; muda a cada nova tentativa ou alteração de rota.
  • provider message ID: recebido após a aceitação de uma tentativa pelo fornecedor; pode ter um formato opaco e específico do fornecedor.
  • event ID: criado ao ingerir cada callback, DLR ou resultado de consulta; permite desduplicar e auditar eventos.

O que cada parte deve criar e o que não deve ser reutilizado

O cliente pode fornecer uma idempotency key ou uma referência de negócio. A plataforma deve criar os seus próprios IDs de correlação, mensagem, tentativa e evento. Cada fornecedor pode devolver o seu próprio identificador de mensagem. Esta distribuição permite manter responsabilidades claras e evita que uma chave de âmbito limitado se transforme indevidamente numa chave universal.

Não reutilize uma idempotency key como message ID, nem um message ID interno como attempt ID. Também não transforme um provider message ID numa referência de cliente. Estas reutilizações parecem simplificar o modelo inicialmente, mas impedem a representação de novas tentativas, migrações de rota e discrepâncias entre sistemas.

Se uma integração HTTP permitir adicionar parâmetros próprios ao URL de callback, estes podem servir como uma pista adicional de associação. Ainda assim, não substituem o ID nativo do fornecedor nem justificam ignorar a validação da origem, o registo completo do evento e a reconciliação posterior.

  • Um pedido repetido pode partilhar uma idempotency key, mas não deve produzir duas mensagens lógicas se a política o reconhecer como duplicado.
  • Uma mensagem lógica pode ter muitas tentativas.
  • Cada tentativa pode receber zero, um ou mais identificadores externos, consoante a interface e os eventos disponíveis.
  • Um callback recebido não deve gerar automaticamente uma nova mensagem quando a sua referência for desconhecida.
  • A associação deve registar o método e o nível de confiança: exata, provável ou não resolvida.

Relações um para um e um para muitos: mensagens, segmentos, tentativas, rotas e DLR

A mensagem lógica é a entidade central, mas nem sempre corresponde a uma única apresentação nem a uma única unidade técnica de SMS. Um conteúdo concatenado pode ser dividido em vários segmentos. A mesma mensagem pode gerar várias tentativas. Cada tentativa pode seguir uma rota diferente e produzir eventos posteriores separados.

Modele explicitamente estas relações. Uma mensagem lógica pode ter um ou vários segmentos; cada segmento pode exigir o seu próprio resultado técnico. Uma mensagem lógica pode ter uma ou várias tentativas, enquanto uma tentativa deve pertencer a uma única mensagem lógica. Uma tentativa pode ter uma decisão de rota registada e um ou vários eventos de fornecedor ou DLR associados.

Em SMPP, as mensagens concatenadas podem ser relacionadas através de sar_msg_ref_num, sar_total_segments e sar_segment_seqnum. A referência SAR é gerada pelo originador para permitir a reassemblagem. É útil preservá-la como atributo técnico de segmentação, mas não deve substituir o message ID interno da plataforma.

  • Mensagem lógica para segmentos: um para muitos.
  • Mensagem lógica para tentativas: um para muitos.
  • Tentativa para fornecedor ou rota: normalmente um para um por apresentação, embora o histórico de decisões deva ser preservado.
  • Tentativa para eventos: um para muitos.
  • Segmento para DLR: pode ser um para muitos quando existem eventos repetidos, alterações de estado ou evidência recebida por mais do que um canal.

HTTP e SMPP: diferenças práticas de correlação

Numa API HTTP, o fornecedor responde geralmente com um identificador de recurso ou de mensagem. Convém guardá-lo juntamente com a resposta inicial, o timestamp e o estado inicial. Os callbacks posteriores devem ser associados primeiro através desse identificador nativo, quando presente. Se o fornecedor disponibilizar uma consulta do recurso, esta serve para reconciliar callbacks em falta ou estados não finais.

Em SMPP, o sequence_number correlaciona uma PDU de pedido com a resposta associada dentro de uma sessão assíncrona. É atribuído pelo originador da PDU, incrementado de forma monotónica e a resposta associada preserva esse valor. É, portanto, uma referência de transporte de curta duração e não um identificador permanente da mensagem entre sistemas ou fornecedores.

A resposta submit_sm_resp pode devolver um message_id atribuído pelo SMSC. Esse ID é opaco e pertence ao domínio do SMSC. Num DLR, o TLV receipted_message_id identifica a mensagem objeto do recibo através do mesmo ID opaco devolvido ao aceitar a apresentação original. Guarde tanto o valor original como o DLR completo para demonstrar como foi realizada a associação.

Para pedir DLR em SMPP, utiliza-se registered_delivery em submit_sm ou data_sm. A norma prevê solicitar o resultado final de sucesso ou falha, ou apenas a falha final. O pedido de um recibo não garante que um evento chegue, que tenha um formato uniforme nem que prove a receção independente no terminal.

  • HTTP: associe a resposta de criação, o ID nativo e cada callback à tentativa correspondente.
  • SMPP sequence_number: utilize-o para pedido-resposta na sessão, nunca como identificador persistente de negócio.
  • SMPP message_id: armazene-o como ID externo atribuído a uma apresentação aceite.
  • SMPP receipted_message_id: utilize-o como chave principal de associação de DLR quando estiver presente e corresponder.
  • SMPP user_message_reference: pode ajudar se for propagado, mas é um TLV opcional; não conceba uma garantia com base na sua presença.
  • DLR dentro de short_message: não presuma um formato universal; a especificação SMPP indica que pode ser específico do fornecedor.

Campos operacionais que convém registar

Os identificadores explicam que objetos estão relacionados; os metadados explicam o que aconteceu e em que condições. Registe timestamps separados para receção do pedido, criação da mensagem, criação da tentativa, envio para o fornecedor, resposta do fornecedor, receção do callback e atualização derivada. Evite utilizar um único campo de data para todas estas etapas.

Conserve o destino numa representação normalizada e separada das referências operacionais. Para SMS, E.164 é uma referência útil para a normalização internacional de números. Ainda assim, um número normalizado não deve ser utilizado como chave exclusiva de correlação: várias mensagens podem ser dirigidas ao mesmo destino e os dados de destino são potencialmente pessoais.

Registe remetente, codificação, comprimento e número de segmentos, configuração de DLR solicitada, interface utilizada, resultado da validação e uma versão da política de rota aplicada. A versão da política permite explicar uma decisão histórica sem a inferir a partir da configuração atual.

  • Timestamps com fuso horário e fonte de relógio claramente definidos.
  • Destino normalizado e protegido como dado potencialmente pessoal.
  • Remetente utilizado na apresentação, sem assumir que identifica o remetente real.
  • Codificação, tamanho e segmentação efetiva.
  • Canal e interface: HTTP, SMPP ou outro adaptador interno.
  • Rota ou fornecedor selecionado e versão da política de encaminhamento.
  • Pedido de DLR, resposta de aceitação, código de erro e payload original do evento.
  • Método de associação e nível de certeza.

Callbacks duplicados, fora de ordem ou sem referência reconhecível

Os callbacks são eventos assíncronos. Podem chegar duplicados, fora de ordem, com campos adicionais ou sem a referência esperada. O desenho correto não consiste em confiar na ordem de chegada, mas em preservar cada evento e calcular um estado derivado através de regras explícitas.

Para desduplicar, calcule uma impressão digital do payload original e combine, sempre que possível, fornecedor, identificador externo, tipo de evento, estado reportado e timestamp de receção. A desduplicação deve assinalar eventos equivalentes sem apagar a evidência recebida. Se dois eventos tiverem a mesma referência, mas dados diferentes, preserve-os como registos distintos e registe a discrepância.

Quando uma referência não for reconhecida, armazene o evento numa área de quarentena ou de não associados. Não crie uma relação baseada apenas em correspondências de destino, hora ou conteúdo: estes atributos podem produzir falsos positivos. Aplique associações probabilísticas apenas se a política operacional o permitir, identificando-as como tal e mantendo o evento original inalterado.

Os parâmetros de callback podem variar conforme o canal e o tipo de evento, podendo inclusivamente ser ampliados. Os recetores devem tolerar novos campos e preservar o payload sem exigir que todos os fornecedores utilizem o mesmo esquema.

  • Persistir primeiro o payload original e os respetivos cabeçalhos relevantes.
  • Validar autenticidade e origem de acordo com o mecanismo documentado por cada fornecedor.
  • Desduplicar sem eliminar a evidência original.
  • Não assumir ordem cronológica com base na ordem de receção.
  • Manter eventos não associados para investigação e reconciliação.
  • Não elevar uma associação provável a certeza sem uma referência verificável.
FAQ

Perguntas frequentes

O message_id de SMPP identifica uma mensagem de forma global?

Não. O message_id devolvido em submit_sm_resp é um identificador opaco atribuído pelo SMSC. É útil para correlacionar a apresentação aceite com um DLR quando este inclui receipted_message_id, mas não deve ser tratado como uma referência global entre fornecedores ou plataformas.

Para que serve sequence_number em SMPP?

Serve para correlacionar uma PDU de pedido com a resposta associada dentro de uma sessão SMPP assíncrona. É atribuído pelo originador da PDU e não deve ser utilizado como identificador persistente da mensagem.

Um DLR confirma que o destinatário leu o SMS?

Não. Um DLR informa sobre um estado de entrega comunicado pela cadeia de mensagens. A aceitação por um fornecedor também não equivale à entrega no terminal. Deve ser documentado que evento foi recebido, de quem provém e qual é o seu âmbito.

Devo depender de user_message_reference para correlacionar DLR SMPP?

Não como base única do desenho. SMPP prevê user_message_reference como parâmetro opcional e a sua propagação não deve ser garantida. Mantenha sempre o mapeamento entre o attempt ID interno e o message_id devolvido pelo SMSC.

O que faço se chegar um callback sem um identificador conhecido?

Conserve o evento original como não associado, registe a sua origem e aplique reconciliação com o fornecedor sempre que possível. Não crie uma associação definitiva apenas com base no número, hora ou conteúdo, pois poderá ligar mensagens diferentes.

Durante quanto tempo devo conservar os registos de rastreabilidade?

Defina o prazo segundo a finalidade operacional, as obrigações aplicáveis e as políticas de segurança. Aplique minimização, limitação da conservação, controlos de acesso e integridade. Separe os identificadores operacionais dos dados pessoais, como destino, remetente ou conteúdo.

Fontes consultadas

  1. SMPP Protocol Specification v3.4, Issue 1.2SMPP Developers Forum
  2. Messages resourceTwilio
  3. Best Practices for Messaging Delivery Status LoggingTwilio
  4. Outbound Message Status in Status CallbacksTwilio
  5. E.164: The international public telecommunication numbering planInternational Telecommunication Union
  6. A guide to the data protection principlesInformation Commissioner's Office