# 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): ```text 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`: ```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 ```http POST /whatsapp/send Content-Type: application/json ``` **Payload**: ```json { "to": "5511999999999@c.us", "message": "Ola, tudo bem?", "media": { "data": "base64String...", "mimetype": "image/png", "filename": "comprovante.png" } } ``` ### 2. Atribuir Chat ```http POST /whatsapp/assign Content-Type: application/json ``` **Payload**: ```json { "chatId": "5511999999999@c.us", "userId": 4, "areaId": 1 } ``` ### 3. Liberar Chat ```http 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 ```bash 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.