docs: adiciona spec do orçamento automático de exames via foto (GChat/Z-PRO + n8n)
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,172 @@
|
||||
# Orçamento automático de exames a partir de foto (GChat/Z-PRO + n8n + IA)
|
||||
|
||||
- **Data:** 2026-08-20
|
||||
- **Status:** Aprovado para implementação
|
||||
- **Instância n8n alvo:** `https://devn8n.gtigrupo.com.br`
|
||||
|
||||
## Objetivo
|
||||
|
||||
Quando um cliente manda, pelo WhatsApp (canal Z-PRO/GChat), uma foto de um pedido
|
||||
médico de exames, o sistema deve:
|
||||
|
||||
1. Identificar os exames escritos/impressos na imagem.
|
||||
2. Cruzar esses exames com uma tabela de preços mantida no prompt da IA.
|
||||
3. Montar um orçamento formatado para WhatsApp (itens + valores + total).
|
||||
4. Enviar esse orçamento automaticamente de volta ao cliente, via API do Z-PRO.
|
||||
|
||||
Este é um teste ponta-a-ponta: o objetivo imediato é validar o fluxo técnico
|
||||
completo (recebimento da imagem → IA de visão → resposta automática), usando uma
|
||||
lista de exames de exemplo. A lista real de exames/valores é trocada depois,
|
||||
diretamente no prompt do agente.
|
||||
|
||||
## Contexto / descobertas
|
||||
|
||||
- A documentação disponível na pasta do projeto (`Z-PRO v4.x.x.x.postman_collection.json`)
|
||||
cobre apenas a **API externa de saída** do Z-PRO (criar ticket, enviar mensagem,
|
||||
listar contatos etc.) — não documenta o formato do webhook de **entrada** que o
|
||||
Z-PRO dispara quando um cliente manda uma mensagem.
|
||||
- A conta n8n já tem vários workflows em produção que integram GChat/Z-PRO com
|
||||
agentes de IA para bots de agendamento (ex.: `Agendamento - GChat - Z-PRO
|
||||
(clínica exemplo)`, id `yG2mi6ECBpPv4Hmn`). Neles, o Z-PRO chama o webhook do
|
||||
n8n com um body como:
|
||||
```json
|
||||
{ "step": "process", "protocol": "...", "entrada": "texto do cliente", "contactName": "...", "number": "55..." }
|
||||
```
|
||||
Nenhum desses fluxos existentes trata **imagem** — todos são só texto. Portanto
|
||||
o nome exato do campo que carrega a foto (`mediaUrl`, `file`, `midia`, etc.) é
|
||||
**desconhecido até o primeiro teste real** com uma imagem de verdade.
|
||||
- Existe um sub-workflow reutilizável para envio de texto pelo Z-PRO:
|
||||
`MCP Server - Mensageria ZPRO - enviar_texto` (id `Y4ndG7GuIUrmVRxV`), que recebe
|
||||
`{ number, body, externalKey, isClosed }`, monta o corpo e faz `POST` para
|
||||
`https://apigchat.gtigrupo.com.br/v2/api/external/{apiId}/` usando a credencial
|
||||
HTTP Header Auth **"ZPRO API Token - Canal QR - MC AGENDAMENTO"**. Este fluxo
|
||||
novo vai **reaproveitar esse mesmo sub-workflow** para enviar a resposta, em vez
|
||||
de duplicar a chamada HTTP.
|
||||
- O node `AI Agent` do n8n (`@n8n/n8n-nodes-langchain.agent`) tem a opção
|
||||
`passthroughBinaryImages` (padrão `true`), que repassa automaticamente imagens
|
||||
binárias do item de entrada para o modelo de chat como mensagem de imagem —
|
||||
não é necessário um node de OCR separado.
|
||||
|
||||
## Decisões (confirmadas com o usuário)
|
||||
|
||||
| Decisão | Escolha |
|
||||
|---|---|
|
||||
| Como responder ao cliente | Assíncrono: o workflow processa a imagem e chama a API do Z-PRO (`SendMessageAPIText`, via sub-workflow existente) para enviar a resposta. O webhook de entrada responde rápido (200 OK) e não fica esperando a IA. |
|
||||
| Envio automático vs. revisão humana | Automático — a IA monta e já envia o orçamento, sem aprovação humana no meio. |
|
||||
| Lista de exames/valores | Lista de exemplo (placeholder) embutida no prompt do agente para este teste. Lista real é trocada depois, editando o texto do system prompt do node `AI Agent` no n8n. |
|
||||
| Exame identificado na imagem mas fora da lista de preços | O orçamento traz os itens reconhecidos normalmente (com valor) e avisa, para os não reconhecidos, que um atendente vai confirmar o valor à parte. Nunca bloqueia o envio do orçamento inteiro por causa de um item não reconhecido. |
|
||||
| Canal/token do Z-PRO usado para enviar a resposta | Reaproveita o canal/credencial já cadastrados no n8n para "Canal QR - MC AGENDAMENTO" (mesmo usado pelo bot de agendamento), via o sub-workflow `enviar_texto` existente. |
|
||||
| Workflow | Novo workflow dedicado (não mexe no workflow de agendamento existente). |
|
||||
| Credenciais (IA, Z-PRO) | Configuradas como credenciais nativas do n8n (não hardcoded nos nodes), para poderem ser trocadas depois sem editar o workflow. |
|
||||
|
||||
## Arquitetura
|
||||
|
||||
Novo workflow: **`Orçamento de Exames - GChat - Z-PRO (IA Visão)`**
|
||||
|
||||
```
|
||||
Webhook (Z-PRO)
|
||||
→ Responder 200 OK imediatamente (ack rápido, não espera a IA)
|
||||
→ Extrair campos do webhook (número, protocolo/ticket, referência da imagem)
|
||||
→ IF: é mensagem de imagem?
|
||||
├─ não → encerra (não faz nada; este fluxo só trata imagem)
|
||||
└─ sim → Baixar imagem (HTTP Request, binário)
|
||||
→ AI Agent (visão) — system prompt com tabela de exames/valores
|
||||
+ OpenAI Chat Model (gpt-4o, com credencial própria)
|
||||
→ Montar corpo da resposta (body/number/externalKey/isClosed)
|
||||
→ Execute Workflow: "MCP Server - Mensageria ZPRO - enviar_texto"
|
||||
(erro em qualquer etapa crítica → mensagem padrão de fallback, enviada pelo
|
||||
mesmo sub-workflow: "Recebemos sua solicitação, nossa equipe vai te
|
||||
responder em breve.")
|
||||
```
|
||||
|
||||
### Componentes
|
||||
|
||||
1. **Webhook (trigger)** — novo path dedicado (ex.: `orcamento-exames-zpro`),
|
||||
`responseMode: lastNode`, responde rápido com um ack simples. Este endpoint
|
||||
precisa ser configurado, do lado do Z-PRO, como destino das mensagens do
|
||||
canal-alvo (mesmo mecanismo já usado para plugar os bots de agendamento —
|
||||
o usuário já sabe fazer isso).
|
||||
|
||||
2. **Extrair campos do webhook** — node Set/Code que lê `number`, `protocol`
|
||||
(ou equivalente) e a referência da imagem do `body` recebido. Os nomes de
|
||||
campo para a imagem são a melhor suposição inicial e **serão corrigidos após
|
||||
o primeiro teste real** (ver seção "Suposições em aberto").
|
||||
|
||||
3. **IF é imagem?** — segue adiante só se a mensagem recebida for do tipo
|
||||
imagem; qualquer outro tipo (texto, áudio, documento) encerra o fluxo sem
|
||||
ação, já que este workflow trata exclusivamente pedidos de exame por foto.
|
||||
|
||||
4. **Baixar imagem** — HTTP Request que baixa o arquivo da imagem como binário
|
||||
(assumindo que o Z-PRO entrega uma URL pública de mídia; se o payload real
|
||||
trouxer a imagem em base64 em vez de URL, este node é trocado por uma
|
||||
conversão base64 → binário).
|
||||
|
||||
5. **AI Agent + OpenAI Chat Model (gpt-4o)** — recebe a imagem baixada como
|
||||
binário (repassada automaticamente ao modelo via `passthroughBinaryImages`).
|
||||
System prompt contém:
|
||||
- Persona: assistente de orçamentos de exames da clínica, respondendo por
|
||||
WhatsApp.
|
||||
- Tabela de exames + valores (placeholder nesta fase).
|
||||
- Instruções: ler os exames pedidos na imagem (impressos ou manuscritos),
|
||||
casar com a tabela (tolerando abreviações/sinônimos comuns), montar
|
||||
resposta formatada para WhatsApp com itens + valores + total: para exames
|
||||
não encontrados na tabela, listar separadamente avisando que um atendente
|
||||
vai confirmar o valor. Saída deve ser só o texto final a enviar ao
|
||||
cliente (sem comentários extras, sem markdown incompatível com WhatsApp).
|
||||
- Credencial de API key da OpenAI própria deste node (independente da usada
|
||||
nos bots de agendamento), para poder ser trocada sem afetar outros fluxos.
|
||||
|
||||
6. **Montar corpo da resposta** — Set/Code node que monta
|
||||
`{ number, body: <texto da IA>, externalKey: <único por execução>,
|
||||
isClosed: false }`. `externalKey` gerado por execução (ex.:
|
||||
`orcamento-{{ $execution.id }}`) para respeitar a exigência do Z-PRO de
|
||||
chave única por ação.
|
||||
|
||||
7. **Execute Workflow: enviar_texto** — chama o sub-workflow existente
|
||||
`MCP Server - Mensageria ZPRO - enviar_texto` (id `Y4ndG7GuIUrmVRxV`),
|
||||
reaproveitando a credencial e a lógica de classificação de erro já
|
||||
existentes.
|
||||
|
||||
### Tratamento de erro
|
||||
|
||||
- Falha ao baixar a imagem ou erro na chamada da IA → segue para o mesmo passo
|
||||
de envio (`enviar_texto`), mas com uma mensagem padrão de fallback em vez do
|
||||
orçamento, avisando que a equipe vai responder manualmente.
|
||||
- Falha no próprio envio (API do Z-PRO fora do ar, token inválido etc.) → fica
|
||||
registrada na execução do n8n (o sub-workflow já classifica o tipo de erro);
|
||||
não há novo retry automático nesta primeira versão.
|
||||
|
||||
## Suposições em aberto (validar no primeiro teste real)
|
||||
|
||||
- **Nome do campo da imagem no webhook** — assumimos algo como `mediaUrl` (por
|
||||
analogia com a API de saída do Z-PRO, que usa esse nome para anexar
|
||||
arquivos). Pode ser diferente; corrigido após ver o payload real de uma
|
||||
mensagem de imagem.
|
||||
- **Formato da mídia** — assumimos URL pública, não base64 inline. Se for
|
||||
base64, o node "Baixar imagem" é substituído por uma conversão local.
|
||||
- **Mecanismo de entrega do webhook para imagens** — os exemplos existentes
|
||||
nessa conta só cobrem texto (via um passo "Webhook" dentro de um ChatFlow do
|
||||
Z-PRO). Se imagens não passarem pelo mesmo tipo de passo, pode ser necessário
|
||||
configurar algo diferente no painel do Z-PRO — isso será resolvido junto com
|
||||
o usuário durante o teste.
|
||||
|
||||
## Plano de teste
|
||||
|
||||
1. Criar o workflow no n8n (inativo) e obter a URL de teste do webhook.
|
||||
2. Usuário configura essa URL como destino de mensagens do canal-alvo no
|
||||
painel do Z-PRO.
|
||||
3. Usuário envia uma foto real de pedido de exames para o número de teste.
|
||||
4. Inspecionar a execução no n8n para confirmar o payload real recebido e
|
||||
ajustar o node "Extrair campos do webhook" (e "Baixar imagem", se
|
||||
necessário).
|
||||
5. Validar que a resposta com o orçamento (lista de exemplo) chega
|
||||
corretamente no WhatsApp do cliente de teste.
|
||||
6. Trocar a lista de exemplo pela lista real de exames/valores no prompt do
|
||||
`AI Agent`.
|
||||
|
||||
## Fora de escopo (por enquanto)
|
||||
|
||||
- Fila/aprovação humana antes do envio (usuário optou por envio automático).
|
||||
- Fonte de preços fora do prompt (planilha/banco) — pode ser considerado no
|
||||
futuro se a lista crescer muito, mas não faz parte deste teste.
|
||||
- Retry automático em caso de falha de envio.
|
||||
Reference in New Issue
Block a user