Arquitetura de Notificações Omnichannel: Push, SMS e Email em Escala
Em sistemas modernos, notificações são o “pulso” da aplicação. O usuário quer saber o momento exato em que seu salário caiu, quando sua compra foi aprovada ou quando recebeu uma mensagem. Mas quando você tem milhões de usuários e múltiplos canais (Push, SMS, Email, WhatsApp), construir um serviço de notificação robusto e escalável é um desafio técnico fascinante.
O maior erro é acoplar a lógica de notificação diretamente no serviço de negócio. A solução é um Notification Service centralizado e desacoplado.
Acoplamento e Latência
Imagine o PaymentService chamando a API do Twilio (SMS) ou do Firebase (Push) de forma síncrona:
- Latência: Se o Twilio demorar 5 segundos, o seu pagamento demora 5 segundos a mais.
- Disponibilidade: Se o Firebase estiver fora, o seu pagamento falha?
- Complexidade: O seu código financeiro não deveria saber o que é um
Device Tokendo Android.
A Solução: Arquitetura Orientada a Mensagens
O design ideal utiliza um padrão de Fan-out usando um Broker de mensagens (Kafka ou RabbitMQ).
- Evento: O
PaymentServicepublica um eventoPaymentApprovedEventno Kafka. - Orquestração: O
NotificationServiceconsome este evento e consulta as preferências do usuário (ex: ele quer Push? SMS?). - Entrega: O sistema dispara jobs assíncronos para cada canal.
O Modelo de Dados de Notificação
1
2
3
4
5
6
public class NotificationRequest {
private String userId;
private NotificationTemplate template; // "PAYMENT_SUCCESS"
private Map<String, String> parameters; // {amount: 50.00, shop: "Restaurante"}
private List<Channel> preferredChannels; // [PUSH, SMS]
}
Estratégias de Resiliência: O Desafio dos Provedores
Provedores externos (Twilio, SendGrid, Firebase) falham o tempo todo. Seu sistema deve ser resiliente:
1. Retries com Backoff Exponencial
Se o Firebase falhou, espere 1s, depois 2s, depois 4s… antes de tentar novamente.
2. Priorização de Filas (Queuing)
Diferencie notificações críticas de promocionais.
- Fila Alta Prioridade: OTP (One-Time Password) para login. Deve ser entregue em segundos.
- Fila Baixa Prioridade: “Você ganhou R$ 10 de cashback”. Pode esperar minutos ou horas.
3. Rate Limiting por Usuário
Não queremos bombardear o usuário com 50 notificações seguidas. Implemente um Throttling para garantir que o usuário não receba mais de X notificações por hora em cada canal.
Funcionamento Interno e Template Engine
Em vez de escrever strings no código, utilize uma Template Engine (como Thymeleaf ou Handlebars).
1
2
String body = templateEngine.process("payment_success_sms.txt", context);
smsClient.send(phoneNumber, body);
Isso permite que o time de marketing altere o texto das mensagens sem que você precise fazer um novo deploy do código.
Curiosidade Técnica: O Id da Mensagem e o ID do Dispositivo
Muitas vezes, um usuário tem múltiplos dispositivos (um iPad e um Android). No Push, você envia para múltiplos Device Tokens, mas o usuário só quer ver uma notificação. O Notification Service deve gerenciar a lista de tokens ativos de cada userId, limpando tokens inválidos automaticamente sempre que o provedor retornar um erro de ExpiredToken.
O futuro das notificações
À medida que a Inteligência Artificial se torna onipresente, o próximo passo para os serviços de notificação é a hiper-personalização preditiva. No futuro próximo, o NotificationService não apenas entregará mensagens, mas decidirá o momento exato em que o usuário tem maior probabilidade de ler um alerta de cashback ou de ignorar um SMS promocional, transformando a comunicação em uma experiência verdadeiramente adaptativa e menos invasiva.