Entrar como:FuncionalidadesDoc
Pular para o conteúdo
← Voltar para a visão geral
✅ ConcluídoCard #28 · M6

Integração WhatsApp (WAHA)

Marco M6: IA + WhatsApp + CRM

📅06 de agosto de 2026
👤Wellington Santiago (via ZCode)
🔧Commits: f54f5c5

📄 Documento de Execução — Card 28: [M6] Integração WhatsApp (WAHA)

Campo Valor
Card Trello [28] [M6] Integração WhatsApp (WAHA)
URL Trello https://trello.com/c/rHzIJnu2
Marco M6 (IA + WhatsApp + CRM)
Data execução 07/08/2026
Responsável Wellington Santiago (via ZCode)
Doc anterior Card 27: Relatórios Gerenciais
Próximo card Card 29: Bot com OpenAI
Commits f54f5c5

🎯 1. O que foi implementado

O módulo WhatsApp do GENIOON foi migrado da Meta Cloud API para o WAHA (self-hosted) e totalmente integrado. A decisão foi do Wellington (07/08/2026): WAHA elimina custo por mensagem (~R$0,25/conversa da Meta), templates pré-aprovados, app review e janela de 24h.

A WAHA roda em Docker na própria VPS Oracle (porta 3100), com a sessão "anik" vinculada ao número oficial 0800 323 3000 ("Atendimento Anik"). Toda a stack foi ajustada — código, schema, docs e infra.

Camada de transporte isolada

O envio passa por src/lib/waha.ts (cliente WAHA), usado pelo worker Bull e pelo painel. Trocar de engine no futuro = mudar 1 arquivo.

✅ Critérios de aceite validados

# Critério Status
1 Webhook inbound recebe mensagens WAHA (event "message")
2 Mensagem recebida é salva em WhatsAppMessage
3 Número 0800 323 3000 / display "Atendimento Anik" configurados
4 Worker password-reset-whatsapp envia real via WAHA (não stub)
5 Reset de senha por WhatsApp (RecoveryChannel.WHATSAPP)
6 Status de entrega (message.ack) atualiza WhatsAppMessage.status
7 Caixa de entrada lista conversas (master.whatsapp.conversations.list)
8 Build passa + lint OK + secrets fora do git
9 Painel admin (/master/whatsapp/config) com status + teste de envio

📁 2. Arquivos criados/modificados

Criados

Arquivo Função
src/lib/waha.ts Cliente WAHA: sendText, sendMedia, getWahaStatus, toChatId, phoneFromChatId, tipos webhook
src/app/api/webhook/whatsapp/route.ts Webhook inbound: event "message" (salva), "message.ack" (status), "session.status" (log)
src/app/(dashboard)/master/whatsapp/config/page.tsx Painel admin: status WAHA, config (session/apiKey/webhookSecret), teste de envio
src/styles/whatsapp-config.module.css Estilos do painel

Modificados

Arquivo Mudança
prisma/schema.prisma WhatsAppConfig +wahaSession, +wahaApiKey (campos Meta wabaId/phoneNumberId/accessToken marcados obsoletos)
src/server/queues/workers/password-reset-whatsapp.ts Reescrito Meta→WAHA: texto livre, sendText via lib/waha; stub só se WAHA_BASE_URL vazio
src/middleware.ts Libera /api/webhook/ (WAHA não tem JWT)
src/server/trpc/routers/master.ts +sub-router whatsapp (config.get/update, test, conversations.list)
src/components/layout/nav-config.ts +link "WhatsApp" no menu Master
.env.example Bloco WhatsApp WAHA (WAHA_BASE_URL, WAHA_SESSION, WAHA_API_KEY, WHATSAPP_HOOK_SECRET)

🗄️ 3. Schema do banco (mudanças)

  • whatsapp_configs: +wahaSession (TEXT), +wahaApiKey (TEXT)
  • Campos Meta (wabaId, phoneNumberId, accessToken) — mantidos (obsoletos, ignorados pelo código WAHA)
  • Migration aplicada via ALTER TABLE manual na VPS (o prisma migrate dev detectou drift histórico e sugeriu reset — evitado pra preservar dados)

🔌 4. Handoff para o próximo card (29 — Bot OpenAI)

Variáveis de ambiente (VPS Oracle .env)

  • WAHA_BASE_URL=http://localhost:3100
  • WAHA_SESSION=anik
  • WAHA_API_KEY=ce2918... (em /home/ubuntu/waha/docker-compose.yml também)
  • WHATSAPP_HOOK_SECRET= (vazio por ora)

Helpers disponíveis (src/lib/waha.ts)

  • sendText({to, text, session?}){waMessageId}
  • sendMedia({to, filename, mimetype, base64, caption?}){waMessageId}
  • getWahaStatus(){available, session?, error?}
  • toChatId(phone)"55XXXXXXXXX@c.us"
  • phoneFromChatId(chatId)"55XXXXXXXXX"

Webhook inbound

  • POST /api/webhook/whatsapp recebe {event, session, payload:{from,to,body,hasMedia,id}}
  • Eventos tratados: message (inbound → salva), message.ack (status), session.status (log)
  • Para o Bot (Card 29): ler WhatsAppMessage onde direction='inbound' e isAiHandled=true na conversa

Infra WAHA (Docker na VPS)

  • Container genioon-waha, imagem devlikeapro/waha:arm (⚠️ tag ARM obrigatória — :latest não tem manifest ARM64)
  • Porta 3100, volume ./sessions (persiste sessão)
  • API key exigida em toda chamada (header X-Api-Key)
  • QR code pendente: Wellington precisa escanear 1x com WhatsApp do 0800 323 3000

📋 5. Deploy DEV

  • WAHA Docker: ✅ rodando (docker ps mostra genioon-waha Up)
  • API WAHA: ✅ HTTP 200 com X-Api-Key
  • GENIOON ↔ WAHA: ✅ conectividade OK (localhost:3100)
  • Sessão anik: ⏳ SCAN_QR_CODE (aguardando Wellington escanear QR)
  • Webhook: ✅ configurado (WHATSAPP_HOOK_URL → /api/webhook/whatsapp)
  • Painel: https://sistemaescolar.wellka.com.br/master/whatsapp/config

🧠 6. Contexto gerado para próximas etapas

  • Card 29 (Bot OpenAI): consumir WhatsAppMessage inbound, processar com GPT-4o, responder via sendText(). Toda infra pronta.
  • Card 30 (CRM): leads chegam pelo webhook inbound → criar Lead. Handler já existe.
  • Jobs futuros (absence-notice, payment-reminder, birthday): usar sendText() igual ao password-reset.

🎯 7. Próximo card

Card 29 [M6] Bot com OpenAI — Atendimento Inteligente. IA consome mensagens inbound (já salvas pelo webhook deste card), classifica intenção, responde com GPT-4o. Infra WhatsApp 100% pronta pra receber.

⚠️ Pendência: escanear QR code

A sessão WAHA "anik" está em SCAN_QR_CODE. Wellington precisa:

# No PC do Wellington:
ssh -L 3100:localhost:3100 oracle-free
# Depois abrir no browser: http://localhost:3100/dashboard
# Login com a API key, escanear QR com WhatsApp do 0800 323 3000

Até escanear, o envio real não funciona (stub). O recebimento via webhook já está plugado.

← Voltar para a visão geral