March 24, 2025
PoC - Envio em Massa de Mensagens no WhatsApp: Uma Jornada de Arquitetura e Resiliência
Como construí uma PoC completa para envio automatizado de mensagens via WhatsApp usando Node.js, BullMQ, Redis e Next.js, enfrentando desafios com Baileys e implementando Clean Architecture.

Esta PoC nasceu de uma necessidade que tive: automatizar o envio de mensagens no WhatsApp de forma segura, resiliente e com observabilidade desde o primeiro momento. A ideia era simples, mas a execução exigiu estudo e adaptações de algumas libs como, o próprio Baileys.
🎯 Objetivo
O objetivo principal foi criar um sistema de envio de mensagens automáticas via WhatsApp, garantindo:
- Processamento assíncrono com filas
- Resiliência a falhas com retry e backoff exponencial
- Logs estruturados
- Escalabilidade horizontal
- Segurança na comunicação e controle por API Key
- Interface simples e funcional para usuários não técnicos
🔐 Segurança
Por se tratar de uma PoC não gastei muito tempo criando uma boa segurança para essa API, apenas adicionei o básico para validação:
- Validação de todas as variáveis de ambiente com Zod
- Middleware para controle de acesso por API Key
- Sanitização e validação de dados de entrada, como telefone e CSV
- Tratamento centralizado de erros e exceções com monitoramento completo no Sentry
🔧 Stack Utilizada
Backend:
- Node.js com NX (Monorepo)
- BullMQ + Redis (fila de mensagens)
- RabbitMQ (mensageria entre workers)
- PostgreSQL + Drizzle ORM (persistência de logs)
- Sentry + Pino (observabilidade e logging)
- Zod (validação)
- Artillery (teste de carga)
Frontend:
- Next.js + Tailwind v4 + Shadcn UI
- Tanstack Query (integrações reativas)
- Dropzone (Upload de CSV)
⚙️ Arquitetura
A arquitetura adotada segue os princípios da Clean Architecture, com influências de DDD e Hexagonal Architecture, favorecendo a separação de responsabilidades e a testabilidade. Mas claro é uma PoC, tem muita coisa pra ajustar:
- Camada de Domínio: (em evolução) agrupa regras e serviços puramente de negócio, independente de tecnologia
- Use Cases: orquestram a lógica de negócio e se comunicam com portas de entrada e saída (ex: enfileirar e publicar mensagens)
- Infraestrutura: implementa os detalhes (BullMQ, RabbitMQ, Redis, Drizzle, etc) conectando-se às interfaces
- Adapters/Ports: permitem plugar novos meios de entradas/saídas sem afetar regras de negócio
- Monorepo com Nx: facilita a organização entre frontend e backend
Essa abordagem permite escalar e manter o projeto organizado, mesmo com o crescimento de features e integrações.
🧩 Desafios com o Baileys
Um dos maiores desafios foi trabalhar com o baileys integrado ao Redis para salvar os authStates e permitir escalabilidade vertical e horizontal se necessário. Até existe uma lib baileys-store-redis
mas não é mais mantida e o repositório está arquivado e também não utiliza ioredis, o que acabou limitando as possibilidades (como pipeline, reconexão inteligente e cache TTL).
Depois de muita pesquisa e erros, resolvi fazer um fork interno da lógica da store e reescrever a parte que usava redis@^3
para que funcionasse com ioredis. Essa versão foi embutida no projeto e customizada com melhorias:
- Cache de mensagens com limite controlado (Map interno)
- Registro de presença, reações e receives com TTL
Essa personalização abriu espaço para observabilidade e resiliência real, algo que a versão oficial não entregava.
💻 Interface Web com Next.js + Shadcn
A interface está em desenvolvimento, mas já tentei fazer o mais básico possível inspirada diretamente na experiência do ChatGPT:
Tudo foi dividido em componentes reutilizáveis (ChatBubble
, ChatInput
, CsvDropzone
, QRCodeBox
, ChatWindow
, etc), garantindo manutenção fácil e reusabilidade em outros contextos.
🔬 Testes de Carga com Artillery
Os testes de carga foram pensados para simular o uso real do sistema sob diferentes cenários. A estratégia que fiz foi:
- Warm-up: simular um pequeno volume de acessos iniciais
- Ramp-up: aumento progressivo de usuários para avaliar elasticidade
- Sustained Load: carga constante para avaliar estabilidade
- Spike: pico abrupto para testar resiliência
- Cooldown: redução gradual para encerrar
Também foram usados dados de um CSV simulando perfis (básico, pro, enterprise) de clientes, onde cada um teria linkado a seu plano uma quantidade de requests por minuto que poderia usar, garantindo que o sistema conseguisse responder com sucesso a cada um.
As métricas observadas incluíram taxa de erro, tempo médio de resposta e logs em tempo real no banco.
✅ Conquistas até Aqui
- ✅ Mensagens sendo enviadas com sucesso via WhatsApp
- ✅ Reconexão automática com regeneração de QR Code
- ✅ Retry com backoff exponencial no BullMQ
- ✅ Registro de logs no banco com status success ou error
- ✅ Worker isolado e leve, pronto para escalar
- ✅ Base em Clean Architecture com crescimento saudável
- ✅ Mínimo Possível de Segurança aplicada com Zod e controle por API Key
- ✅ Frontend desacoplado e moderno
- ✅ Organização via Nx Monorepo trazendo uma boa DevX
🔜 Próximos Passos
Essa PoC ainda está em evolução. Tenho algumas ideias para as próximas implementações:
- Adicionar autenticação de verdade com API Key por cliente/ OAuth
- Criar sistema de template de mensagens
- Criar painel de métricas com mensagens por hora, falhas, entregas, etc.
- Persistir contatos vindos do CSV
- Validar os números do CSV antes de enfileirar
- Criar UI para reenvio de mensagens com erro
- Usar SSE/WebSocket para exibir status de envio em tempo real
🚀 Conclusão
Essa PoC começou com a necessidade de um sistema simples de disparo de mensagens via WhatsApp. Aos poucos, o projeto foi crescendo, enfrentando desafios com dependências, arquitetura — e está virando uma solução interessante e "robusta" para envio em escala, com resiliência e boas práticas.
A interface está ficando cada vez mais amigável, o backend sólido, e o projeto está só começando.
Vou continuar evoluindo e documentando cada passo.
Repositório: https://github.com/EliseuSantos/ezap-bulk-sender
Este artigo documenta minha jornada construindo uma PoC completa para envio de mensagens em massa via WhatsApp. Para discussões técnicas ou contribuições, me encontre no LinkedIn ou GitHub.