gb/zap.md
Rodrigo Rodriguez (Pragmatismo) e245077700
Some checks failed
BotServer CI / build (push) Failing after 10s
feat(whatsapp): add phone_number_id based bot routing
- Add resolve_bot_by_phone_number_id function for automatic routing
- Webhooks now route to correct bot based on whatsapp-phone-number-id
- Enables multiple WhatsApp numbers to use single webhook URL
- Falls back to default bot if no match found

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-03-09 12:28:44 -03:00

8.4 KiB

WhatsApp - Bot Salesianos

respeitar AGENTS.md

Status: Operacional

Campo Valor
Bot ID 32c579e5-609b-4a07-8599-4e0fccc4d764
Phone +15558293147
Phone ID 323250907549153
Business ID 1261667644771701

Comandos

  • /clear - Limpa histórico da conversa

Streaming

  1. Mensagens sem lista: enviar a cada 3 parágrafos
  2. Mensagens com lista: ISOLAR como mensagem única (sem texto antes ou depois)
  3. Limite máximo: 4000 caracteres por mensagem

Exemplo de Agrupamento Correto

Resposta completa do bot:

Olá! 😊

Infelizmente, não tenho a informação específica sobre o horário de funcionamento da Escola Salesiana no momento.

Para obter essa informação, você pode:
1. *Entrar em contato com a secretaria* - Posso te ajudar a enviar uma mensagem perguntando sobre os horários
2. *Agendar uma visita* - Assim você conhece a escola pessoalmente e obtém todas as informações necessárias

Gostaria que eu te ajudasse com alguma dessas opções? Se quiser entrar em contato com a secretaria, preciso apenas de:
- Seu nome
- Telefone
- Email
- Sua pergunta sobre os horários

Ou, se preferir, posso agendar uma visita para você conhecer a escola! 🏫

O que prefere?

Deve ser enviado como 5 mensagens separadas:

Mensagem 1:

Olá! 😊

Infelizmente, não tenho a informação específica sobre o horário de funcionamento da Escola Salesiana no momento.

Para obter essa informação, você pode:

Mensagem 2 (LISTA ISOLADA):

1. *Entrar em contato com a secretaria* - Posso te ajudar a enviar uma mensagem perguntando sobre os horários
2. *Agendar uma visita* - Assim você conhece a escola pessoalmente e obtém todas as informações necessárias

Mensagem 3:

Gostaria que eu te ajudasse com alguma dessas opções? Se quiser entrar em contato com a secretaria, preciso apenas de:

Mensagem 4 (LISTA ISOLADA):

- Seu nome
- Telefone
- Email
- Sua pergunta sobre os horários

Mensagem 5:

Ou, se preferir, posso agendar uma visita para você conhecer a escola! 🏫

O que prefere?

Regras:

  • Cada lista = 1 mensagem ISOLADA (nunca misturar com texto)
  • Texto antes da lista = mensagem separada
  • Texto depois da lista = mensagem separada
  • Listas nunca são quebradas no meio

Testar Webhook (Simular Callback)

Script de teste em /tmp/test_whatsapp.sh:

#!/bin/bash
# Testa o webhook do WhatsApp simulando uma mensagem

BOT_ID="32c579e5-609b-4a07-8599-4e0fccc4d764"
FROM="5521972102162"  # Número de teste

curl -X POST "http://localhost:8080/webhook/whatsapp/${BOT_ID}" \
  -H "Content-Type: application/json" \
  -d '{
    "object": "whatsapp_business_account",
    "entry": [{
      "id": "1261667644771701",
      "changes": [{
        "field": "messages",
        "value": {
          "messaging_product": "whatsapp",
          "metadata": {
            "display_phone_number": "15558293147",
            "phone_number_id": "323250907549153"
          },
          "contacts": [{
            "wa_id": "'${FROM}'",
            "profile": { "name": "Teste Usuario" }
          }],
          "messages": [{
            "id": "test_msg_'$(date +%s)'",
            "from": "'${FROM}'",
            "timestamp": "'$(date +%s)'",
            "type": "text",
            "text": { "body": "Olá, como posso ajudar?" }
          }]
        }
      }]
    }]
  }'

Executar teste:

bash /tmp/test_whatsapp.sh

Testar Comando /clear

BOT_ID="32c579e5-609b-4a07-8599-4e0fccc4d764"
FROM="5521972102162"

curl -X POST "http://localhost:8080/webhook/whatsapp/${BOT_ID}" \
  -H "Content-Type: application/json" \
  -d '{
    "object": "whatsapp_business_account",
    "entry": [{
      "id": "1261667644771701",
      "changes": [{
        "field": "messages",
        "value": {
          "messaging_product": "whatsapp",
          "metadata": {
            "display_phone_number": "15558293147",
            "phone_number_id": "323250907549153"
          },
          "contacts": [{
            "wa_id": "'${FROM}'",
            "profile": { "name": "Teste Usuario" }
          }],
          "messages": [{
            "id": "test_clear_'$(date +%s)'",
            "from": "'${FROM}'",
            "timestamp": "'$(date +%s)'",
            "type": "text",
            "text": { "body": "/clear" }
          }]
        }
      }]
    }]
  }'

