Endpoint para agentes

Conecte Eventos duráveis da BotoZap ao seu runtime de agente e responda ao Contato sem consultar mensagens em loop.

O exemplo oficial é um projeto Node.js executável no repositório público botozap-js/examples/agent-endpoint. Ele usa apenas o SDK e a API públicos: a BotoZap continua sendo o canal oficial e o modelo/runtime do agente continua sendo seu.

Se o seu cliente mantém uma sessão MCP persistente, veja também o guia MCP para agentes. Ele separa notification, releitura do resource e novo agent turn, e mostra como o cursor/replay de baixa latência complementa este Endpoint durável. O resource MCP, GET /v1/events e boto.events.list do SDK leem o mesmo log de Eventos por cursor.

Para configurar o atendimento executado pelos agentes do próprio BotoZap, consulte Agente de IA pela API. Esse recurso tem escopos e controles próprios de configuração e ativação.

Fluxo orientado a Eventos

Meta → BotoZap (inbox/outbox) → seu Endpoint
                                  │
                            INSERT + NOTIFY
                                  │
                            ACK 2xx rápido
                                  ▼
                         worker do agente
                                  │
                       POST /v1/messages → Meta

O Endpoint valida o HMAC sobre os bytes crus, grava o Evento numa fila PostgreSQL e só então confirma com 2xx. O ACK não espera o agente nem a Meta responder. Depois do commit, LISTEN/NOTIFY acorda o worker; a linha durável continua sendo a fonte da verdade caso um processo reinicie.

A coluna idempotency_key é única. Retry ou replay com a mesma X-Idempotency-Key encontra o job existente e não produz outra mensagem outbound. Veja também Confiabilidade e entrega.

Rodar o exemplo

git clone https://github.com/bytecraft-fernando/botozap-js.git
cd botozap-js
pnpm install

export DATABASE_URL='postgresql://app:senha@localhost:5432/app'
export BOTOZAP_API_KEY='bz_live_xxx'
export BOTOZAP_WEBHOOK_SECRET='whsec_xxx'
export BOTOZAP_FALLBACK_TEMPLATE='retomar_atendimento'

pnpm --filter example-agent-endpoint start

Para produção, rode start:endpoint e start:worker como processos separados. Ambos usam o mesmo PostgreSQL; não existe fila em memória entre eles. Publique a rota https://seu-dominio.example/webhooks/botozap. Um túnel é útil no desenvolvimento, mas não deve virar Endpoint permanente.

Sem configuração de modelo, a resposta local é determinística. Com AGENT_ENDPOINT_URL, o worker envia { input, event } ao seu runtime e espera { reply }. O README do exemplo documenta o contrato.

Criar o Endpoint

Cadastre a URL em Webhooks no painel ou pela API. A resposta 201 é a única leitura que contém o secret; guarde-o em BOTOZAP_WEBHOOK_SECRET. O endpoint nasce com health_status=unverified: mesmo comactive=true, não recebe Eventos reais até um teste assinado retornar 2xx.

curl -sS https://botozap.com.br/api/v1/webhooks \
  -H "Authorization: Bearer $BOTOZAP_API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{
    "url": "https://seu-dominio.example/webhooks/botozap",
    "events": ["messages"],
    "active": true
  }'

Testar sem enviar WhatsApp

curl -sS -X POST \
  https://botozap.com.br/api/v1/webhooks/$ENDPOINT_ID/test \
  -H "Authorization: Bearer $BOTOZAP_API_KEY"

O teste usa os mesmos headers, assinatura e caminho HTTP de uma Entrega real. Uma resposta 2xx verifica e ativa o endpoint; qualquer não-2xx, timeout ou erro de rede retorna 502 e não incrementa o streak de saúde. A tentativa webhook.test é auditada separadamente e não aciona retry automático nem pausa por falhas repetidas.

Se você alterar a URL ou o Authorization, faça o teste novamente. PATCH active=true sozinho retorna verification_required; a reativação passa por este teste.

Após a verificação, falhas reais seguem a curva de 1 / 2 / 4 / 8 / 16 / 32 / 60 minutos, com 60 minutos repetidos nas tentativas seguintes. A BotoZap alerta o owner nos streaks 5, 10 e 15 e pausa automaticamente no 15º. Essa pausa mantém active=true, retém o backlog por 14 dias e aguarda outro teste 2xx após a correção.

Janela de 24h e Template

O worker usa o timestamp inbound com margem de segurança: envia texto livre dentro da janela e o Template aprovado configurado em BOTOZAP_FALLBACK_TEMPLATE fora dela. A API BotoZap ainda é a autoridade. Se a janela fechar entre a decisão e o envio, ela responde outside_window antes de chamar a Meta e o adapter troca para Template sem gerar duas mensagens.

Antes do I/O outbound, o job muda para sending. Esse estado nunca é retomado automaticamente: uma queda nesse ponto pode exigir inspeção humana, mas não dispara uma resposta duplicada para o Contato.

Observar Entregas

curl -sS \
  "https://botozap.com.br/api/v1/webhook_deliveries?webhook_id=$ENDPOINT_ID" \
  -H "Authorization: Bearer $BOTOZAP_API_KEY"

A listagem mostra status, response_code, número de tentativas e próxima retentativa. No banco do exemplo, consulte agent_jobs sem imprimir payload para observar os estados sem expor a conversa.

Replay

No caminho health-aware, falhas consecutivas levam o endpoint a paused no 15º streak, não a um teto fixo de seis tentativas. Depois de corrigir o destino, use Testar e ativar para sair da pausa e acordar o backlog ainda retido; a plataforma mantém o mesmo corpo e a mesma chave de idempotência.

Qualquer membro da conta pode usar Operação → Replay para uma Entrega terminal que ainda esteja retida. O exemplo responde 200 duplicate e não cria outro job. A Entrega permanece observável e o replay é auditado.

Se a Entrega teve sucesso, mas o runtime do agente esgotou três tentativas, o estado failed é a DLQ local. Rode pnpm --filter example-agent-endpoint replay -- <job-id>para fazer failed → queued e acordar o worker. O comando recusa qualquer job que não esteja em failed.

Não retente automaticamente jobs locais em sending ou ambiguous: a Meta não fornece uma chave de idempotência no envio e uma tentativa anterior pode ter sido aceita.

Endpoint BotoZap não é receiver Meta

Endpoint do agenteReceiver Meta da BotoZap
Quem chamaBotoZapMeta
HeaderX-Webhook-SignatureX-Hub-Signature-256
Segredowhsec_…App Secret da Meta
Formato HMAChex purosha256=<hex>

Não aponte o callback do app Meta para este exemplo. A BotoZap já opera esse receiver, persiste o envelope cru antes do 200 e cria a Entrega durável que chega ao seu Endpoint.

Para detalhes do header e do payload, continue em Webhooks.