📄 Documento de Execução — Card 29: [M6] Bot com OpenAI
| Campo | Valor |
|---|---|
| Card Trello | [29] [M6] Bot com OpenAI |
| URL Trello | https://trello.com/c/sUFrJ6Xs |
| Marco | M6 (IA + WhatsApp + CRM) |
| Data execução | 09/08/2026 |
| Responsável | Wellington Santiago (via ZCode) |
| Doc anterior | Card 28: WhatsApp WAHA |
| Próximo card | Card 30: CRM Kanban |
| Commits | 1eb4da2, 134a394 |
🎯 1. O que foi implementado
Bot de atendimento virtual que responde 24h mensagens WhatsApp via OpenAI (GPT-4o-mini). Funciona em modo duplo: se OPENAI_API_KEY configurada, usa a API real com function calling; senão, cai em modo mock (heurística baseada em FAQ/regras) — permite testar todo o fluxo sem custo até a ANIK inserir a chave.
O bot detecta 3 intenções:
- FAQ — responde perguntas comuns (horários, valores) usando a base de conhecimento.
- falar_secretaria — cliente (já aluno) quer humano → handoff (cria notificação + pausa bot).
- novo_lead — contato novo interessado em matrícula → cria Lead (alimenta Card 30) + handoff.
Tom de voz configurável (informal/formal/amigável — default informal, decisão do cliente).
✅ Critérios de aceite validados
| # | Critério | Status |
|---|---|---|
| 1 | Bot responde sozinho 24h perguntas comuns (FAQ/horários/valores) | ✅ |
| 2 | Intent "falar com a secretaria" dispara handoff (notifica painel) | ✅ |
| 3 | Atendente assume conversa e bot pausa (isAiHandled=false) | ✅ |
| 4 | Tom informal configurável | ✅ |
| 5 | Lead criado automaticamente quando contato é novo | ✅ |
| 6 | Pesquisa de satisfação (estrutura pronta no config) | ✅ |
| 7 | Histórico de quem falou (bot/humano/cliente) preservado (sender) | ✅ |
| 8 | OpenAI key em env (fora do git) | ✅ |
| 9 | Build passa + lint OK | ✅ |
📁 2. Arquivos criados/modificados
Criados
| Arquivo | Função |
|---|---|
src/lib/bot/openai.ts |
Cliente OpenAI (gpt-4o-mini + function calling) com fallback mock |
src/lib/bot/faq.ts |
Helper getActiveFaqs (base de conhecimento) |
src/lib/bot/handoff.ts |
Handoff bot→humano: cria lead + notifica atendentes |
src/server/queues/workers/bot-process.ts |
Processa msg inbound: chama IA, responde ou faz handoff |
src/app/(dashboard)/master/bot/config/page.tsx |
Painel admin: status OpenAI + FAQ manager + personalidade |
src/styles/bot-config.module.css |
Estilos do painel |
Modificados
| Arquivo | Mudança |
|---|---|
src/app/api/webhook/whatsapp/route.ts |
Dispara bot-process após salvar inbound + sender='CONTACT' |
src/server/trpc/routers/master.ts |
+sub-router bot (faqList/faqUpsert/faqDelete/status) |
src/server/trpc/routers/attendant.ts |
+conversations.reply (manual via WAHA) +conversations.handBack |
src/app/(dashboard)/atendimento/conversas/[id]/page.tsx |
Banner handoff + reply manual + devolver ao bot |
prisma/schema.prisma |
WhatsAppMessage: +sender +openaiMessageId; WhatsAppConversation: +botHandoffAt |
src/components/layout/nav-config.ts |
+item "Bot IA" no menu Master |
package.json |
+dep openai |
🗄️ 3. Schema do banco (mudanças)
whatsapp_messages: +sender(TEXT — BOT|HUMAN|CONTACT), +openaiMessageId(TEXT)whatsapp_conversations: +botHandoffAt(TIMESTAMP — momento do handoff)- Migration aplicada via
prisma db pushna VPS
🔌 4. Handoff para o próximo card (30 — CRM Kanban)
Variáveis de ambiente
OPENAI_API_KEY=(vazio → modo mock; ANIK insere quando assumir o sistema)OPENAI_MODEL=gpt-4o-mini(default)
Helpers disponíveis (src/lib/bot/)
generateBotReply(text, ctx)→{ text, intent, confidence, openaiMessageId }processHandoff({ conversationId, phoneNumber, intent })→{ leadId, notified }processInboundMessage({ conversationId, messageId, phoneNumber })→{ replied, intent }
Fluxo do bot
- Webhook recebe msg inbound → salva WhatsAppMessage (sender=CONTACT)
- Dispara
processInboundMessage(não-bloqueante) - Se conversa isAiHandled e sem handoff → chama
generateBotReply - Se intent=falar_secretaria/novo_lead → handoff (cria Lead + notifica ATTENDANT)
- Senão → envia resposta FAQ via sendText (sender=BOT)
📋 5. Deploy DEV
- Migration: ✅ prisma db push (novos campos)
- Build VPS: ✅ (após limpar .next)
- pm2 reload: ✅ genioon-dev + genioon-workers
- Smoke test: /master/bot/config → 307 (login), webhook GET → 200
- URL: https://sistemaescolar.wellka.com.br/master/bot/config
🧠 6. Contexto gerado para próximas etapas
- Card 30 (CRM): Leads criados pelo handoff (novo_lead) aparecem no Kanban.
- Card 31 (E-mail): handoff pode disparar e-mail ao atendente (opcional).
- OpenAI ativação: quando ANIK inserir OPENAI_API_KEY no .env, o bot passa a responder com GPT-4o (sem mudança de código — automático).
🎯 7. Próximo card
Card 30 [M6] CRM — Funil de Leads & Matrículas. Kanban drag-and-drop consome os leads criados pelo bot.