Deduplicação em SMS A2P: como evitar mensagens repetidas sem bloquear notificações legítimas
Um guia operacional para distinguir duplicados técnicos, tentativas controladas e mensagens repetidas intencionalmente, com chaves de idempotência, janelas por caso de uso e rastreabilidade auditável.

Que problema a deduplicação resolve e o que não deve fazer
A deduplicação de mensagens SMS A2P reduz envios repetidos resultantes de pedidos duplicados, novas tentativas de rede, eventos concorrentes ou incerteza após uma resposta incompleta de uma API. O seu objetivo não é impedir toda repetição: deve evitar que uma mesma intenção de negócio produza vários SMS indesejados, sem bloquear um reenvio legítimo, um novo alerta ou uma comunicação consentida com um propósito diferente.
O princípio técnico é a idempotência. Uma operação idempotente mantém o mesmo efeito pretendido, mesmo que seja processada uma ou mais vezes. Nas mensagens, isto exige que a aplicação consiga reconhecer que dois pedidos representam a mesma intenção antes de criar dois envios independentes.
Uma desconexão antes de receber a resposta da plataforma não demonstra que o envio não foi criado. Nesse caso, criar outra mensagem sem reconciliar o estado pode causar um duplicado. A política deve manter um identificador de idempotência próprio, persistir esse identificador e usá-lo para consultar ou reconciliar o resultado antes de emitir um segundo envio.
- Não trate a deduplicação como um bloqueio global por número de telefone.
- Não assuma que uma confirmação da API, um estado em fila ou um evento de envio confirma a receção no terminal.
- Aplique a decisão à intenção de negócio e ao estado do ciclo de vida, e não apenas ao texto do SMS.
- Defina exceções explícitas e auditáveis para reenvios solicitados, alterações materiais de conteúdo ou incidentes.

Os três casos que devem ser separados
Uma política útil começa por classificar o motivo da repetição. Os três casos podem parecer iguais no histórico de um destinatário, mas exigem decisões diferentes.
O duplicado técnico ocorre quando a mesma intenção é processada mais de uma vez: por exemplo, dois pedidos concorrentes com a mesma chave, uma nova tentativa após a perda da resposta ou a repetição de um evento proveniente de uma fila. Normalmente, deve ser suprimido se já existir um envio ativo ou criado para a mesma intenção.
A nova tentativa controlada é uma ação deliberada dentro de uma política definida. Pode ser necessária quando o estado anterior indica falha, não entrega ou resultado incerto, mas deve usar a mesma correlação de negócio, os mesmos limites de frequência e as regras de elegibilidade. Não deve ser confundida com a repetição cega de um pedido.
Uma mensagem legitimamente repetida corresponde a um novo propósito, evento, desafio ou autorização. Uma confirmação de encomenda e um alerta posterior sobre uma alteração à encomenda podem ser enviados para o mesmo número e ter texto semelhante, mas não correspondem ao mesmo evento de negócio.
- Duplicado técnico: mesma intenção, mesma chave, repetição indesejada.
- Nova tentativa controlada: mesma intenção, nova ação permitida por uma regra de estado e tempo.
- Repetição legítima: nova intenção ou alteração material verificável.

