This workflow follows the HTTP Request → OpenAI recipe pattern — see all workflows that pair these two integrations.
The workflow JSON
Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →
{
"name": "OTTO - \u00c9pico 2: Funil de Hip\u00f3tese (IA Sugere, Sistema Julga)",
"nodes": [
{
"parameters": {
"content": "## \ud83e\udde0 \u00c9pico 2: Funil de Hip\u00f3tese\n\n**Regra**: A IA interpreta a sem\u00e2ntica, mas uma m\u00e1quina de estados aprova a transi\u00e7\u00e3o.\n\n**Fluxo**:\n1. Recebe lead_id confirmado (do \u00c9pico 1) + transcri\u00e7\u00e3o\n2. LLM prop\u00f5e hip\u00f3tese de evento\n3. Code Node valida transi\u00e7\u00e3o cronol\u00f3gica\n4. Se v\u00e1lido \u2192 salva evento + incrementa version\n5. Se inv\u00e1lido \u2192 notifica vendedor da regra",
"height": 280,
"width": 420,
"color": 5
},
"id": "note-docs",
"name": "\ud83d\udccb Documenta\u00e7\u00e3o",
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"position": [
40,
40
]
},
{
"parameters": {
"httpMethod": "POST",
"path": "otto_hipotese_comercial",
"authentication": "headerAuth",
"responseMode": "responseNode",
"options": {}
},
"id": "webhook-hipotese",
"name": "Webhook: Hip\u00f3tese Comercial",
"type": "n8n-nodes-base.webhook",
"typeVersion": 2,
"position": [
260,
340
],
"credentials": {
"httpHeaderAuth": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"mode": "manual",
"duplicateItem": false,
"assignments": {
"assignments": [
{
"id": "lead_id",
"name": "lead_id",
"value": "={{ $json.lead_id }}",
"type": "string"
},
{
"id": "vendedor_id",
"name": "vendedor_id",
"value": "={{ $json.vendedor_id }}",
"type": "string"
},
{
"id": "vendedor_whatsapp",
"name": "vendedor_whatsapp",
"value": "={{ $json.vendedor_whatsapp }}",
"type": "string"
},
{
"id": "transcricao",
"name": "transcricao",
"value": "={{ $json.transcricao }}",
"type": "string"
},
{
"id": "estagio_atual",
"name": "estagio_atual",
"value": "={{ $json.estagio_atual }}",
"type": "string"
},
{
"id": "state_version",
"name": "state_version",
"value": "={{ $json.state_version }}",
"type": "number"
},
{
"id": "temperatura",
"name": "temperatura",
"value": "={{ $json.temperatura || 'morno' }}",
"type": "string"
}
]
},
"options": {}
},
"id": "set-vars",
"name": "Extrair Vari\u00e1veis",
"type": "n8n-nodes-base.set",
"typeVersion": 3.4,
"position": [
500,
340
]
},
{
"parameters": {
"model": "gpt-4o-mini",
"messages": {
"values": [
{
"content": "Voc\u00ea \u00e9 um analista comercial de concession\u00e1ria de ve\u00edculos premium.\n\nAnalise a transcri\u00e7\u00e3o do vendedor e proponha UMA hip\u00f3tese de evento comercial.\n\nEst\u00e1gios do funil (em ordem):\nCONTATO_INICIAL \u2192 QUALIFICACAO \u2192 VISITA_AGENDADA \u2192 VISITA_REALIZADA \u2192 PROPOSTA \u2192 NEGOCIACAO \u2192 APROVACAO_FINANCEIRA \u2192 FECHAMENTO \u2192 POS_VENDA\n\nTipos de evento poss\u00edveis:\n- AVANCO_ETAPA: progresso real na negocia\u00e7\u00e3o\n- OBJECAO_REGISTRADA: cliente levantou obje\u00e7\u00e3o (pre\u00e7o, prazo, financiamento)\n- PROPOSTA_ENVIADA: proposta formal foi apresentada\n- PROPOSTA_ACEITA / PROPOSTA_RECUSADA\n- TESTE_DRIVE: cliente fez/agendou test drive\n- FINANCIAMENTO_APROVADO / FINANCIAMENTO_RECUSADO\n- CONTRATO_ASSINADO\n- INTERACAO_INVALIDA: sauda\u00e7\u00f5es, respostas evasivas, sem avan\u00e7o real\n- LEAD_PERDIDO: cliente desistiu definitivamente\n\nEst\u00e1gio atual do lead: {{ $json.estagio_atual }}\n\nRetorne EXATAMENTE este JSON:\n{\n \"hipotese_evento\": \"TIPO_DO_EVENTO\",\n \"novo_estagio\": \"ESTAGIO_SUGERIDO ou null se n\u00e3o muda\",\n \"nivel_confianca\": 0-100,\n \"resumo_comercial\": \"Frase curta do que aconteceu\",\n \"objecao_detectada\": \"string ou null\",\n \"razao\": \"Por que voc\u00ea classificou assim\"\n}",
"role": "system"
},
{
"content": "={{ $json.transcricao }}",
"role": "user"
}
]
},
"options": {
"temperature": 0.2,
"maxTokens": 600
}
},
"id": "llm-hipotese",
"name": "LLM: Agente de Hip\u00f3tese",
"type": "@n8n/n8n-nodes-langchain.openAi",
"typeVersion": 1.4,
"position": [
740,
340
],
"credentials": {
"openAiApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"jsCode": "// VALIDADOR DE TRANSI\u00c7\u00c3O (M\u00e1quina de Estados Determin\u00edstica)\nconst vars = $('Extrair Vari\u00e1veis').first().json;\nconst llmRaw = $input.first().json;\n\nlet hipotese;\ntry {\n const raw = typeof llmRaw.text === 'string' ? llmRaw.text : JSON.stringify(llmRaw.text);\n hipotese = JSON.parse(raw.replace(/```json?\\n?/g, '').replace(/```/g, '').trim());\n} catch (e) {\n return [{ json: { ...vars, resultado: 'ERRO_PARSE', mensagem: 'N\u00e3o consegui interpretar o \u00e1udio. Pode repetir?' } }];\n}\n\n// Mapa de transi\u00e7\u00f5es v\u00e1lidas\nconst TRANSICOES = {\n 'CONTATO_INICIAL': ['QUALIFICACAO'],\n 'QUALIFICACAO': ['VISITA_AGENDADA'],\n 'VISITA_AGENDADA': ['VISITA_REALIZADA'],\n 'VISITA_REALIZADA': ['PROPOSTA'],\n 'PROPOSTA': ['NEGOCIACAO', 'QUALIFICACAO'],\n 'NEGOCIACAO': ['APROVACAO_FINANCEIRA', 'PROPOSTA'],\n 'APROVACAO_FINANCEIRA': ['FECHAMENTO', 'NEGOCIACAO'],\n 'FECHAMENTO': ['POS_VENDA']\n};\n\nconst evento = hipotese.hipotese_evento;\nconst novoEstagio = hipotese.novo_estagio;\n\n// INTERA\u00c7\u00c3O INV\u00c1LIDA - cron\u00f4metro n\u00e3o recome\u00e7a\nif (evento === 'INTERACAO_INVALIDA') {\n return [{ json: {\n ...vars,\n hipotese,\n resultado: 'INTERACAO_INVALIDA',\n evento_salvar: 'INTERACAO_INVALIDA',\n mensagem: `\ud83d\udcdd Anotado. Mas lembre-se: o rel\u00f3gio da ${vars.estagio_atual === 'PROPOSTA' ? 'proposta' : 'negocia\u00e7\u00e3o'} dele continua rodando.`,\n cronometro_reseta: false\n }}];\n}\n\n// Validar transi\u00e7\u00e3o cronol\u00f3gica\nif (novoEstagio && novoEstagio !== vars.estagio_atual) {\n const permitidas = TRANSICOES[vars.estagio_atual] || [];\n if (!permitidas.includes(novoEstagio)) {\n return [{ json: {\n ...vars,\n hipotese,\n resultado: 'TRANSICAO_INVALIDA',\n evento_salvar: null,\n mensagem: `\u26a0\ufe0f N\u00e3o posso mover de ${vars.estagio_atual} para ${novoEstagio}. O lead precisa passar pelas etapas intermedi\u00e1rias.`,\n cronometro_reseta: false\n }}];\n }\n}\n\n// EVENTO V\u00c1LIDO\nreturn [{ json: {\n ...vars,\n hipotese,\n resultado: 'EVENTO_VALIDO',\n evento_salvar: evento,\n novo_estagio: novoEstagio || vars.estagio_atual,\n mensagem: `\u2705 ${hipotese.resumo_comercial}\\n\\n\ud83d\udcca Confian\u00e7a: ${hipotese.nivel_confianca}%${hipotese.objecao_detectada ? '\\n\u26a0\ufe0f Obje\u00e7\u00e3o: ' + hipotese.objecao_detectada : ''}`,\n cronometro_reseta: true\n}}];"
},
"id": "validador-transicao",
"name": "Validador de Transi\u00e7\u00e3o",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
980,
340
]
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict"
},
"conditions": [
{
"id": "is-valid",
"leftValue": "={{ $json.resultado }}",
"rightValue": "EVENTO_VALIDO",
"operator": {
"type": "string",
"operation": "equals"
}
}
],
"combinator": "and"
}
},
"id": "if-evento-valido",
"name": "Evento V\u00e1lido?",
"type": "n8n-nodes-base.if",
"typeVersion": 2,
"position": [
1220,
340
]
},
{
"parameters": {
"operation": "executeQuery",
"query": "=INSERT INTO eventos_comerciais (lead_id, vendedor_id, tipo_evento, estagio_anterior, estagio_novo, evidencia_ia, nivel_confianca, state_version_at) VALUES ('{{ $json.lead_id }}', '{{ $json.vendedor_id }}', '{{ $json.evento_salvar }}', '{{ $json.estagio_atual }}', '{{ $json.novo_estagio }}', '{{ JSON.stringify($json.hipotese).replace(/'/g, \"''\") }}'::jsonb, {{ $json.hipotese.nivel_confianca }}, {{ $json.state_version }}); UPDATE leads SET estagio_funil = '{{ $json.novo_estagio }}', estagio_atual = '{{ $json.novo_estagio }}', ultima_interacao = NOW() WHERE id = '{{ $json.lead_id }}';",
"options": {}
},
"id": "salvar-evento",
"name": "Salvar Evento + Atualizar Lead",
"type": "n8n-nodes-base.postgres",
"typeVersion": 2.5,
"position": [
1460,
240
],
"credentials": {
"postgres": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"operation": "executeQuery",
"query": "=INSERT INTO eventos_comerciais (lead_id, vendedor_id, tipo_evento, evidencia_ia, nivel_confianca, state_version_at) VALUES ('{{ $('Extrair Vari\u00e1veis').first().json.lead_id }}', '{{ $('Extrair Vari\u00e1veis').first().json.vendedor_id }}', '{{ $json.evento_salvar || 'INTERACAO_INVALIDA' }}', '{{ JSON.stringify($json.hipotese || {}).replace(/'/g, \"''\") }}'::jsonb, {{ ($json.hipotese || {}).nivel_confianca || 0 }}, {{ $('Extrair Vari\u00e1veis').first().json.state_version }});",
"options": {}
},
"id": "salvar-interacao-invalida",
"name": "Registrar Intera\u00e7\u00e3o (Sem Avan\u00e7o)",
"type": "n8n-nodes-base.postgres",
"typeVersion": 2.5,
"position": [
1460,
460
],
"credentials": {
"postgres": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"method": "POST",
"url": "=https://graph.facebook.com/v18.0/{{ $env.WHATSAPP_PHONE_ID }}/messages",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth",
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={\n \"messaging_product\": \"whatsapp\",\n \"to\": \"{{ $('Extrair Vari\u00e1veis').first().json.vendedor_whatsapp }}\",\n \"type\": \"text\",\n \"text\": { \"body\": \"{{ $('Validador de Transi\u00e7\u00e3o').first().json.mensagem }}\" }\n}",
"options": {}
},
"id": "notificar-vendedor",
"name": "Notificar Vendedor",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
1700,
340
],
"credentials": {
"httpHeaderAuth": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"respondWith": "json",
"responseBody": "={\n \"success\": true,\n \"resultado\": \"{{ $('Validador de Transi\u00e7\u00e3o').first().json.resultado }}\",\n \"evento\": \"{{ $('Validador de Transi\u00e7\u00e3o').first().json.evento_salvar }}\",\n \"cronometro_reseta\": {{ $('Validador de Transi\u00e7\u00e3o').first().json.cronometro_reseta }}\n}",
"options": {}
},
"id": "respond-webhook",
"name": "Responder Webhook",
"type": "n8n-nodes-base.respondToWebhook",
"typeVersion": 1.1,
"position": [
1940,
340
]
}
],
"connections": {
"Webhook: Hip\u00f3tese Comercial": {
"main": [
[
{
"node": "Extrair Vari\u00e1veis",
"type": "main",
"index": 0
}
]
]
},
"Extrair Vari\u00e1veis": {
"main": [
[
{
"node": "LLM: Agente de Hip\u00f3tese",
"type": "main",
"index": 0
}
]
]
},
"LLM: Agente de Hip\u00f3tese": {
"main": [
[
{
"node": "Validador de Transi\u00e7\u00e3o",
"type": "main",
"index": 0
}
]
]
},
"Validador de Transi\u00e7\u00e3o": {
"main": [
[
{
"node": "Evento V\u00e1lido?",
"type": "main",
"index": 0
}
]
]
},
"Evento V\u00e1lido?": {
"main": [
[
{
"node": "Salvar Evento + Atualizar Lead",
"type": "main",
"index": 0
}
],
[
{
"node": "Registrar Intera\u00e7\u00e3o (Sem Avan\u00e7o)",
"type": "main",
"index": 0
}
]
]
},
"Salvar Evento + Atualizar Lead": {
"main": [
[
{
"node": "Notificar Vendedor",
"type": "main",
"index": 0
}
]
]
},
"Registrar Intera\u00e7\u00e3o (Sem Avan\u00e7o)": {
"main": [
[
{
"node": "Notificar Vendedor",
"type": "main",
"index": 0
}
]
]
},
"Notificar Vendedor": {
"main": [
[
{
"node": "Responder Webhook",
"type": "main",
"index": 0
}
]
]
}
},
"settings": {
"executionOrder": "v1"
},
"staticData": null,
"tags": [
{
"id": "otto-1",
"name": "OTTO"
},
{
"id": "otto-4",
"name": "Hip\u00f3tese"
},
{
"id": "otto-5",
"name": "\u00c9pico 2"
}
],
"triggerCount": 1,
"updatedAt": "2026-02-26T12:00:00.000Z",
"versionId": "1"
}
Credentials you'll need
Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.
httpHeaderAuthopenAiApipostgres
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
OTTO - Épico 2: Funil de Hipótese (IA Sugere, Sistema Julga). Uses openAi, postgres, httpRequest. Webhook trigger; 10 nodes.
Source: https://github.com/paraisolorrayne/Attra/blob/6dd06914bf6be4654e2cb2b445995786aa402cd3/automations/epico-2-funil-hipotese.json — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
Postgres. Uses openAi, postgres, postgresTool, httpRequest. Webhook trigger; 19 nodes.
Crop Planning. Uses postgres, httpRequest, respondToWebhook, googleGemini. Webhook trigger; 11 nodes.
OTTO - Épico 1: Resolução Determinística de Identidade. Uses openAi, postgres, httpRequest. Webhook trigger; 11 nodes.
Web Scraper with AI Extraction. Uses httpRequest, openAi, postgres. Webhook trigger; 7 nodes.
This n8n workflow automates the transformation of spreadsheet data into professional charts and graphs using AI-driven analysis. Triggered via Slack, it processes uploaded files (Excel, CSV, Google Sh