1 Chat Whatsapp
Rafael Alves Lopes edited this page 2026-05-27 16:44:28 -03:00

Modulo de Chat WhatsApp (Backend)

Visao geral

O modulo de WhatsApp do backend e desenvolvido em NestJS e utiliza a biblioteca whatsapp-web.js (que roda uma instancia headless do Chromium via Puppeteer) para integrar a aplicacao diretamente com o WhatsApp Web em tempo real.

A arquitetura e constituida por quatro pilares:

  1. Puppeteer Client: Controla o WhatsApp Web, gera o QR Code para autenticacao e escuta eventos de novas mensagens.
  2. WebSocket Gateway: Transmite eventos em tempo real (novas mensagens, atualizacao de status) para o frontend usando Socket.io.
  3. Persistencia Hibrida: Mantem conversas indexadas localmente via JSON para performance e o status de atribuicao de atendimento gravado no banco relacional (PostgreSQL).
  4. Servico de Atribuicao: Gerencia o vinculo dos chats com os atendentes (usuarios) e suas respectivas areas operacionais.

Fluxo de Eventos e Mensagens

1. Inicializacao e Conexao

  • O backend inicia o cliente do whatsapp-web.js na porta configurada.
  • Se nenhuma sessao ativa for encontrada na pasta /whatsapp-session, o cliente gera um QR Code em formato Base64.
  • Esse QR Code e enviado via WebSocket (qr) para o frontend configurar o dispositivo.
  • Uma vez conectado, o status muda para CONNECTED e a pasta de sessao e gravada localmente.

2. Captura de Mensagens (message_create)

Utilizamos o evento global message_create para capturar tanto mensagens recebidas do cliente quanto mensagens enviadas pelo proprio atendente (seja pela tela ou por outro dispositivo sincronizado):

Puppeteer (Message)
  -> Trata de-duplicacao ou broadcast
  -> Se possuir midia, baixa os buffers em tempo real
  -> Transmite via WebSocket 'message' para o frontend
  -> Salva ou atualiza a conversa na persistencia local JSON

Persistencia e Banco de Dados

1. Cache Local JSON (whatsapp-chats-persist.json)

Para evitar sobrecarregar o banco relacional e garantir latencias imperceptiveis de scroll, os chats e seus metadados de visualizacao sao armazenados de forma persistente em um arquivo JSON local na raiz do backend.

2. Tabela de Atribuicao de Chat (whatsapp_chat_atribuicoes)

O controle de quem esta atendendo qual chat e estritamente transacional e reside no banco PostgreSQL.

A estrutura da tabela e criada pela migration 004_whatsapp.sql:

CREATE TABLE IF NOT EXISTS whatsapp_chat_atribuicoes (
  id SERIAL PRIMARY KEY,
  chat_id VARCHAR(255) NOT NULL,
  user_id SERIAL REFERENCES usuarios(id) ON DELETE CASCADE,
  area_id SERIAL REFERENCES areas(id) ON DELETE SET NULL,
  assigned_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
  UNIQUE(chat_id)
);

Regras de Atribuicao:

  • chat_id: Identificador unico da conversa no WhatsApp (ex: 5511999999999@c.us ou ...@lid).
  • user_id: ID inteiro (usuarios.id) do atendente que assumiu.
  • area_id: ID inteiro (areas.id) do setor sob o qual o atendimento esta sendo prestado (ex: 1 para Suporte).

Endpoints do Modulo

Base path: /whatsapp

1. Enviar Mensagem

POST /whatsapp/send
Content-Type: application/json

Payload:

{
  "to": "5511999999999@c.us",
  "message": "Ola, tudo bem?",
  "media": {
    "data": "base64String...",
    "mimetype": "image/png",
    "filename": "comprovante.png"
  }
}

2. Atribuir Chat

POST /whatsapp/assign
Content-Type: application/json

Payload:

{
  "chatId": "5511999999999@c.us",
  "userId": 4,
  "areaId": 1
}

3. Liberar Chat

DELETE /whatsapp/release/:chatId

Limitacoes e Solucoes de Bugs

1. Payload Too Large (Upload de Midia)

Para permitir o envio de imagens, videos e audios pesados codificados em Base64, o limite padrao de payload do NestJS foi estendido para 50MB no main.ts tanto para formato JSON quanto para urlencoded.

2. Nomes Numericos do WhatsApp (Smart Name Resolution)

Devido a latencias do WhatsApp Web, as mensagens recebidas as vezes reportam apenas o telefone/JID como nome do contato. O servico de WhatsApp contem uma camada reativa de reparacao automatica:

  • Checa se o nome e puramente numerico.
  • Se for, faz uma chamada em background para o Puppeteer (client.getContactById) para obter o notifyName real do cliente e atualizar o cache local.

Como Rodar e Testar

Requisitos locais

  • Node.js v18+
  • PostgreSQL ativo com as migrations executadas
  • Google Chrome ou Chromium instalado (o Puppeteer tentara usar o bundle local se omitido)

Executando em desenvolvimento

cd backend
npm run dev

Os logs do NestJS no terminal indicarao as fases de inicializacao do Puppeteer, geracao de QR Code ou recuperacao de sessao ativa.