Conceba uma chave de deduplicação baseada na intenção
A chave deve representar uma unidade concreta de intenção de negócio. O número de destino é necessário, mas não suficiente. Deve ser armazenado e comparado numa representação internacional normalizada de acordo com o plano E.164, evitando que diferenças de formato local, espaços, hífenes ou prefixos produzam chaves diferentes para o mesmo destino.
Como base, uma chave pode combinar destino normalizado, propósito, identificador do evento de negócio, remetente ou perfil de envio e um identificador de correlação. O modelo ou a sua versão pode ser adicionado quando ajudar a distinguir comunicações materialmente diferentes. Em sistemas distribuídos, também é recomendável guardar uma chave de idempotência gerada pela aplicação e estável durante as novas tentativas da mesma operação.
Não use o corpo do SMS como única chave. As mensagens dinâmicas variam consoante valores, datas, nomes ou referências. Na autenticação, o texto pode conter segredos diferentes para a mesma transação ou mensagens semelhantes para desafios diferentes. Dois OTPs com aspeto semelhante não devem ser considerados equivalentes sem conhecer o desafio, a tentativa ou o evento de autenticação a que pertencem.
- Destino normalizado em formato internacional.
- Propósito: autenticação, alerta, confirmação, campanha ou outro domínio definido.
- Identificador do evento: encomenda, incidente, sessão, desafio ou transação.
- Remetente ou perfil de envio, quando fizer parte da intenção.
- Versão do modelo ou classificação de conteúdo, se relevante.
- Identificador de correlação e idempotência persistente.
Aplique janelas temporais por caso de uso, não uma janela universal
A janela de deduplicação é o período durante o qual dois pedidos com a mesma intenção são considerados candidatos a supressão ou reconciliação. Não existe uma duração universal correta: deve ser definida conforme o propósito, o risco, a experiência do utilizador e o ciclo de vida esperado da mensagem.
Em OTPs e outros segredos de autenticação, a política deve estar associada à transação de autenticação e ao segredo específico. Um segredo deve ser aceite apenas uma vez durante a sua validade. O NIST estabelece que uma autenticação fora de banda deve ser considerada inválida se não for concluída no prazo de 10 minutos; esse limite não obriga a que a janela operacional de supressão seja de 10 minutos, mas impede que a autenticação seja tratada como um processo aberto indefinidamente.
Para alertas transacionais, confirmações e comunicações consentidas, a janela deve refletir o evento. Uma confirmação repetida da mesma encomenda pode ser suprimida enquanto o mesmo evento e versão estiverem pendentes ou já processados. No entanto, uma alteração material da encomenda, um novo incidente ou um pedido verificável de reenvio deve ser avaliado como uma nova condição, e não como um duplicado automático.
- OTP: associe a decisão ao desafio e ao segredo, não apenas ao destinatário ou ao texto.
- Alertas: use o identificador do incidente, estado ou evento que originou a notificação.
- Confirmações: diferencie a primeira confirmação de uma alteração posterior do mesmo processo.
- Campanhas consentidas: separe eventos e regras de frequência da deduplicação técnica.
Use estados de decisão e uma máquina de estados
Uma deduplicação segura não se limita a devolver sim ou não. É aconselhável usar estados de decisão explícitos: permitir, suprimir, colocar em revisão e substituir uma mensagem pendente. Cada estado deve ser suportado por uma máquina de estados que distinga, no mínimo, novos pedidos, mensagens pendentes de envio, enviadas, entregues, não entregues, falhadas e de resultado desconhecido.
Permitir significa que não existe uma correspondência equivalente dentro da política aplicável ou que uma exceção autorizada transforma o pedido numa nova intenção. Suprimir significa que já existe uma operação equivalente cujo efeito deve ser preservado. Rever é reservado para conflitos de dados, exceções de alto risco ou resultados ambíguos que não devem ser resolvidos por uma regra automática.
Substituir pendente só pode ser utilizado quando a política permite substituir uma mensagem que ainda não saiu do estado pendente e a plataforma ou arquitetura controla essa transição de forma fiável. Não se deve assumir que uma mensagem já enviada, mesmo que marcada como enviada por um fornecedor, possa ser retirada ou substituída.
- Permitir: nova intenção ou exceção válida.
- Suprimir: mesma intenção dentro da janela e com um estado que impede outro envio.
- Rever: conflito de correlação, dados incompletos ou exceção de risco.
- Substituir pendente: apenas antes do envio efetivo e com controlo do estado.
Resolva concorrência, incerteza e callbacks assíncronos
Dois pedidos idênticos podem chegar ao mesmo tempo a partir de processos diferentes. A proteção deve ocorrer antes da criação de duas mensagens: use uma reserva atómica ou uma restrição de unicidade sobre a chave de deduplicação e a janela aplicável. A operação deve devolver a decisão e a referência ao registo existente, quando aplicável.
Quando uma resposta da API é perdida ou ocorre uma desconexão, mantenha o resultado como incerto. Antes de voltar a enviar, consulte ou reconcilie através da chave de idempotência, do identificador de correlação ou do identificador externo disponível. Se não for possível determinar o resultado, aplique uma regra de risco documentada em vez de assumir que a primeira tentativa falhou.
Os callbacks de estado são eventos assíncronos do ciclo de vida. Podem chegar tarde ou numa ordem diferente da esperada. Devem ser validados de acordo com o mecanismo disponibilizado pela plataforma e processados de forma tolerante a alterações de parâmetros e sequências. Um estado em fila indica aceitação para processamento; um estado enviado também não é uma confirmação uniforme de entrega no terminal. Mesmo um DLR de entrega deve ser interpretado segundo a semântica contratual e técnica da rota, sem ser apresentado como prova independente de leitura pelo utilizador.
- Reserve a chave antes de criar o envio para evitar condições de corrida.
- Mantenha o estado desconhecido quando a resposta for incerta.
- Torne idempotente o processamento de callbacks.
- Não reduza estados terminais com eventos atrasados ou reordenados sem uma regra explícita.
- Diferencie aceitação da API, processamento, envio e entrega reportada.
Registe cada supressão para que possa ser explicada e revista
Uma supressão que não pode ser explicada torna-se um risco operacional. O registo deve permitir reconstruir que pedido foi recebido, com que mensagem ou intenção foi comparado, qual a regra que tomou a decisão e quando expira a janela que impede uma nova criação.
Guarde a chave de idempotência e de deduplicação, os identificadores de correlação internos e externos, o propósito, o destino normalizado, o estado anterior e o novo estado, a regra aplicada, a marca temporal, a expiração da janela e a referência à mensagem existente. Quando houver uma exceção ou revisão manual, registe o responsável, a justificação e o resultado.
Os dados de auditoria devem seguir políticas adequadas de acesso, minimização e retenção. Evite registar segredos de autenticação em texto simples. Para OTPs, é particularmente importante que a rastreabilidade permita relacionar o evento sem expor o segredo fora de banda.
- Motivo para permitir, suprimir, rever ou substituir.
- Chave e correlação do pedido e da mensagem existente.
- Estado conhecido do ciclo de vida e fonte do estado.
- Regra, versão da política e expiração aplicadas.
- Responsável e justificação para exceções manuais.
- Dados mínimos necessários para diagnóstico e auditoria.
Defina exceções sem as transformar numa via de contorno
As exceções devem ser predefinidas, verificáveis e deixar rastreabilidade. Uma alteração material de conteúdo, um novo evento de negócio, uma alteração de canal autorizada, um incidente operacional ou um pedido verificável de reenvio podem justificar que um pedido não seja tratado como duplicado.
Na autenticação, gerar um novo segredo e reenviar um segredo existente são decisões diferentes. O segredo aceite deve poder ser utilizado apenas uma vez enquanto for válido. Além disso, gerar um novo segredo não deve reiniciar o controlo de tentativas falhadas quando este for aplicável. A deduplicação não deve enfraquecer os controlos de segurança nem substituir a limitação de tentativas.
Não use exceções para ultrapassar limites de frequência, ocultar falhas de integração ou repetir mensagens comerciais sem uma base de consentimento e uma política aplicável. A deduplicação técnica deve coexistir com as regras de consentimento, exclusão, frequência e conteúdo, mas não substituí-las.
- Alteração material verificável de conteúdo ou estado.
- Novo propósito ou novo evento de negócio.
- Alteração de canal autorizada e rastreável.
- Reenvio solicitado e verificável pelo utilizador.
- Incidente com procedimento de aprovação e registo.
- Nunca reinicie controlos de tentativas apenas por criar um novo OTP.
Perguntas frequentes
Uma mensagem com o mesmo texto é sempre um duplicado?
Não. O mesmo texto pode pertencer a eventos diferentes, e textos diferentes podem representar a mesma intenção. A decisão deve basear-se no destino normalizado, propósito, evento de negócio, correlação, estado e janela aplicável.
Uma confirmação da API confirma que o utilizador recebeu o SMS?
Não. A aceitação de um pedido ou o estado em fila confirma que a mensagem entrou em processamento, não que chegou ao terminal. Os estados posteriores devem ser interpretados de acordo com a sua semântica e não equivalem a uma confirmação de leitura num SMS.
Como deve ser tratado um OTP reenviado?
Deve estar associado à transação de autenticação e ao segredo concreto. Reenviar o mesmo segredo e gerar um novo são políticas diferentes. Um segredo aceite deve poder ser usado apenas uma vez durante a sua validade.
O que acontece se a resposta da plataforma de envio for perdida?
Mantenha o resultado como incerto, conserve a chave de idempotência e reconcilie o estado antes de criar outro envio. A perda de uma resposta não prova que o pedido original não foi aplicado.
Que métricas ajudam a detetar uma má configuração?
Analise a taxa de supressão por propósito, duplicados observados, novas tentativas falhadas, mensagens suprimidas que acabaram por exigir reenvio, reclamações, erros de correlação e casos de revisão manual. Analise tanto os falsos positivos, em que uma mensagem legítima foi bloqueada, como os falsos negativos, em que foi permitido um duplicado.
Fontes consultadas
- E.164: The international public telecommunication numbering planInternational Telecommunication Union (ITU-T)
- NIST SP 800-63B-4: AuthenticatorsNational Institute of Standards and Technology (NIST)
- RFC 9110: HTTP SemanticsIETF / RFC Editor
- Messages resourceTwilio Documentation
- Outbound Message Status in Status CallbacksTwilio Documentation
- Message Status StreamTwilio Documentation
- Authentication Cheat SheetOWASP Foundation