---
title: "PoC - Envio em Massa de Mensagens no WhatsApp: Uma Jornada de Arquitetura e Resiliência"
slug: ezap-bulk-sender-poc
date: 2025-03-24
category: "Arquitetura"
tags: ["nodejs", "whatsapp", "bullmq", "redis", "nextjs", "clean-architecture", "poc", "microservices"]
readTime: "5 min"
excerpt: "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."
url: https://eliseu.dev/blog/ezap-bulk-sender-poc
---

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](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](https://linkedin.com/in/eliseusantos) ou [GitHub](https://github.com/EliseuSantos).*