fix(n8n): responde de forma sincrona (texto puro) e usa memoria simples

O Z-PRO captura a resposta HTTP do webhook e reenvia direto ao cliente
(variavel n8n1 -> passo Mensagem), entao o envio assincrono via API duplicava
a mensagem. Troca para responseMode: responseNode + Respond to Webhook em
texto puro, remove o node de envio assincrono, e troca a memoria de sessao
de Postgres (reservado para outro fluxo) para o node Simple Memory nativo.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Eric
2026-08-21 09:13:27 -03:00
co-authored by Claude Sonnet 5
parent 772747d74e
commit 314ccf5cdf
2 changed files with 160 additions and 185 deletions
@@ -205,11 +205,62 @@ agendamento desta conta (`Agendamento - GChat - Z-PRO (clínica exemplo)`):
Os dois testes reais feitos pelo usuário mostraram o webhook recebendo
`body: {}` (content-length 0, user-agent `axios/1.19.0`) — ou seja, o Z-PRO
não mandou `protocol`/`entrada`/`contactName`/`number` como os bots de
agendamento recebem. Isso sugere que a URL foi configurada num campo de
webhook diferente do usado pelo ChatFlow desses bots (que é o que gera esse
formato JSON). Ainda em aberto — precisa confirmar com o usuário onde
exatamente a URL foi cadastrada no painel do Z-PRO, e ajustar pro mesmo
mecanismo usado pelos bots que já funcionam (ChatFlow → passo "Webhook").
agendamento recebem. Causa raiz confirmada pelo usuário: no ChatFlow do
Z-PRO, o passo "Webhook Avançado" do fluxo de orçamento (`Menu Orçamento` /
`Menu Orçamento 2`) estava com o campo **Body** vazio, enquanto o do fluxo de
agendamento (`Menu Agendamento` / `Menu Agendamento 2`, que já funciona) tem:
```json
{
"step": "process",
"entrada": "{{entrada}}",
"number": "{{phoneNumber}}",
"contactName": "{{name}}",
"protocol": "{{protocol}}"
}
```
Ação do usuário: copiar o mesmo Body (com essas mesmas variáveis) para os
passos "Webhook Avançado" de `Menu Orçamento` e `Menu Orçamento 2`. Os nomes
de campo já batem com o que o node "Extrair campos do webhook" espera
(`body.protocol`, `body.number`, `body.contactName`, `body.entrada`) — não
precisou ajustar nada do lado do n8n para esses campos.
### Descoberta 2: o Z-PRO captura a resposta HTTP e reenvia ao cliente
Nas telas do ChatFlow, o passo "Webhook Avançado" tem uma seção "Resposta da
API (captura e roteamento)": ele salva o corpo da resposta HTTP do nosso
webhook numa variável (`n8n1`) e o passo seguinte ("Mensagem") manda
`{{n8n1}}` de volta ao cliente pelo WhatsApp. Ou seja, **o Z-PRO não usa a
API de envio de mensagens para essa resposta — ele repassa direto o que o
webhook devolver na hora**. Como o "Caminho no JSON" fica vazio, o corpo
precisa ser **texto puro**, não JSON.
Isso invalida a decisão original de "envio assíncrono via API do Z-PRO": o
workflow foi ajustado para responder de forma **síncrona**, com
`responseMode: responseNode` no Webhook e um node "Respond to Webhook"
(`respondWith: text`) devolvendo o texto final direto na resposta HTTP. O
node "Enviar orçamento (Z-PRO)" (chamada assíncrona ao sub-workflow
`enviar_texto`) foi removido — mantê-lo mandaria a mensagem duas vezes.
### Descoberta 3: memória de conversa
A credencial Postgres reaproveitada do bot de agendamento
(`Postgres Agendamento - (clínica exemplo)`) é de uso exclusivo daquele
fluxo — o usuário pediu para não usá-la aqui sem autorização explícita. A
memória de sessão agora usa o node nativo **Simple Memory**
(`memoryBufferWindow`, sem credencial), com `sessionKey` prefixado
(`orcamento-<protocolo ou telefone>`) para isolar as conversas de orçamento
das de agendamento.
### Ainda em aberto
Não há, até agora, nenhuma variável de mídia/imagem confirmada no seletor de
variáveis do ChatFlow do Z-PRO (o Body de `Menu Agendamento` só tem campos de
texto). Falta o usuário verificar, ao editar o Body do passo "Webhook
Avançado", se existe alguma variável de imagem/anexo no seletor (ícone "×")
— se existir, incluir no Body (ex.: `"mediaUrl": "{{variavel}}"`) e informar
o nome exato pra ajustar o node "Extrair campos do webhook".
## Fora de escopo (por enquanto)