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": "\ud83e\udd16 Fluxo Principal \u2014 Peddi Order",
"nodes": [
{
"parameters": {
"httpMethod": "POST",
"path": "peddi-whatsapp-webhook",
"responseMode": "lastNode",
"options": {}
},
"name": "\ud83d\udce9 Webhook Trigger (WhatsApp)",
"type": "n8n-nodes-base.webhook",
"typeVersion": 1,
"position": [
0,
300
]
},
{
"parameters": {
"jsCode": "const body = $input.first().json.body;\nconst telefone = (body.telefone || body.from || '').toString().replace(/[^0-9]/g, '');\nconst mensagem = (body.mensagem || body.message || body.text || '').toString().trim().toLowerCase();\nconst restaurante_id = body.restaurante_id || body.business_id || '';\n\nreturn {\n telefone,\n mensagem,\n restaurante_id,\n message_type: body.type || 'text',\n raw: body\n};"
},
"name": "\ud83d\udd27 1. Normalizar entrada",
"type": "n8n-nodes-base.code",
"typeVersion": 1,
"position": [
250,
300
]
},
{
"parameters": {
"method": "GET",
"url": "={{ $env.SUPABASE_URL }}/rest/v1/sessoes?cliente_id=eq.{{ $json.telefone }}&restaurante_id=eq.{{ $json.restaurante_id }}&status=eq.ativa&select=*",
"authentication": "genericCredentialType",
"sendQuery": false,
"sendBody": false,
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "apikey",
"value": "={{ $env.SUPABASE_SERVICE_KEY }}"
},
{
"name": "Authorization",
"value": "Bearer {{ $env.SUPABASE_SERVICE_KEY }}"
}
]
}
},
"name": "\ud83d\udd0e 2. Buscar sess\u00e3o ativa",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 1,
"position": [
500,
300
]
},
{
"parameters": {
"jsCode": "const sessions = $input.first().json;\nif (Array.isArray(sessions) && sessions.length > 0) {\n return { session: sessions[0], exists: true };\n}\nreturn { session: null, exists: false };"
},
"name": "\ud83d\udd27 2b. Verificar se sess\u00e3o existe",
"type": "n8n-nodes-base.code",
"typeVersion": 1,
"position": [
750,
300
]
},
{
"parameters": {
"conditions": {
"boolean": [
{
"value1": "={{ $json.exists }}",
"value2": "true"
}
]
}
},
"name": "\u2753 Sess\u00e3o existe?",
"type": "n8n-nodes-base.if",
"typeVersion": 1,
"position": [
1000,
300
]
},
{
"parameters": {
"method": "POST",
"url": "={{ $env.SUPABASE_URL }}/rest/v1/sessoes",
"authentication": "genericCredentialType",
"sendBody": true,
"bodyParameters": {
"parameters": [
{
"name": "restaurante_id",
"value": "={{ $json.restaurante_id }}"
},
{
"name": "cliente_id",
"value": "={{ $json.telefone }}"
},
{
"name": "etapa_atual",
"value": "inicio"
},
{
"name": "carrinho",
"value": "[]"
},
{
"name": "bump_ofertado",
"value": "false"
},
{
"name": "upsell_ofertado",
"value": "false"
},
{
"name": "downsell_ofertado",
"value": "false"
},
{
"name": "status",
"value": "ativa"
}
]
},
"headerParameters": {
"parameters": [
{
"name": "apikey",
"value": "={{ $env.SUPABASE_SERVICE_KEY }}"
},
{
"name": "Authorization",
"value": "Bearer {{ $env.SUPABASE_SERVICE_KEY }}"
},
{
"name": "Content-Type",
"value": "application/json"
},
{
"name": "Prefer",
"value": "return=representation"
}
]
}
},
"name": "\ud83c\udd95 2c. Criar nova sess\u00e3o",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 1,
"position": [
1250,
200
]
},
{
"parameters": {
"method": "GET",
"url": "={{ $env.SUPABASE_URL }}/rest/v1/restaurantes?id=eq.{{ $json.restaurante_id }}&select=*",
"authentication": "genericCredentialType",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "apikey",
"value": "={{ $env.SUPABASE_SERVICE_KEY }}"
},
{
"name": "Authorization",
"value": "Bearer {{ $env.SUPABASE_SERVICE_KEY }}"
}
]
}
},
"name": "\ud83c\udfea 3. Buscar restaurante",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 1,
"position": [
1250,
400
]
},
{
"parameters": {
"jsCode": "const data = $input.first().json;\nconst restaurante = Array.isArray(data) ? data[0] : data;\nconst agora = new Date();\nconst horaAtual = agora.getHours() * 60 + agora.getMinutes();\n\nfunction toMinutos(h) {\n if (!h) return null;\n const partes = h.split(':').map(Number);\n return partes[0] * 60 + (partes[1] || 0);\n}\n\nconst abertura = toMinutos(restaurante.horario_abertura);\nconst fechamento = toMinutos(restaurante.horario_fechamento);\n\nlet aberto = true;\nlet motivo = '';\n\nif (!restaurante.ativo) {\n aberto = false;\n motivo = 'Estamos fechados no momento! Aguarde nosso retorno. \ud83d\ude0a';\n} else if (abertura !== null && fechamento !== null) {\n if (horaAtual < abertura || horaAtual > fechamento) {\n aberto = false;\n motivo = `Estamos fechados! Abrimos \u00e0s ${restaurante.horario_abertura}. \ud83d\ude0a`;\n }\n}\n\nreturn {\n restaurante,\n aberto,\n motivo,\n horaAtual,\n abertura,\n fechamento\n};"
},
"name": "\ud83d\udd27 3b. Validar hor\u00e1rio",
"type": "n8n-nodes-base.code",
"typeVersion": 1,
"position": [
1500,
400
]
},
{
"parameters": {
"conditions": {
"boolean": [
{
"value1": "={{ $json.aberto }}",
"value2": "true"
}
]
}
},
"name": "\u2753 Est\u00e1 aberto?",
"type": "n8n-nodes-base.if",
"typeVersion": 1,
"position": [
1750,
400
]
},
{
"parameters": {
"jsCode": "const data = $input.first().json;\n// Enviar mensagem de fechado via Z-API\nconst telefone = data.telefone || data.cliente?.telefone;\nconst message = data.motivo || 'Estamos fechados! \ud83d\ude0a';\n\n// This node signals the webhook response\nreturn {\n to: telefone,\n message,\n action: 'send_message'\n};"
},
"name": "\ud83d\udeab Enviar fora do hor\u00e1rio",
"type": "n8n-nodes-base.code",
"typeVersion": 1,
"position": [
2000,
500
]
},
{
"parameters": {
"jsCode": "// Merge session data with input\nconst input = $input.first().json;\nconst sessionData = $('\ud83d\udd0e 2. Buscar sess\u00e3o ativa').first().json;\nconst session = Array.isArray(sessionData) && sessionData.length > 0 ? sessionData[0] : null;\n\nconst menuMsg = input.mensagem;\nconst etapa = session?.etapa_atual || 'inicio';\nconst carrinho = session?.carrinho || [];\n\n// Comandos globais\nif (menuMsg === 'cancelar') {\n return { acao: 'cancelar', etapa, carrinho };\n}\n\nswitch (etapa) {\n case 'inicio': return { acao: 'boas_vindas', etapa, carrinho };\n case 'menu': return { acao: 'categoria', etapa, carrinho, opcao: menuMsg };\n case 'categoria': return { acao: 'adicionar_item', etapa, carrinho, opcao: menuMsg };\n case 'bump': return { acao: 'resposta_bump', etapa, carrinho, opcao: menuMsg };\n case 'carrinho':\n if (menuMsg === '2') return { acao: 'upsell', etapa, carrinho };\n return { acao: 'adicionar_mais', etapa, carrinho };\n case 'upsell':\n if (menuMsg === '1') return { acao: 'aceitar_upsell', etapa, carrinho };\n return { acao: 'downsell', etapa, carrinho };\n case 'downsell':\n if (menuMsg === '1') return { acao: 'aceitar_downsell', etapa, carrinho };\n return { acao: 'localizacao', etapa, carrinho };\n case 'localizacao': return { acao: 'coletar_pagamento', etapa, carrinho, localizacao: menuMsg };\n case 'pagamento': return { acao: 'confirmar', etapa, carrinho, pagamento: input.pagamento || menuMsg };\n case 'confirmacao':\n if (menuMsg === '1') return { acao: 'handoff', etapa, carrinho };\n if (menuMsg === '2') return { acao: 'editar', etapa, carrinho };\n return { acao: 'cancelar', etapa, carrinho };\n default: return { acao: 'menu', etapa, carrinho };\n}"
},
"name": "\ud83d\udd00 4. Roteador principal",
"type": "n8n-nodes-base.code",
"typeVersion": 1,
"position": [
1500,
200
]
},
{
"parameters": {
"conditions": {
"string": [
{
"value1": "={{ $json.acao }}",
"value2": "boas_vindas"
}
]
}
},
"name": "\u2753 Rota: Boas-vindas?",
"type": "n8n-nodes-base.if",
"typeVersion": 1,
"position": [
1750,
100
]
},
{
"parameters": {
"method": "GET",
"url": "={{ $env.SUPABASE_URL }}/rest/v1/clientes?telefone=eq.{{ $json.telefone }}&restaurante_id=eq.{{ $json.restaurante_id }}&select=*",
"authentication": "genericCredentialType",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "apikey",
"value": "={{ $env.SUPABASE_SERVICE_KEY }}"
},
{
"name": "Authorization",
"value": "Bearer {{ $env.SUPABASE_SERVICE_KEY }}"
}
]
}
},
"name": "\ud83d\udc64 5. Buscar/cliente",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 1,
"position": [
2000,
0
]
},
{
"parameters": {
"jsCode": "const clienteData = $input.first().json;\nconst cliente = Array.isArray(clienteData) ? clienteData[0] : clienteData;\nconst restaurante = $('\ud83c\udfea 3. Buscar restaurante').first().json;\nconst r = Array.isArray(restaurante) ? restaurante[0] : restaurante;\nconst nomeRestaurante = r?.nome || 'Restaurante';\n\nlet message = '';\nlet isNovo = false;\n\nif (!cliente || cliente.total_pedidos === 0) {\n isNovo = true;\n message = `Bem-vindo(a) ao ${nomeRestaurante}! \ud83d\udc4b\\n\\nSomos especialistas em deliver! \ud83d\ude0a\\n\\n1\ufe0f\u20e3 Ver card\u00e1pio\\n2\ufe0f\u20e3 Repetir \u00faltimo pedido\\n3\ufe0f\u20e3 Falar com atendente`;\n} else {\n message = `Ol\u00e1 ${cliente.nome}! Que bom ter voc\u00ea de volta! \ud83d\ude0a\\n\\n1\ufe0f\u20e3 Ver card\u00e1pio\\n2\ufe0f\u20e3 Repetir \u00faltimo pedido\\n3\ufe0f\u20e3 Falar com atendente`;\n}\n\nreturn { message, isNovo, nome: cliente?.nome || '', total_pedidos: cliente?.total_pedidos || 0 };"
},
"name": "\ud83d\udcac 5b. Montar boas-vindas",
"type": "n8n-nodes-base.code",
"typeVersion": 1,
"position": [
2250,
0
]
},
{
"parameters": {
"method": "GET",
"url": "={{ $env.SUPABASE_URL }}/rest/v1/cardapio?restaurante_id=eq.{{ $json.restaurante_id }}&disponivel=eq.true&select=distinct.categoria",
"authentication": "genericCredentialType",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "apikey",
"value": "={{ $env.SUPABASE_SERVICE_KEY }}"
},
{
"name": "Authorization",
"value": "Bearer {{ $env.SUPABASE_SERVICE_KEY }}"
}
]
}
},
"name": "\ud83d\udccb 6. Card\u00e1pio din\u00e2mico",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 1,
"position": [
2000,
200
]
},
{
"parameters": {
"jsCode": "const categorias = $input.first().json;\nconst lista = Array.isArray(categorias) ? categorias : [];\n\nlet message = '\ud83c\udf7d\ufe0f Card\u00e1pio:\\n\\n';\nlista.forEach((cat, i) => {\n message += `${i + 1}\ufe0f\u20e3 ${cat.categoria}\\n`;\n});\nmessage += '\\n0\ufe0f\u20e3 Voltar';\n\nreturn {\n message,\n categorias: lista,\n categoria_atual: null\n};"
},
"name": "\ud83d\udcac 6b. Montar lista categorias",
"type": "n8n-nodes-base.code",
"typeVersion": 1,
"position": [
2250,
200
]
},
{
"parameters": {
"method": "GET",
"url": "={{ $env.SUPABASE_URL }}/rest/v1/cardapio?restaurante_id=eq.{{ $json.restaurante_id }}&disponivel=eq.true&order=nome.asc",
"authentication": "genericCredentialType",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "apikey",
"value": "={{ $env.SUPABASE_SERVICE_KEY }}"
},
{
"name": "Authorization",
"value": "Bearer {{ $env.SUPABASE_SERVICE_KEY }}"
}
]
}
},
"name": "\ud83c\udf54 7. Buscar itens do card\u00e1pio",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 1,
"position": [
2250,
400
]
},
{
"parameters": {
"jsCode": "const itens = $input.first().json;\nconst lista = Array.isArray(itens) ? itens : [];\nconst opcao = parseInt($('\ud83d\udd00 4. Roteador principal').first().json.opcao) - 1;\nconst categorias = $('\ud83d\udccb 6. Card\u00e1pio din\u00e2mico').first().json;\nconst cats = Array.isArray(categorias) ? categorias : [];\n\n// Se estamos na etapa categoria, filtra pela categoria escolhida\nconst etapa = $('\ud83d\udd00 4. Roteador principal').first().json.etapa;\n\nlet itensFiltrados;\nif (etapa === 'categoria' && cats[opcao]) {\n const catNome = cats[opcao].categoria;\n itensFiltrados = lista.filter(i => i.categoria === catNome);\n} else {\n itensFiltrados = lista;\n}\n\nlet message = 'Itens dispon\u00edveis:\\n\\n';\nitensFiltrados.forEach((item, i) => {\n message += `${i + 1}\ufe0f\u20e3 ${item.nome} \u2014 R$ ${item.preco.toFixed(2)}\\n`;\n if (item.descricao) message += ` ${item.descricao}\\n`;\n});\nmessage += '\\n0\ufe0f\u20e3 Voltar';\n\nreturn {\n message,\n itens: itensFiltrados,\n item_escolhido: null\n};"
},
"name": "\ud83d\udcac 7b. Montar lista itens",
"type": "n8n-nodes-base.code",
"typeVersion": 1,
"position": [
2500,
400
]
},
{
"parameters": {
"jsCode": "const itens = $('\ud83c\udf54 7. Buscar itens do card\u00e1pio').first().json;\nconst lista = Array.isArray(itens) ? itens : [];\nconst opcao = parseInt($('\ud83d\udd00 4. Roteador principal').first().json.opcao || '0');\nconst carrinhoAtual = $('\ud83d\udd00 4. Roteador principal').first().json.carrinho || [];\n\nif (opcao <= 0 || opcao > lista.length) {\n return { acao: 'invalido', carrinho: carrinhoAtual };\n}\n\nconst itemEscolhido = lista[opcao - 1];\nconst novoCarrinho = [...carrinhoAtual, {\n id: itemEscolhido.id,\n nome: itemEscolhido.nome,\n preco: itemEscolhido.preco,\n categoria: itemEscolhido.categoria\n}];\n\n// Verificar se tem bump\nif (itemEscolhido.bump_sugerido_id) {\n return {\n acao: 'bump',\n carrinho: novoCarrinho,\n item_adicionado: itemEscolhido,\n bump_id: itemEscolhido.bump_sugerido_id,\n bump_preco: itemEscolhido.bump_preco,\n bump_nome: ''\n };\n}\n\nreturn {\n acao: 'carrinho',\n carrinho: novoCarrinho,\n item_adicionado: itemEscolhido,\n bump_id: null\n};"
},
"name": "\u2795 7c. Adicionar item ao carrinho",
"type": "n8n-nodes-base.code",
"typeVersion": 1,
"position": [
2750,
400
]
},
{
"parameters": {
"method": "GET",
"url": "={{ $env.SUPABASE_URL }}/rest/v1/cardapio?id=eq.{{ $json.bump_id }}&select=*",
"authentication": "genericCredentialType",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "apikey",
"value": "={{ $env.SUPABASE_SERVICE_KEY }}"
},
{
"name": "Authorization",
"value": "Bearer {{ $env.SUPABASE_SERVICE_KEY }}"
}
]
}
},
"name": "\ud83d\udd0d Buscar bump sugerido",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 1,
"position": [
3000,
300
]
},
{
"parameters": {
"jsCode": "const bumpData = $input.first().json;\nconst bump = Array.isArray(bumpData) ? bumpData[0] : bumpData;\n\nreturn {\n message: `\u2705 Item adicionado!\\n\\n\ud83d\udd25 Por +R$ ${bump.preco.toFixed(2)} adicione ${bump.nome}!\\n\\n1\ufe0f\u20e3 Sim\\n2\ufe0f\u20e3 N\u00e3o obrigado`,\n bump_item: bump\n};"
},
"name": "\ud83d\udcac 8a. Montar oferta bump",
"type": "n8n-nodes-base.code",
"typeVersion": 1,
"position": [
3250,
300
]
},
{
"parameters": {
"jsCode": "const input = $input.first().json;\nconst carrinhoAtual = $('\ud83d\udd00 4. Roteador principal').first().json.carrinho || [];\nconst opcao = $('\ud83d\udd00 4. Roteador principal').first().json.opcao || '';\n\nif (opcao === '1') {\n // Aceitou bump\n const bumpItem = $('\ud83d\udd0d Buscar bump sugerido').first().json;\n const bump = Array.isArray(bumpItem) ? bumpItem[0] : bumpItem;\n const novoCarrinho = [...carrinhoAtual, {\n id: bump.id,\n nome: `${bump.nome} (bump)`,\n preco: bump.preco,\n categoria: bump.categoria\n }];\n\n return {\n acao: 'carrinho',\n carrinho: novoCarrinho,\n message: '\u00d3timo! Adicionado! \ud83c\udf89\\n\\n1\ufe0f\u20e3 Adicionar mais\\n2\ufe0f\u20e3 Fechar pedido',\n bump_aceito: true\n };\n}\n\nreturn {\n acao: 'carrinho',\n carrinho: carrinhoAtual,\n message: 'Tudo bem! \ud83d\ude0a\\n\\n1\ufe0f\u20e3 Adicionar mais\\n2\ufe0f\u20e3 Fechar pedido',\n bump_aceito: false\n};"
},
"name": "\ud83d\udd27 8b. Processar resposta bump",
"type": "n8n-nodes-base.code",
"typeVersion": 1,
"position": [
3000,
500
]
},
{
"parameters": {
"jsCode": "const carrinho = $('\ud83d\udd00 4. Roteador principal').first().json.carrinho || [];\nconst sessionData = $('\ud83d\udd0e 2. Buscar sess\u00e3o ativa').first().json;\nconst session = Array.isArray(sessionData) && sessionData.length > 0 ? sessionData[0] : null;\n\n// Verificar upsell j\u00e1 ofertado\nif (session?.upsell_ofertado) {\n return { acao: 'pular_upsell', carrinho, upsell_ofertado: true };\n}\n\nconst restauranteData = $('\ud83c\udfea 3. Buscar restaurante').first().json;\nconst restaurante = Array.isArray(restauranteData) ? restauranteData[0] : restauranteData;\nconst ticketMedio = restaurante?.ticket_medio || 30;\n\nconst totalAtual = carrinho.reduce((sum, item) => sum + (item.preco || 0), 0);\n\nif (totalAtual < ticketMedio) {\n // Buscar item de upsell\n return {\n acao: 'oferecer_upsell',\n carrinho,\n totalAtual,\n diferenca: ticketMedio - totalAtual,\n upsell_ofertado: false\n };\n}\n\nreturn { acao: 'pular_upsell', carrinho, upsell_ofertado: false };"
},
"name": "\ud83d\udcb8 9. Verificar upsell",
"type": "n8n-nodes-base.code",
"typeVersion": 1,
"position": [
2750,
600
]
},
{
"parameters": {
"method": "GET",
"url": "={{ $env.SUPABASE_URL }}/rest/v1/cardapio?restaurante_id=eq.{{ $json.restaurante_id }}&disponivel=eq.true&order=preco.desc&limit=1&select=*",
"authentication": "genericCredentialType",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "apikey",
"value": "={{ $env.SUPABASE_SERVICE_KEY }}"
},
{
"name": "Authorization",
"value": "Bearer {{ $env.SUPABASE_SERVICE_KEY }}"
}
]
}
},
"name": "\ud83d\udd0d Buscar item upsell",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 1,
"position": [
3000,
600
]
},
{
"parameters": {
"jsCode": "const upsellData = $input.first().json;\nconst upsell = Array.isArray(upsellData) ? upsellData[0] : upsellData;\nconst diff = $('\ud83d\udcb8 9. Verificar upsell').first().json.diferenca;\n\nif (!upsell) {\n return { acao: 'pular_upsell', message: '' };\n}\n\nreturn {\n acao: 'mostrar_upsell',\n message: `\ud83c\udf54 Que tal completar seu pedido?\\n\\nAdicione ${upsell.nome} por apenas R$ ${upsell.preco.toFixed(2)}!\\n\\n1\ufe0f\u20e3 Aceitar\\n2\ufe0f\u20e3 N\u00e3o obrigado`,\n upsell_item: upsell\n};"
},
"name": "\ud83d\udcac 9b. Montar oferta upsell",
"type": "n8n-nodes-base.code",
"typeVersion": 1,
"position": [
3250,
600
]
},
{
"parameters": {
"jsCode": "const opcao = $('\ud83d\udd00 4. Roteador principal').first().json.opcao || '';\nconst carrinhoAtual = $('\ud83d\udcb8 9. Verificar upsell').first().json.carrinho || [];\n\nif (opcao === '1') {\n const upsellItem = $('\ud83d\udd0d Buscar item upsell').first().json;\n const item = Array.isArray(upsellItem) ? upsellItem[0] : upsellItem;\n const novoCarrinho = [...carrinhoAtual, {\n id: item.id,\n nome: `${item.nome} (upsell)`,\n preco: item.preco,\n categoria: item.categoria\n }];\n\n return {\n acao: 'localizacao',\n carrinho: novoCarrinho,\n message: '',\n upsell_aceito: true\n };\n}\n\nreturn {\n acao: 'downsell',\n carrinho: carrinhoAtual,\n message: '',\n upsell_aceito: false\n};"
},
"name": "\ud83d\udd27 9c. Processar resposta upsell",
"type": "n8n-nodes-base.code",
"typeVersion": 1,
"position": [
3500,
600
]
},
{
"parameters": {
"jsCode": "const sessionData = $('\ud83d\udd0e 2. Buscar sess\u00e3o ativa').first().json;\nconst session = Array.isArray(sessionData) && sessionData.length > 0 ? sessionData[0] : null;\nconst carrinhoAtual = $('\ud83d\udd00 4. Roteador principal').first().json.carrinho || [];\n\nif (session?.downsell_ofertado) {\n return { acao: 'pular_downsell', carrinho: carrinhoAtual };\n}\n\nreturn {\n acao: 'oferecer_downsell',\n carrinho: carrinhoAtual,\n downsell_ofertado: false\n};"
},
"name": "\ud83d\udcb8 10. Verificar downsell",
"type": "n8n-nodes-base.code",
"typeVersion": 1,
"position": [
2750,
800
]
},
{
"parameters": {
"method": "GET",
"url": "={{ $env.SUPABASE_URL }}/rest/v1/cardapio?restaurante_id=eq.{{ $json.restaurante_id }}&disponivel=eq.true&order=preco.asc&limit=1&select=*",
"authentication": "genericCredentialType",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "apikey",
"value": "={{ $env.SUPABASE_SERVICE_KEY }}"
},
{
"name": "Authorization",
"value": "Bearer {{ $env.SUPABASE_SERVICE_KEY }}"
}
]
}
},
"name": "\ud83d\udd0d Buscar item downsell",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 1,
"position": [
3000,
800
]
},
{
"parameters": {
"jsCode": "const downsellData = $input.first().json;\nconst downsell = Array.isArray(downsellData) ? downsellData[0] : downsellData;\n\nif (!downsell) {\n return { acao: 'pular_downsell', message: '' };\n}\n\nreturn {\n acao: 'mostrar_downsell',\n message: `\ud83d\ude0a Tudo bem! Que tal experimentar ${downsell.nome} por apenas R$ ${downsell.preco.toFixed(2)}?\\n\\n1\ufe0f\u20e3 Sim\\n2\ufe0f\u20e3 N\u00e3o, quero finalizar`,\n downsell_item: downsell\n};"
},
"name": "\ud83d\udcac 10b. Montar oferta downsell",
"type": "n8n-nodes-base.code",
"typeVersion": 1,
"position": [
3250,
800
]
},
{
"parameters": {
"jsCode": "const opcao = $('\ud83d\udd00 4. Roteador principal').first().json.opcao || '';\nconst carrinhoAtual = $('\ud83d\udcb8 10. Verificar downsell').first().json.carrinho || [];\n\nif (opcao === '1') {\n const downsellItem = $('\ud83d\udd0d Buscar item downsell').first().json;\n const item = Array.isArray(downsellItem) ? downsellItem[0] : downsellItem;\n const novoCarrinho = [...carrinhoAtual, {\n id: item.id,\n nome: `${item.nome} (downsell)`,\n preco: item.preco,\n categoria: item.categoria\n }];\n\n return {\n acao: 'localizacao',\n carrinho: novoCarrinho,\n message: '',\n downsell_aceito: true\n };\n}\n\nreturn {\n acao: 'localizacao',\n carrinho: carrinhoAtual,\n message: '',\n downsell_aceito: false\n};"
},
"name": "\ud83d\udd27 10c. Processar resposta downsell",
"type": "n8n-nodes-base.code",
"typeVersion": 1,
"position": [
3500,
800
]
},
{
"parameters": {
"jsCode": "return {\n message: '\ud83d\udccd Seu pedido \u00e9 para:\\n\\n1\ufe0f\u20e3 Entrega (delivery)\\n2\ufe0f\u20e3 Retirada no balc\u00e3o\\n\\n0\ufe0f\u20e3 Voltar'\n};"
},
"name": "\ud83d\udcac 11. Perguntar localiza\u00e7\u00e3o",
"type": "n8n-nodes-base.code",
"typeVersion": 1,
"position": [
2750,
1000
]
},
{
"parameters": {
"jsCode": "const input = $input.first().json;\nconst opcao = $('\ud83d\udd00 4. Roteador principal').first().json.opcao || '';\n\nlet tipo = '';\nlet message = '';\n\nif (opcao === '1') {\n tipo = 'entrega';\n message = '\ud83d\udccd Manda seu endere\u00e7o: Rua, n\u00famero, bairro';\n} else if (opcao === '2') {\n tipo = 'retirada';\n message = '\ud83d\udecd\ufe0f OK! Retirada no balc\u00e3o!\\n\\nQual forma de pagamento?';\n}\n\nreturn { tipo, message, endereco: null };"
},
"name": "\ud83d\udd27 11b. Processar tipo entrega",
"type": "n8n-nodes-base.code",
"typeVersion": 1,
"position": [
3000,
1000
]
},
{
"parameters": {
"method": "GET",
"url": "={{ $env.SUPABASE_URL }}/rest/v1/restaurantes?id=eq.{{ $json.restaurante_id }}&select=formas_pagamento&select=*",
"authentication": "genericCredentialType",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "apikey",
"value": "={{ $env.SUPABASE_SERVICE_KEY }}"
},
{
"name": "Authorization",
"value": "Bearer {{ $env.SUPABASE_SERVICE_KEY }}"
}
]
}
},
"name": "\ud83d\udcb3 12. Buscar formas pagamento",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 1,
"position": [
2750,
1200
]
},
{
"parameters": {
"jsCode": "const pagData = $input.first().json;\nconst restaurante = Array.isArray(pagData) ? pagData[0] : pagData;\nconst formas = restaurante?.formas_pagamento || ['Pix', 'Dinheiro', 'Cart\u00e3o', 'D\u00e9bito'];\n\nlet message = '\ud83d\udcb3 Formas de pagamento:\\n\\n';\nformas.forEach((f, i) => {\n message += `${i + 1}\ufe0f\u20e3 ${f}\\n`;\n});nmessage += '\\n0\ufe0f\u20e3 Voltar';\n\nreturn { message, formas };"
},
"name": "\ud83d\udcac 12b. Montar menu pagamento",
"type": "n8n-nodes-base.code",
"typeVersion": 1,
"position": [
3000,
1200
]
},
{
"parameters": {
"jsCode": "const opcaoIndex = parseInt($('\ud83d\udd00 4. Roteador principal').first().json.opcao || '0') - 1;\nconst formas = $('\ud83d\udcac 12b. Montar menu pagamento').first().json.formas || [];\nconst pagamento = formas[opcaoIndex] || 'Pix';\n\nlet message = pagamento === 'Dinheiro' ? '\ud83d\udcb0 Troco para quanto?' : '';\n\nreturn { pagamento, precisa_troco: pagamento === 'Dinheiro', message };"
},
"name": "\ud83d\udd27 12c. Processar pagamento",
"type": "n8n-nodes-base.code",
"typeVersion": 1,
"position": [
3250,
1200
]
},
{
"parameters": {
"jsCode": "const carrinho = $('\ud83d\udd00 4. Roteador principal').first().json.carrinho || [];\nconst restauranteData = $('\ud83c\udfea 3. Buscar restaurante').first().json;\nconst restaurante = Array.isArray(restauranteData) ? restauranteData[0] : restauranteData;\nconst tipo = $('\ud83d\udd27 11b. Processar tipo entrega').first().json.tipo;\nconst pagamento = $('\ud83d\udd27 12c. Processar pagamento').first().json.pagamento;\nconst troco = $('\ud83d\udd00 4. Roteador principal').first().json.opcao || null;\n\nconst totalItens = carrinho.reduce((sum, item) => sum + (item.preco || 0), 0);\nconst freteGratis = restaurante?.valor_frete_gratis || 50;\nconst frete = totalItens >= freteGratis ? 0 : (restaurante?.valor_minimo || 5);\nconst totalFinal = totalItens + frete;\n\nconst endereco = $('\ud83d\udd27 11b. Processar tipo entrega').first().json.endereco || 'A confirmar';\n\nlet resumo = `\ud83d\udccb RESUMO DO PEDIDO\\n\\n`;\ncarrinho.forEach((item, i) => {\n resumo += `${i + 1}x ${item.nome} \u2014 R$ ${item.preco.toFixed(2)}\\n`;\n});\nresumo += `\\n\ud83d\udcb0 Total itens: R$ ${totalItens.toFixed(2)}`;\nresumo += `\\n\ud83d\ude9a Frete: ${frete === 0 ? 'GR\u00c1TIS \ud83c\udf89' : 'R$ ' + frete.toFixed(2)}`;\nresumo += `\\n\ud83d\udcb5 Total final: R$ ${totalFinal.toFixed(2)}`;\nresumo += `\\n\ud83d\udccd ${tipo === 'entrega' ? 'Entrega em: ' + endereco : 'Retirada no balc\u00e3o'}`;\nresumo += `\\n\ud83d\udcb3 Pagamento: ${pagamento}`;\nif (troco) resumo += `\\n\ud83d\udcb0 Troco para: R$ ${troco}`;\nresumo += `\\n\\n1\ufe0f\u20e3 \u2705 Confirmar\\n2\ufe0f\u20e3 \u270f\ufe0f Editar\\n3\ufe0f\u20e3 \u274c Cancelar`;\n\nreturn {\n message: resumo,\n total_itens: totalItens,\n frete,\n total_final: totalFinal,\n tipo,\n endereco,\n pagamento,\n troco\n};"
},
"name": "\ud83d\udccb 13. Montar resumo + confirma\u00e7\u00e3o",
"type": "n8n-nodes-base.code",
"typeVersion": 1,
"position": [
2750,
1400
]
},
{
"parameters": {
"jsCode": "const sessionData = $('\ud83d\udd0e 2. Buscar sess\u00e3o ativa').first().json;\nconst session = Array.isArray(sessionData) && sessionData.length > 0 ? sessionData[0] : null;\nconst clienteData = $('\ud83d\udc64 5. Buscar/cliente').first().json;\nconst cliente = Array.isArray(clienteData) ? clienteData[0] : clienteData;\nconst resumo = $('\ud83d\udccb 13. Montar resumo + confirma\u00e7\u00e3o').first().json;\nconst bumps = resumo.itens?.filter(i => i.nome?.includes('(bump)')) || [];\n\nconst pedido = {\n restaurante_id: $json.restaurante_id,\n cliente_id: cliente?.id || $json.telefone,\n itens: (resumo.itens || []).map(i => ({\n nome: i.nome?.replace(' (bump)', '').replace(' (upsell)', '').replace(' (downsell)', ''),\n preco: i.preco\n })),\n bumps: bumps.map(b => ({ nome: b.nome, preco: b.preco })),\n upsell: $('\ud83d\udd27 9c. Processar resposta upsell').first().json.upsell_aceito || false,\n total: resumo.total_final,\n tipo: resumo.tipo,\n endereco: resumo.endereco,\n pagamento: resumo.pagamento,\n troco: resumo.troco,\n status: 'aguardando_pagamento'\n};\n\nreturn { pedido, message: '' };"
},
"name": "\ud83d\udce6 14. Montar payload pedido",
"type": "n8n-nodes-base.code",
"typeVersion": 1,
"position": [
3000,
1600
]
},
{
"parameters": {
"method": "POST",
"url": "={{ $env.SUPABASE_URL }}/rest/v1/pedidos",
"authentication": "genericCredentialType",
"sendBody": true,
"bodyParameters": {
"parameters": [
{
"name": "restaurante_id",
"value": "={{ $json.pedido.restaurante_id }}"
},
{
"name": "cliente_id",
"value": "={{ $json.pedido.cliente_id }}"
},
{
"name": "itens",
"value": "={{ $json.pedido.itens }}"
},
{
"name": "bumps",
"value": "={{ $json.pedido.bumps }}"
},
{
"name": "upsell",
"value": "={{ $json.pedido.upsell }}"
},
{
"name": "total",
"value": "={{ $json.pedido.total }}"
},
{
"name": "tipo",
"value": "={{ $json.pedido.tipo }}"
},
{
"name": "endereco",
"value": "={{ $json.pedido.endereco }}"
},
{
"name": "pagamento",
"value": "={{ $json.pedido.pagamento }}"
},
{
"name": "troco",
"value": "={{ $json.pedido.troco }}"
},
{
"name": "status",
"value": "={{ $json.pedido.status }}"
}
]
},
"headerParameters": {
"parameters": [
{
"name": "apikey",
"value": "={{ $env.SUPABASE_SERVICE_KEY }}"
},
{
"name": "Authorization",
"value": "Bearer {{ $env.SUPABASE_SERVICE_KEY }}"
},
{
"name": "Content-Type",
"value": "application/json"
},
{
"name": "Prefer",
"value": "return=representation"
}
]
}
},
"name": "\ud83d\udcbe 14b. Salvar pedido no Supabase",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 1,
"position": [
3250,
1600
]
},
{
"parameters": {
"method": "PATCH",
"url": "={{ $env.SUPABASE_URL }}/rest/v1/sessoes?id=eq.{{ $json.session_id }}",
"authentication": "genericCredentialType",
"sendBody": true,
"bodyParameters": {
"parameters": [
{
"name": "status",
"value": "aguardando_pagamento"
},
{
"name": "etapa_atual",
"value": "finalizado"
}
]
},
"headerParameters": {
"parameters": [
{
"name": "apikey",
"value": "={{ $env.SUPABASE_SERVICE_KEY }}"
},
{
"name": "Authorization",
"value": "Bearer {{ $env.SUPABASE_SERVICE_KEY }}"
},
{
"name": "Content-Type",
"value": "application/json"
}
]
}
},
"name": "\ud83d\udd04 14c. Atualizar sess\u00e3o",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 1,
"position": [
3500,
1600
]
},
{
"parameters": {
"jsCode": "const pedidoId = $('\ud83d\udcbe 14b. Salvar pedido no Supabase').first().json[0]?.id || '';\n\nreturn {\n to: $json.telefone,\n message: `\u2705 Pedido #${pedidoId.slice(0, 8)} recebido!\\n\\nUm atendente vai confirmar seu pagamento agora. Em breve voc\u00ea recebe a confirma\u00e7\u00e3o! \ud83d\ude0a\\n\\nAcompanhe pelo WhatsApp. \ud83d\ude80`\n};"
},
"name": "\ud83d\udcac 14d. Mensagem confirma\u00e7\u00e3o",
"type": "n8n-nodes-base.code",
"typeVersion": 1,
"position": [
3750,
1600
]
},
{
"parameters": {
"jsCode": "const sessionData = $('\ud83d\udd0e 2. Buscar sess\u00e3o ativa').first().json;\nconst session = Array.isArray(sessionData) && sessionData.length > 0 ? sessionData[0] : null;\n\nif (!session) {\n return { message: 'N\u00e3o entendi \ud83d\ude05 Digite o n\u00famero da op\u00e7\u00e3o ou 1 para o card\u00e1pio.' };\n}\n\nreturn { message: 'Op\u00e7\u00e3o inv\u00e1lida! Digite o n\u00famero da op\u00e7\u00e3o \ud83d\ude0a' };"
},
"name": "\ud83d\udcac Op\u00e7\u00e3o inv\u00e1lida (default)",
"type": "n8n-nodes-base.code",
"typeVersion": 1,
"position": [
2000,
600
]
},
{
"parameters": {
"jsCode": "// Cancelar fluxo - resetar sess\u00e3o\nreturn {\n message: '\u274c Pedido cancelado. Digite 1 para voltar ao card\u00e1pio! \ud83d\ude0a'\n};"
},
"name": "\ud83d\udcac Cancelar fluxo",
"type": "n8n-nodes-base.code",
"typeVersion": 1,
"position": [
2000,
800
]
},
{
"parameters": {
"jsCode": "// Handoff manual para atendente\nreturn {\n to: $json.telefone,\n message: '\ud83d\udd01 Transferindo para um atendente...\\n\\nEm breve algu\u00e9m vai te atender! \ud83d\ude0a'\n};"
},
"name": "\ud83d\udcac Handoff atendente",
"type": "n8n-nodes-base.code",
"typeVersion": 1,
"position": [
2750,
100
]
},
{
"parameters": {
"jsCode": "// Z-API send text\nconst config = $('\ud83d\udce9 Webhook Trigger (WhatsApp)').first().json;\nconst body = $input.first().json;\n\nreturn {\n url: 'https://api.z-api.io/instances/{{INSTANCE_ID}}/token/{{TOKEN}}/send-text',\n body: {\n phone: body.to || body.telefone,\n message: body.message\n }\n};"
},
"name": "\ud83d\udce4 Enviar WhatsApp (Z-API)",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 1,
"position": [
4000,
100
]
}
],
"connections": {
"\ud83d\udce9 Webhook Trigger (WhatsApp)": {
"main": [
[
{
"node": "\ud83d\udd27 1. Normalizar entrada",
"type": "main",
"index": 0
}
]
]
},
"\ud83d\udd27 1. Normalizar entrada": {
"main": [
[
{
"node": "\ud83d\udd0e 2. Buscar sess\u00e3o ativa",
"type": "main",
"index": 0
}
]
]
},
"\ud83d\udd0e 2. Buscar sess\u00e3o ativa": {
"main": [
[
{
"node": "\ud83d\udd27 2b. Verificar se sess\u00e3o existe",
"type": "main",
"index": 0
}
]
]
},
"\ud83d\udd27 2b. Verificar se sess\u00e3o existe": {
"main": [
[
{
"node": "\u2753 Sess\u00e3o existe?",
"type": "main",
"index": 0
}
],
[
{
"node": "\ud83c\udfea 3. Buscar restaurante",
"type": "main",
"index": 1
}
]
]
},
"\u2753 Sess\u00e3o existe?": {
"main": [
[
{
"node": "\ud83d\udd00 4. Roteador principal",
"type": "main",
"index": 0
}
],
[
{
"node": "\ud83c\udd95 2c. Criar nova sess\u00e3o",
"type": "main",
"index": 1
}
]
]
},
"\ud83c\udd95 2c. Criar nova sess\u00e3o": {
"main": [
[
{
"node": "\ud83c\udfea 3. Buscar restaurante",
"type": "main",
"index": 0
}
]
]
},
"\ud83c\udfea 3. Buscar restaurante": {
"main": [
[
{
"node": "\ud83d\udd27 3b. Validar hor\u00e1rio",
"type": "main",
"index": 0
}
]
]
},
"\ud83d\udd27 3b. Validar hor\u00e1rio": {
"main": [
[
{
"node": "\u2753 Est\u00e1 aberto?",
"type": "main",
"index": 0
}
]
]
},
"\u2753 Est\u00e1 aberto?": {
"main": [
[
{
"node": "\ud83d\udd00 4. Roteador principal",
"type": "main",
"index": 0
}
],
[
{
"node": "\ud83d\udeab Enviar fora do hor\u00e1rio",
"type": "main",
"index": 1
}
]
]
},
"\ud83d\udeab Enviar fora do hor\u00e1rio": {
"main": [
[
{
"node": "\ud83d\udce4 Enviar WhatsApp (Z-API)",
"type": "main",
"index": 0
}
]
]
},
"\ud83d\udd00 4. Roteador principal": {
"main": [
[
{
"node": "\u2753 Rota: Boas-vindas?",
"type": "main",
"index": 0
}
]
]
},
"\u2753 Rota: Boas-vindas?": {
"main": [
[
{
"node": "\ud83d\udc64 5. Buscar/cliente",
"type": "main",
"index": 0
}
],
[
{
"node": "\ud83d\udccb 6. Card\u00e1pio din\u00e2mico",
"type": "main",
"index": 1
}
]
]
},
"\ud83d\udc64 5. Buscar/cliente": {
"main": [
[
{
"node": "\ud83d\udcac 5b. Montar boas-vindas",
"type": "main",
"index": 0
}
]
]
},
"\ud83d\udcac 5b. Montar boas-vindas": {
"main": [
[
{
"node": "\ud83d\udce4 Enviar WhatsApp (Z-API)",
"type": "main",
"index": 0
}
]
]
},
"\ud83d\udccb 6. Card\u00e1pio din\u00e2mico": {
"main": [
[
{
"node": "\ud83d\udcac 6b. Montar lista categorias",
"type": "main",
"index": 0
}
]
]
},
"\ud83d\udcac 6b. Montar lista categorias": {
"main": [
[
{
"node": "\ud83c\udf54 7. Buscar itens do card\u00e1pio",
"type": "main",
"index": 0
}
]
]
},
"\ud83c\udf54 7. Buscar itens do card\u00e1pio": {
"main": [
[
{
"node": "\ud83d\udcac 7b. Montar lista itens",
"type": "main",
"index": 0
}
]
]
},
"\ud83d\udcac 7b. Montar lista itens": {
"main": [
[
{
"node": "\u2795 7c. Adicionar item ao carrinho",
"type": "main",
"index": 0
}
]
]
},
"\u2795 7c. Adicionar item ao carrinho": {
"main": [
[
{
"node": "\ud83d\udd0d Buscar bump sugerido",
"type": "main",
"index": 0
}
],
[
{
"node": "\ud83d\udcb8 9. Verificar upsell",
"type": "main",
"index": 1
}
]
]
},
"\ud83d\udd0d Buscar bump sugerido": {
"main": [
[
{
"node": "\ud83d\udcac 8a. Montar oferta bump",
"type": "main",
"index": 0
}
]
]
},
"\ud83d\udcac 8a. Montar oferta bump": {
"main": [
[
{
"node": "\ud83d\udd27 8b. Processar resposta bump",
"type": "main",
"index": 0
}
]
]
},
"\ud83d\udd27 8b. Processar resposta bump": {
"main": [
[
{
"node": "\ud83d\udcac 7b. Montar lista itens",
"type": "main",
"index": 0
}
]
]
},
"\ud83d\udcb8 9. Verificar upsell": {
"main": [
[
{
"node": "\ud83d\udd0d Buscar item upsell",
"type": "main",
"index": 0
}
],
[
{
"node": "\ud83d\udcac 11. Perguntar localiza\u00e7\u00e3o",
"type": "main",
"index": 1
}
]
]
},
"\ud83d\udd0d Buscar item upsell": {
"main": [
[
{
"node": "\ud83d\udcac 9b. Montar oferta upsell",
"type": "main",
"index": 0
}
]
]
},
"\ud83d\udcac 9b. Montar oferta upsell": {
"main": [
[
{
"node": "\ud83d\udd27 9c. Processar resposta upsell",
"type": "main",
"index": 0
}
]
]
},
"\ud83d\udd27 9c. Processar resposta upsell": {
"main": [
[
{
"node": "\ud83d\udcac 11. Perguntar localiza\u00e7\u00e3o",
"type": "main",
"index": 0
}
],
[
{
"node": "\ud83d\udcb8 10. Verificar downsell",
"type": "main",
"index": 1
}
]
]
},
"\ud83d\udcb8 10. Verificar downsell": {
"main": [
[
{
"node": "\ud83d\udd0d Buscar item downsell",
"type": "main",
"index": 0
}
],
[
{
"node": "\ud83d\udcac 11. Perguntar localiza\u00e7\u00e3o",
"type": "main",
"index": 1
}
]
]
},
"\ud83d\udd0d Buscar item downsell": {
"main": [
[
{
"node": "\ud83d\udcac 10b. Montar oferta downsell",
"type": "main",
"index": 0
}
]
]
},
"\ud83d\udcac 10b. Montar oferta downsell": {
"main": [
[
{
"node": "\ud83d\udd27 10c. Processar resposta downsell",
"type": "main",
"index": 0
}
]
]
},
"\ud83d\udd27 10c. Processar resposta downsell": {
"main": [
[
{
"node": "\ud83d\udcac 11. Perguntar localiza\u00e7\u00e3o",
"type": "main",
"index": 0
}
]
]
},
"\ud83d\udcac 11. Perguntar localiza\u00e7\u00e3o": {
"main": [
[
{
"node": "\ud83d\udd27 11b. Processar tipo entrega",
"type": "main",
"index": 0
}
]
]
},
"\ud83d\udd27 11b. Processar tipo entrega": {
"main": [
[
{
"node": "\ud83d\udcb3 12. Buscar formas pagamento",
"type": "main",
"index": 0
}
]
]
},
"\ud83d\udcb3 12. Buscar formas pagamento": {
"main": [
[
{
"node": "\ud83d\udcac 12b. Montar menu pagamento",
"type": "main",
"index": 0
}
]
]
},
"\ud83d\udcac 12b. Montar menu pagamento": {
"main": [
[
{
"node": "\ud83d\udd27 12c. Processar pagamento",
"type": "main",
"index": 0
}
]
]
},
"\ud83d\udd27 12c. Processar pagamento": {
"main": [
[
{
"node": "\ud83d\udccb 13. Montar resumo + confirma\u00e7\u00e3o",
"type": "main",
"index": 0
}
]
]
},
"\ud83d\udccb 13. Montar resumo + confirma\u00e7\u00e3o": {
"main": [
[
{
"node": "\ud83d\udce6 14. Montar payload pedido",
"type": "main",
"index": 0
}
]
]
},
"\ud83d\udce6 14. Montar payload pedido": {
"main": [
[
{
"node": "\ud83d\udcbe 14b. Salvar pedido no Supabase",
"type": "main",
"index": 0
}
]
]
},
"\ud83d\udcbe 14b. Salvar pedido no Supabase": {
"main": [
[
{
"node": "\ud83d\udd04 14c. Atualizar sess\u00e3o",
"type": "main",
"index": 0
}
]
]
},
"\ud83d\udd04 14c. Atualizar sess\u00e3o": {
"main": [
[
{
"node": "\ud83d\udcac 14d. Mensagem confirma\u00e7\u00e3o",
"type": "main",
"index": 0
}
]
]
},
"\ud83d\udcac 14d. Mensagem confirma\u00e7\u00e3o": {
"main": [
[
{
"node": "\ud83d\udce4 Enviar WhatsApp (Z-API)",
"type": "main",
"index": 0
}
]
]
}
},
"settings": {
"timezone": "America/Sao_Paulo",
"saveDataErrorExecution": "all",
"saveDataSuccessExecution": "all",
"executionOrder": "v1"
},
"tags": [
"peddi-order",
"fluxo-principal",
"delivery"
]
}
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
๐ค Fluxo Principal โ Peddi Order. Uses httpRequest. Webhook trigger; 44 nodes.
Source: https://github.com/Yuriwzzkk/peddi-order-flow/blob/cc29256d71ab236933109e1ff4d785240710cce2/public/n8n-workflows/fluxo-principal.json โ original creator credit. Request a take-down โ
More Web Scraping workflows โ ยท Browse all categories โ
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
This n8n template provides enterprise-level version control for your workflows using GitHub integration. Stop losing hours to broken workflows and manual exports โ get proper commit history, visual di
This flow creates dummy files for every item added in your *Arrs (Radarr/Sonarr) with the tag .
eek-Go v2 (Batch-Then-Review). Uses httpRequest. Webhook trigger; 75 nodes.
This workflow receives webhook requests from a content calendar and uses the X API v2 to publish text posts, threads, image/video posts, and polls, as well as delete existing posts and run a credentia
This workflow acts as a central API gateway for all technical indicator agents in the Binance Spot Market Quant AI system. It listens for incoming webhook requests and dynamically routes them to the c