Files
Documentos-Unicos/projetos/newwhats.clube67.com/integracao-satelites.md
T
2026-06-28 17:39:00 +02:00

6.7 KiB

newwhats.clube67.com — Contrato de integração Motor ↔ Satélite

O motor (newwhats) expõe a plataforma WhatsApp + Secretária IA; cada satélite (ex.: mercado.clube67.com / "Alemão Conveniências", plugin newwhats v2.1.0) consome o motor e fornece dados do seu negócio. Fonte da verdade do contrato (auditado em 28/jun/2026).

⚠️ Regra de registro bidirecional

  • Cada plugin satélite é ÚNICO do projeto onde está instalado — o newwhats do mercado.clube67.com pode divergir do de outro projeto. Não copiar cego.
  • Toda mudança no plugin que toque o contrato deve ser registrada no motor e nesta doc; toda mudança no motor que afete o contrato deve ser refletida no doc do plugin (INTEGRACAO-MOTOR.md, dentro de cada plugin).
  • O plugin é um braço inteligente do motor: consome, alimenta e configura — não duplica lógica do motor.

Satélites conhecidos

  • mercado.clube67.com ("Alemão Conveniências") — plugin CommonJS no PluginManager. Domínio: clubes/planos/sorteio/vagas/promoções.
  • scoreodonto.com (28/jun/2026) — clonado e adaptado ao odonto. Módulo ESM em backend/newwhats/ (sem PluginManager; registerNewwhats(app, pool) no server.js), config por ENV. /nw/* e sync-knowledge usam clínica/especialidades/dentistas/procedimentos/planos (multi-tenant por clinica_id). Removidos os recursos só-mercado e o media-transcribe. Em branch feat/newwhats-satelite (sem deploy); falta parear com o motor (apiKey + agente) e preencher as ENV. Ver backend/newwhats/INTEGRACAO-MOTOR.md.

Docs relacionadas

  • tarefas.md — checklist mestre de pendências.
  • wasabi-midias.md — storage, index e delete em lote.
  • ativacao-whatsapp.md — trajeto inteligente de ativação.
  • INTEGRACAO-MOTOR.md — dentro de cada plugin satélite (lado do satélite).

Config do satélite (plugin_configs, manifest newwhats)

newwhats_url (URL do motor) · integration_key (x-nw-key, rotas /nw/*) · api_token (Bearer, envio de mensagens) · webhook_secret (HMAC do webhook).

Contrato A — Satélite → Motor (ext-api /api/ext/v1/*)

Satélite chama Motor (ext-api) Status
inbox, inbox/:chatId/messages, inbox/:chatId/send idem
media/:messageId media/:messageId
stream (WS) stream
secretaria/ask secretaria/ask (routes.ts)
secretaria/numbers alias adicionadosec_numbers (corrigido)
secretaria/* interno (sync-knowledge) /api/secretaria/* (plugin)

Demais dados da Secretária no ext-api ficam sob /sec/* (sec/agent, sec/nodes, sec/slots, sec/conversations, sec/keys, sec/handoff).

Contrato B — Motor → Satélite

Mecanismo Satélite Auth
Webhook POST /api/webhook/newwhats (message.new, session.status) webhook-receiver.js HMAC webhook_secret
Secretária consulta /nw/* (/cliente, /clube, /parceiros, /promocoes, /sorteio, /vagas, /ping) routes.js integration_key (timingSafeEqual)

O que o satélite já faz (e poderia migrar ao motor)

  • media-transcribe.js: transcrição de áudio + descrição de imagem via Gemini (cache Redis, fallback Whisper). Hoje só no satélite → candidato a ir ao motor.
  • sync-knowledge.js: monta o nó de conhecimento com dados reais e envia ao motor.
  • smart-router.js (roteamento sem LLM), personas.js, follow-up-detector.js, context-builder.js (contexto local do negócio).

Estado da sincronização (faseado)

  1. Contrato documentado (este arquivo).
  2. Compatibilidade de API: alias GET /secretaria/numbers no ext-api do motor (retrocompatível) — fecha o gap do webhook-receiver. (commit motor)
  3. Config/conexão (auditado 28/jun/2026, satélite mercado@VPS3 ↔ motor dev newwhats_dev). Resultado:
    • Satélite → Motor (ext-api/proxy/WS) proxy.js envia x-nw-key = integration_key do satélite; o ext-api valida contra a tabela apiKey. A chave do satélite (nw_t…_001, len 34) é igual à apiKey ativa do motor. Teste vivo: GET /api/ext/v1/sessions com a chave → 200; sem chave / chave inválida → 401 (correto).
    • Webhook Motor → Satélite (HMAC) ext_webhooks do motor: url http://127.0.0.1:4001/api/webhook/newwhats, eventos [message.new, session.status], ativo, secret (len 64) igual ao webhook_secret do satélite. Assinatura x-nw-signature: sha256=HMAC (webhook-dispatcher.ts).
    • Topologia co-locada (127.0.0.1): satélite espera motor em :8008; motor espera satélite em :4001. Para teste vivo ponta-a-ponta o satélite precisa rodar co-locado com o motor dev (hoje não está rodando na VPS4).
    • ⚠️ /nw/* (Motor → Satélite, Secretária): o satélite valida o x-nw-key entrante contra plugin_configs.integration_key (nw_t…_001); o PluginPair do motor usa outra chave (nwk_…1039, lastSeenAt=null). Se esse sentido for usado, reconciliar a chave (não afeta a Fase 4, que é Satélite → Motor).
    • ⚠️ api_token não existe em plugin_configs do satélite — não é necessário: o ext-api autentica por x-nw-key (= integration_key), não por Bearer separado.
  4. Conhecimento: sync-knowledge rodado end-to-end (28/jun/2026). Driver executou o buildKnowledgeText real do satélite (DB mercado@VPS3: 2 clubes, 4 planos, 6 promoções → 1895 chars) e publicou no motor dev via /api/secretaria (nginx-dev :8022 → backend, rotas internas sem auth). Nó knowledge atualizado. RAG indexou: sec_knowledge_chunks = 4 chunks do nó, todos com embedding Gemini (768d). pipeline ok.
    • ⚠️ A geração final do LLM (gemini-2.0-flash:generateContent) retorna 429 quota (free tier) — billing da chave Gemini, não defeito do pipeline.
    • Corrigido de quebra: /secretaria/ask filtrava prisma.chat por remoteJid (inexistente) → 500; agora usa jid.
  5. Mover recursos para o motor (genéricos a todos os satélites):
    • Transcrição (áudio→texto, imagem→descrição) já no motor via Gemini (messages.transcription). O media-transcribe.js do satélite vira redundante.
    • memória (a secretária já tem memória por contato no motor; falta o satélite deixar de duplicar). Satélite passa a só enviar contexto.

Inconsistência anotada

A transcrição no satélite usa process.env.GEMINI_API_KEY; o RAG/memória do motor usa cfg.gemini_key (config do plugin). Unificar a fonte da chave ao migrar.