Debug

# Verificar servidor
curl http://localhost:8080/health

# Monitorar logs
tail -f botserver.log | grep -iE "(whatsapp|Embedding)"

# Verificar sessões ativas (requer acesso ao banco)
# SELECT * FROM user_sessions WHERE bot_id = '32c579e5-609b-4a07-8599-4e0fccc4d764';

Arquivos Relacionados

  • Config: /opt/gbo/data/salesianos.gbai/salesianos.gbot/config.csv
  • Handler: botserver/src/whatsapp/mod.rs
  • Adapter: botserver/src/core/bot/channels/whatsapp.rs
  • Cache: botserver/src/llm/cache.rs

Pendências

  1. Implementar suporte a /webhook/whatsapp/default (ver TODO abaixo)
  2. Configurar webhook na Meta Business Suite para produção
  3. Configurar SSL/TLS no servidor de produção

📋 TODO: Default Bot Routing

Objetivo

Permitir que a URL /webhook/whatsapp/default funcione como roteador dinâmico de bots baseado em comandos de usuário.

Comportamento Atual

  • /webhook/whatsapp/{uuid} → Rota direta para bot específico
  • /webhook/whatsapp/defaultFALHA (espera UUID, não aceita "default")

Comportamento Desejado

  1. /webhook/whatsapp/default → Rota para o bot default (/opt/gbo/data/default.gbai/default.gbot)
  2. Quando usuário digita um whatsapp-id (ex: "cristo", "salesianos"):
    • Sistema busca bot com essa propriedade no config.csv
    • Mapeia phone_numberbot_id na sessão/cache
    • Troca de bot para aquela sessão
  3. Mensagens subsequentes daquele phone_number são roteadas para o bot mapeado
  4. Se usuário digitar outro whatsapp-id, encerra sessão anterior e abre nova para o novo bot

Arquivos a Modificar

1. botserver/src/whatsapp/mod.rs

  • Linha ~178: Modificar verify_webhook e handle_webhook
    • Mudar Path(bot_id): Path<Uuid>Path(bot_id): Path<String>
    • Adicionar parsing: "default" → buscar UUID do bot default
    • Manter parsing UUID para compatibilidade

2. botserver/src/whatsapp/mod.rs

  • Nova função: resolve_bot_id(bot_id_str: &str, state: &AppState) -> Result<Uuid, Error>
    • Se "default" → retorna UUID do bot default via get_default_bot()
    • Se UUID válido → retorna UUID
    • Caso contrário → erro

3. botserver/src/whatsapp/mod.rs

  • Nova função: check_whatsapp_id_routing(message_text: &str, state: &AppState) -> Option<Uuid>
    • Verifica se texto é um comando de troca de bot
    • Busca em todos os bots por whatsapp-id no config.csv
    • Retorna bot_id se encontrar match

4. botserver/src/whatsapp/mod.rs

  • Modificar process_incoming_message
    • Antes de processar, verificar se mensagem é comando de roteamento
    • Se for, atualizar mapeamento phonebot_id no cache
    • Se não for, usar mapeamento existente do cache

Bots com whatsapp-id Configurado

  • cristo.gbot: whatsapp-id,cristo
  • salesianos.gbot: verificar se tem whatsapp-id
  • default.gbot: não tem whatsapp-id (é o roteador)

Implementação em Passos

Passo 1: Modificar handlers para aceitar "default"

// Antes
Path(bot_id): Path<Uuid>

// Depois
Path(bot_id_str): Path<String>
let bot_id = resolve_bot_id(&bot_id_str, &state)?;

Passo 2: Implementar resolve_bot_id

  • Buscar get_default_bot() quando bot_id_str == "default"
  • Parse UUID caso contrário

Passo 3: Implementar roteamento dinâmico

  • Verificar cache: phone_numberbot_id
  • Se não existir, usar bot_id do webhook
  • Se mensagem for comando (whatsapp-id), atualizar cache

Passo 4: Testar

# Teste 1: URL com default
curl -X POST "http://localhost:8080/webhook/whatsapp/default" ...

# Teste 2: URL com UUID (deve continuar funcionando)
curl -X POST "http://localhost:8080/webhook/whatsapp/32c579e5-609b-4a07-8599-4e0fccc4d764" ...

# Teste 3: Roteamento por comando
# Enviar mensagem "cristo" → deve rotear para bot cristo
# Enviar mensagem "salesianos" → deve trocar para bot salesianos

URLs de Teste

  • Localtunnel: https://bright-bananas-deny.loca.lt/webhook/whatsapp/default
  • Local: http://localhost:8080/webhook/whatsapp/default