{
  "nodes": [
    {
      "parameters": {
        "httpMethod": "POST",
        "path": "/webhook/7ab5d664-349d-4ad2-84f1-23da3b2df1a7/webhook",
        "authentication": "headerAuth",
        "responseMode": "lastNode",
        "options": {}
      },
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 2.1,
      "position": [
        9856,
        784
      ],
      "id": "4dd03e91-9894-41f4-b0f4-c4dae191e31b",
      "name": "Webhook",
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "descriptionType": "manual",
        "toolDescription": "Nessa ferramenta temos os Procedimento e \u00c1reas de Aplica\u00e7\u00e3o com seus Valores e Valores de Oferta em R$ (Real)",
        "documentId": {
          "__rl": true,
          "value": {},
          "mode": "id"
        },
        "sheetName": {
          "__rl": true,
          "value": 1667361004,
          "mode": "list",
          "cachedResultName": "Pre\u00e7os Gerais",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1lZrtlFpEcbzVT5UfNXcs9wpP-v1YwNE5JnaLfvxA-VA/edit#gid=1667361004"
        },
        "options": {}
      },
      "type": "n8n-nodes-base.googleSheetsTool",
      "typeVersion": 4.7,
      "position": [
        12432,
        976
      ],
      "id": "9d0d20be-d7ec-4a59-a8ac-3230da4acd01",
      "name": "Tabela de Pre\u00e7os"
    },
    {
      "parameters": {
        "operation": "upsert",
        "dataTableId": {
          "__rl": true,
          "value": "PAIZPk6Yh1l2zQON",
          "mode": "list",
          "cachedResultName": "Atendimento Nova Forge",
          "cachedResultUrl": "/projects/GvKfk2Y7L7rLi2zA/datatables/PAIZPk6Yh1l2zQON"
        },
        "filters": {
          "conditions": [
            {
              "keyName": "sessionId",
              "keyValue": "={{ $json.session_id }}"
            }
          ]
        },
        "columns": {
          "mappingMode": "defineBelow",
          "value": {
            "sessionId": "={{ $json.session_id }}",
            "ultima_pergunta_contato": "={{ $json.input }}"
          },
          "matchingColumns": [
            "sessionId"
          ],
          "schema": [
            {
              "id": "sessionId",
              "displayName": "sessionId",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "readOnly": false,
              "removed": false
            },
            {
              "id": "nome_completo",
              "displayName": "nome_completo",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "readOnly": false,
              "removed": true
            },
            {
              "id": "interesse",
              "displayName": "interesse",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "readOnly": false,
              "removed": true
            },
            {
              "id": "historico_tratamento",
              "displayName": "historico_tratamento",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "readOnly": false,
              "removed": true
            },
            {
              "id": "data_agendamento",
              "displayName": "data_agendamento",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "readOnly": false,
              "removed": true
            },
            {
              "id": "agendamento_id",
              "displayName": "agendamento_id",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "readOnly": false,
              "removed": true
            },
            {
              "id": "ultima_pergunta_contato",
              "displayName": "ultima_pergunta_contato",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "readOnly": false,
              "removed": false
            },
            {
              "id": "ultima_resposta_ia",
              "displayName": "ultima_resposta_ia",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "readOnly": false,
              "removed": true
            }
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {}
      },
      "type": "n8n-nodes-base.dataTable",
      "typeVersion": 1,
      "position": [
        10256,
        784
      ],
      "id": "7f4890a2-f961-491b-8888-a463f9a265a9",
      "name": "Criar/atualizar sessionId"
    },
    {
      "parameters": {
        "operation": "get",
        "dataTableId": {
          "__rl": true,
          "value": "PAIZPk6Yh1l2zQON",
          "mode": "list",
          "cachedResultName": "Atendimento Nova Forge",
          "cachedResultUrl": "/projects/GvKfk2Y7L7rLi2zA/datatables/PAIZPk6Yh1l2zQON"
        },
        "filters": {
          "conditions": [
            {
              "keyName": "sessionId",
              "keyValue": "={{ $('Define:Mensagem e Session_id').first().json.session_id }}"
            }
          ]
        },
        "limit": 1
      },
      "type": "n8n-nodes-base.dataTable",
      "typeVersion": 1,
      "position": [
        10432,
        784
      ],
      "id": "a12877e0-6f94-4d0f-b1cf-eae93136ec11",
      "name": "Get row(s)",
      "alwaysOutputData": true
    },
    {
      "parameters": {
        "operation": "upsert",
        "dataTableId": {
          "__rl": true,
          "value": "PAIZPk6Yh1l2zQON",
          "mode": "list",
          "cachedResultName": "Atendimento Nova Forge",
          "cachedResultUrl": "/projects/GvKfk2Y7L7rLi2zA/datatables/PAIZPk6Yh1l2zQON"
        },
        "filters": {
          "conditions": [
            {
              "keyName": "sessionId",
              "keyValue": "={{ $('Define:Mensagem e Session_id').first().json.session_id }}"
            }
          ]
        },
        "columns": {
          "mappingMode": "defineBelow",
          "value": {
            "nome_completo": "={{ ($('Information Extractor').first().json.output.nome_completo || $('Get row(s)').first().json.nome_completo || '') }}",
            "interesse": "={{ ($('Information Extractor').first().json.output.interesse || $('Get row(s)').first().json.interesse || '') }}",
            "historico_tratamento": "={{ ($('Information Extractor').first().json.output.historico_tratamento || $('Get row(s)').first().json.historico_tratamento || '') }}",
            "data_agendamento": "={{ $('Information Extractor').first().json.output.data_agendamento || $('Get row(s)').first().json.data_agendamento || null }}"
          },
          "matchingColumns": [],
          "schema": [
            {
              "id": "sessionId",
              "displayName": "sessionId",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "readOnly": false,
              "removed": true
            },
            {
              "id": "nome_completo",
              "displayName": "nome_completo",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "readOnly": false,
              "removed": false
            },
            {
              "id": "interesse",
              "displayName": "interesse",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "readOnly": false,
              "removed": false
            },
            {
              "id": "historico_tratamento",
              "displayName": "historico_tratamento",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "readOnly": false,
              "removed": false
            },
            {
              "id": "data_agendamento",
              "displayName": "data_agendamento",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "readOnly": false,
              "removed": false
            },
            {
              "id": "agendamento_id",
              "displayName": "agendamento_id",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "readOnly": false,
              "removed": true
            },
            {
              "id": "ultima_pergunta_contato",
              "displayName": "ultima_pergunta_contato",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "readOnly": false,
              "removed": true
            },
            {
              "id": "ultima_resposta_ia",
              "displayName": "ultima_resposta_ia",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "readOnly": false,
              "removed": true
            }
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {}
      },
      "type": "n8n-nodes-base.dataTable",
      "typeVersion": 1,
      "position": [
        11520,
        784
      ],
      "id": "8d4e600e-99dd-40ec-8a79-f486e053c0d9",
      "name": "AtualizaVariaveisExtrator"
    },
    {
      "parameters": {
        "operation": "upsert",
        "dataTableId": {
          "__rl": true,
          "value": "PAIZPk6Yh1l2zQON",
          "mode": "list",
          "cachedResultName": "Atendimento Nova Forge",
          "cachedResultUrl": "/projects/GvKfk2Y7L7rLi2zA/datatables/PAIZPk6Yh1l2zQON"
        },
        "filters": {
          "conditions": [
            {
              "keyName": "sessionId",
              "keyValue": "={{ $('Define:Mensagem e Session_id').first().json.session_id }}"
            }
          ]
        },
        "columns": {
          "mappingMode": "defineBelow",
          "value": {
            "ultima_resposta_ia": "={{ $('AI Agent - Respostas').first().json.output }}",
            "ultima_pergunta_contato": "={{ $('Define:Mensagem e Session_id').first().json.input }}"
          },
          "matchingColumns": [],
          "schema": [
            {
              "id": "sessionId",
              "displayName": "sessionId",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "readOnly": false,
              "removed": true
            },
            {
              "id": "nome_completo",
              "displayName": "nome_completo",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "readOnly": false,
              "removed": true
            },
            {
              "id": "interesse",
              "displayName": "interesse",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "readOnly": false,
              "removed": true
            },
            {
              "id": "historico_tratamento",
              "displayName": "historico_tratamento",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "readOnly": false,
              "removed": true
            },
            {
              "id": "data_agendamento",
              "displayName": "data_agendamento",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "readOnly": false,
              "removed": true
            },
            {
              "id": "agendamento_id",
              "displayName": "agendamento_id",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "readOnly": false,
              "removed": true
            },
            {
              "id": "ultima_pergunta_contato",
              "displayName": "ultima_pergunta_contato",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "readOnly": false,
              "removed": false
            },
            {
              "id": "ultima_resposta_ia",
              "displayName": "ultima_resposta_ia",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "readOnly": false,
              "removed": false
            }
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {}
      },
      "type": "n8n-nodes-base.dataTable",
      "typeVersion": 1,
      "position": [
        12208,
        784
      ],
      "id": "4264ed73-2f85-41a3-9f5f-c3531039104c",
      "name": "AtualizaPerguntaResposta"
    },
    {
      "parameters": {
        "operation": "update",
        "dataTableId": {
          "__rl": true,
          "value": "PAIZPk6Yh1l2zQON",
          "mode": "list",
          "cachedResultName": "Atendimento Nova Forge",
          "cachedResultUrl": "/projects/GvKfk2Y7L7rLi2zA/datatables/PAIZPk6Yh1l2zQON"
        },
        "filters": {
          "conditions": [
            {
              "keyName": "sessionId",
              "keyValue": "={{ $('Define:Mensagem e Session_id').first().json.session_id }}"
            }
          ]
        },
        "columns": {
          "mappingMode": "defineBelow",
          "value": {
            "agendamento_id": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('agendamento_id', `Atualiza o campo \"agendamento_id\" com o ID obtido da cria\u00e7\u00e3o do evento. Este ID vem do resultado da ferramenta \"Cria Evento\" no campo \"id\" ou \"data.id\" ou na resposta JSON. Use este ID para referenciar o evento criado.`, 'string') }}",
            "data_agendamento": "={{ $fromAI('data_agendamento', `Atualiza o campo \"data_agendamento\" com a data de in\u00edcio do evento criado. Use o campo \"start_at\" do resultado da ferramenta \"Cria Evento\" (pode estar em \"data.start_at\" ou diretamente em \"start_at\") no formato ISO 8601 (ex: 2026-01-15T10:00:00Z). Esta \u00e9 a data de in\u00edcio do evento que foi criado com sucesso.`, 'string') }}"
          },
          "matchingColumns": [],
          "schema": [
            {
              "id": "sessionId",
              "displayName": "sessionId",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "readOnly": false,
              "removed": true
            },
            {
              "id": "nome_completo",
              "displayName": "nome_completo",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "readOnly": false,
              "removed": true
            },
            {
              "id": "interesse",
              "displayName": "interesse",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "readOnly": false,
              "removed": true
            },
            {
              "id": "historico_tratamento",
              "displayName": "historico_tratamento",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "readOnly": false,
              "removed": true
            },
            {
              "id": "data_agendamento",
              "displayName": "data_agendamento",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "readOnly": false,
              "removed": false
            },
            {
              "id": "agendamento_id",
              "displayName": "agendamento_id",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "readOnly": false,
              "removed": false
            },
            {
              "id": "ultima_pergunta_contato",
              "displayName": "ultima_pergunta_contato",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "readOnly": false,
              "removed": true
            },
            {
              "id": "ultima_resposta_ia",
              "displayName": "ultima_resposta_ia",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "readOnly": false,
              "removed": true
            }
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {}
      },
      "type": "n8n-nodes-base.dataTableTool",
      "typeVersion": 1,
      "position": [
        11856,
        992
      ],
      "id": "50a547ed-45d5-489b-8a91-a096352274b5",
      "name": "Data table Update",
      "notesInFlow": false,
      "notes": "ESSENCIAL: Use esta ferramenta IMEDIATAMENTE ap\u00f3s usar 'Cria Evento' para salvar o ID do agendamento. Sem isso, o sistema perder\u00e1 o agendamento. Par\u00e2metros: agendamento_id (o ID retornado pela cria\u00e7\u00e3o) e data_agendamento."
    },
    {
      "parameters": {
        "operation": "get",
        "dataTableId": {
          "__rl": true,
          "value": "PAIZPk6Yh1l2zQON",
          "mode": "list",
          "cachedResultName": "Atendimento Nova Forge",
          "cachedResultUrl": "/projects/GvKfk2Y7L7rLi2zA/datatables/PAIZPk6Yh1l2zQON"
        },
        "filters": {
          "conditions": [
            {
              "keyName": "sessionId",
              "keyValue": "={{ $('Define:Mensagem e Session_id').first().json.session_id }}"
            }
          ]
        },
        "limit": 1
      },
      "type": "n8n-nodes-base.dataTable",
      "typeVersion": 1,
      "position": [
        12032,
        784
      ],
      "id": "2575e12d-f8f0-47f2-825f-8130275435fa",
      "name": "Get row(s)1",
      "alwaysOutputData": true
    },
    {
      "parameters": {
        "jsCode": "// Obter o prompt_text do n\u00f3 '#Prompt Extra\u00e7\u00e3o de Dados'\nconst promptText = $json.prompt_text || '';\n\n// Fun\u00e7\u00e3o para escapar chaves simples, mas preservar chaves duplas (n8n expressions)\nfunction escapeCurlyBraces(text) {\n  if (!text) return '';\n  // Substitui { por [ e } por ] para evitar conflito com f-strings do LangChain\n  // Mas n\u00e3o afeta {{...}} que s\u00e3o express\u00f5es do n8n\n  return text.replace(/\\{\\{/g, 'TEMP_DOUBLE_OPEN').replace(/\\}\\}/g, 'TEMP_DOUBLE_CLOSE').replace(/\\{/g, '[').replace(/\\}/g, ']').replace(/TEMP_DOUBLE_OPEN/g, '{{').replace(/TEMP_DOUBLE_CLOSE/g, '}}');\n}\n\nconst escapedPromptText = escapeCurlyBraces(promptText);\n\nreturn [\n  {\n    json: {\n      prompt_text_escaped: escapedPromptText,\n      prompt_text: promptText\n    }\n  }\n];"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        11200,
        784
      ],
      "id": "1b081780-dadc-4831-be42-26d68e42b1f2",
      "name": "Processar Prompt Extractor"
    },
    {
      "parameters": {
        "text": "=Mensagem atual do usu\u00e1rio: {{ $('Define:Mensagem e Session_id').first().json.input }}",
        "attributes": {
          "attributes": [
            {
              "name": "nome_completo",
              "description": "Nome completo do paciente com 2 ou mais palavras."
            },
            {
              "name": "historico_tratamento",
              "description": "Situa\u00e7\u00e3o atual do projeto: \"Ideia do zero\", \"Sistema legado\", \"Refatora\u00e7\u00e3o\", \"Primeira vez contratando\"..."
            },
            {
              "name": "interesse",
              "description": "O tipo de solu\u00e7\u00e3o tecnol\u00f3gica buscada (ex: App, Sistema Web, Automa\u00e7\u00e3o, IA, Chatbot)."
            },
            {
              "name": "data_agendamento",
              "description": "Extraia datas futuras mencionadas para reuni\u00e3o."
            }
          ]
        },
        "options": {
          "systemPromptTemplate": "={{ $('Processar Prompt Extractor').first().json.prompt_text_escaped || $('Concatenador #IA de Atendimento e Triagem').first().json.prompt_text_escaped || '' }}\n\n## Dados Atuais do Contato\n\nNome do contato: {{ $('Webhook').first().json.body.message.from.first_name || 'N\u00e3o informado' }}\n\n### Status atual de cada informa\u00e7\u00e3o:\n\n- Nome Completo: {{ $('Get row(s)').first().json.nome_completo || 'N\u00e3o informado' }}\n- Hist\u00f3rico de Tratamento: {{ $('Get row(s)').first().json.historico_tratamento || 'N\u00e3o informado' }}\n- Interesse: {{ $('Get row(s)').first().json.interesse || 'N\u00e3o informado' }}\n- Data de Agendamento: {{ $('Get row(s)').first().json.data_agendamento || 'N\u00e3o agendado' }}\n\n## Contexto da Conversa:\n\n### REFER\u00caNCIA TEMPORAL (IMPORTANTE):\nHoje \u00e9: {{ $now.setZone('America/Sao_Paulo').setLocale('pt-BR').toFormat(\"cccc, dd 'de' MMMM 'de' yyyy\") }}\nUse esta data como base para calcular qualquer termo relativo (ex: \"amanh\u00e3\", \"segunda-feira\").\n\n- \u00daltima pergunta feita: {{ $('Get row(s)').first().json.ultima_pergunta_contato || 'Nenhuma' }}\n- \u00daltima resposta dada ao paciente: {{ $('Get row(s)').first().json.ultima_resposta_ia || 'Nenhuma' }}\n\n- Data/Hora Atual da conversa: {{ $now.setLocale('pt-BR').toFormat('cccc') }}, {{ $now.setZone('America/Sao_Paulo').setLocale('pt-BR').toFormat(\"dd 'de' LLLL 'de' yyyy HH:mm'hrs'\") }}\n\n### REGRA ABSOLUTA: N\u00c3O INVENTE VALORES\n\n\u26a0\ufe0f CR\u00cdTICO: Voc\u00ea DEVE retornar APENAS informa\u00e7\u00f5es que foram mencionadas EXPLICITAMENTE na mensagem do usu\u00e1rio ou que podem ser inferidas com 100% de CERTEZA do contexto.\n\n\u274c NUNCA FA\u00c7A:\n- Inventar nome completo se o usu\u00e1rio mencionou apenas primeiro nome (ex: se mencionar \"Jo\u00e3o\", N\u00c3O retorne \"Jo\u00e3o Silva\")\n- Inferir interesse se n\u00e3o foi mencionado diretamente na mensagem\n- Criar data de agendamento se o usu\u00e1rio n\u00e3o mencionou data/hora futura explicitamente\n- Assumir hist\u00f3rico de tratamento sem contexto claro e expl\u00edcito\n- Preencher campos baseado em suposi\u00e7\u00f5es ou infer\u00eancias n\u00e3o garantidas\n\n\u2705 SEMPRE FA\u00c7A:\n- Se a informa\u00e7\u00e3o n\u00e3o foi mencionada, retorne string vazia (\"\") para campos string (nome_completo, historico_tratamento, interesse)\n- Se n\u00e3o houver data mencionada explicitamente, omita o campo data_agendamento ou retorne null\n- Extraia APENAS o que est\u00e1 claramente presente na mensagem atual\n- Se houver d\u00favida se uma informa\u00e7\u00e3o foi mencionada, N\u00c3O extraia - \u00e9 melhor retornar vazio\n\n### INSTRU\u00c7\u00c3O CR\u00cdTICA DE OUTPUT:\nRetorne APENAS o objeto JSON v\u00e1lido, sem markdown, sem code blocks (```), sem explica\u00e7\u00f5es adicionais.\nApenas o objeto JSON puro, diretamente, sem formata\u00e7\u00e3o markdown.\n\n### REGRAS OBRIGAT\u00d3RIAS PARA OS CAMPOS:\n\n1. **nome_completo** (string): \n   - Extraia APENAS se o usu\u00e1rio mencionar nome completo (2+ palavras)\n   - Se mencionar apenas primeiro nome, retorne string vazia \"\" (NUNCA invente sobrenome)\n   - Se n\u00e3o encontrar, retorne string vazia \"\" (NUNCA null)\n\n2. **historico_tratamento** (string): \n   - Extraia APENAS se houver men\u00e7\u00e3o clara \u00e0 situa\u00e7\u00e3o do projeto\n   - Valores v\u00e1lidos: \"Ideia do zero\", \"Sistema legado\", \"Refatora\u00e7\u00e3o\", \"Primeira vez contratando\"\n   - Se n\u00e3o houver contexto suficiente, retorne string vazia \"\" (NUNCA null)\n\n3. **interesse** (string): \n   - Extraia APENAS se o cliente mencionar explicitamente o tipo de solu\u00e7\u00e3o (App, Sistema Web, etc.)\n   - Se n\u00e3o mencionar, retorne string vazia \"\" (NUNCA null)\n\n4. **data_agendamento** (string): \n   - Extraia APENAS se o usu\u00e1rio mencionar EXPLICITAMENTE uma data/hora futura\n   - Se n\u00e3o houver men\u00e7\u00e3o clara a data/hora, omita o campo ou retorne null\n   - Sempre retorne no formato ISO 8601 UTC (ex: 2026-01-15T10:00:00Z)\n   - NUNCA invente datas ou hor\u00e1rios n\u00e3o mencionados\n\nIMPORTANTE: Campos do tipo string (nome_completo, historico_tratamento, interesse) SEMPRE devem ser strings, nunca null. Use \"\" (string vazia) se a informa\u00e7\u00e3o n\u00e3o for encontrada ou n\u00e3o foi mencionada explicitamente.\n\nPara o campo data_agendamento, sempre retorne no formato ISO 8601 (ex: 2026-01-15T10:00:00Z) se houver uma data mencionada explicitamente.\nSe n\u00e3o houver data mencionada, n\u00e3o inclua o campo ou retorne null."
        }
      },
      "type": "@n8n/n8n-nodes-langchain.informationExtractor",
      "typeVersion": 1.2,
      "position": [
        11200,
        784
      ],
      "id": "8f964953-aa8a-4099-8990-d07395cfdbe0",
      "name": "Information Extractor",
      "executeOnce": false,
      "alwaysOutputData": true
    },
    {
      "parameters": {
        "method": "POST",
        "url": "=https://controliaa.vercel.app/api/webhooks/n8n/channel-response",
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={{ $json }}",
        "options": {}
      },
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.3,
      "position": [
        12624,
        784
      ],
      "id": "4b4e7b46-b554-4031-86f4-1ec0f90f9ae7",
      "name": "HTTP Request (Enviar Resposta)"
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "85de3930-14ce-48a5-9e78-b68ac68f9f75",
              "name": "input",
              "value": "={{ $json.body.message.text }}",
              "type": "string"
            },
            {
              "id": "cbb5e494-7253-4f18-967f-0f97ef6d3079",
              "name": "session_id",
              "value": "={{ $json.body.controlia.conversation_id }}",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        10048,
        784
      ],
      "id": "34a9de49-5560-43bf-a59a-dee8c732cff2",
      "name": "Define:Mensagem e Session_id"
    },
    {
      "parameters": {
        "operation": "getAll",
        "tableId": "ai_prompts",
        "filters": {
          "conditions": [
            {
              "keyName": "id",
              "condition": "eq",
              "keyValue": "fe5c1cb7-bc87-4922-9736-8ca6b83ae613"
            }
          ]
        }
      },
      "type": "n8n-nodes-base.supabase",
      "typeVersion": 1,
      "position": [
        10624,
        784
      ],
      "id": "5830efa3-d75a-480b-a6fa-e8d17910444c",
      "name": "#Prompt IA de Atendimento e Triagem",
      "credentials": {
        "supabaseApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "jsCode": "// Defina aqui a ordem desejada dos IDs\nconst ordemDesejada = ['fe5c1cb7-bc87-4922-9736-8ca6b83ae613'];\n\nconst concatenado = ordemDesejada\n  .map(id => {\n    const item = items.find(i => i.json.id === id);\n    // CORRE\u00c7\u00c3O AQUI: Mudamos de .content_prompt para .prompt_text\n    return item ? item.json.prompt_text : null;\n  })\n  .filter(Boolean) // remove nulos\n  .join('\\n');\n\n// Escapar chaves simples do prompt para evitar interpreta\u00e7\u00e3o como vari\u00e1veis de template pelo LangChain\n// Substitui { por [ e } por ] para evitar conflito com templates do n8n ({{ }}) e LangChain\nconst promptEscapado = concatenado\n  .replace(/\\{\\{/g, 'TEMP_DOUBLE_OPEN')  // Salva chaves duplas temporariamente\n  .replace(/\\}\\}/g, 'TEMP_DOUBLE_CLOSE')\n  .replace(/\\{/g, '[')  // Substitui chaves simples por colchetes\n  .replace(/\\}/g, ']')\n  .replace(/TEMP_DOUBLE_OPEN/g, '{{')  // Restaura chaves duplas\n  .replace(/TEMP_DOUBLE_CLOSE/g, '}}');\n\nreturn [\n  {\n    json: {\n      content_prompt_concatenado: concatenado,\n      prompt_text_escaped: promptEscapado\n    }\n  }\n];"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        10816,
        784
      ],
      "id": "1754d437-f448-4c0a-9e41-7b604cde2983",
      "name": "Concatenador #IA de Atendimento e Triagem"
    },
    {
      "parameters": {
        "operation": "getAll",
        "tableId": "ai_prompts",
        "limit": 1,
        "filters": {
          "conditions": [
            {
              "keyName": "id",
              "condition": "eq",
              "keyValue": "c0827f59-1ff5-4de8-924e-4c16504a5d10"
            }
          ]
        }
      },
      "type": "n8n-nodes-base.supabase",
      "typeVersion": 1,
      "position": [
        11008,
        784
      ],
      "id": "70438d01-544a-49ec-ac82-feaaa9473a45",
      "name": "#Prompt Extra\u00e7\u00e3o de Dados",
      "credentials": {
        "supabaseApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "jsCode": "// Obter dados do webhook original\nconst webhookData = $('Webhook').first().json.body || $('Webhook').first().json;\nconst controlia = webhookData.controlia || {};\nconst message = webhookData.message || {};\n\n// Obter resposta da IA\nconst output = $('AI Agent - Respostas').first().json.output;\n\n// Obter dados da linha do DataTable\nconst rowData = $('Get row(s)1').first().json || {};\n\n// Preparar campos customizados para atualizar (s\u00f3 incluir se n\u00e3o forem null/undefined)\nconst customFields = {};\nif (rowData.interesse) customFields.interesse = rowData.interesse;\nif (rowData.historico_tratamento) customFields.historico_tratamento = rowData.historico_tratamento;\nif (rowData.data_agendamento) customFields.data_agendamento = rowData.data_agendamento;\n\n// Retornar payload completo\nreturn {\n  // Resposta da IA que ser\u00e1 enviada ao canal (Telegram, WhatsApp, etc.)\n  output: output,\n  \n  // Dados do Controlia (obrigat\u00f3rios - j\u00e1 v\u00eam do webhook original)\n  controlia: {\n    company_id: controlia.company_id,\n    contact_id: controlia.contact_id,\n    conversation_id: controlia.conversation_id,\n    message_id: controlia.message_id,\n    channel: controlia.channel || 'telegram',\n    channel_id: controlia.channel_id || message.chat?.id?.toString()\n  },\n  \n  // Dados da mensagem original (opcional, mas recomendado)\n  message: {\n    from: message.from || controlia.message?.from,\n    chat: message.chat || controlia.message?.chat\n  },\n  \n  // \u2705 Campos customizados para atualizar no contato (s\u00f3 se houver valores)\n  ...(Object.keys(customFields).length > 0 ? { custom_fields: customFields } : {})\n};"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        12416,
        784
      ],
      "id": "21661a51-b0a4-45d6-85e2-63fd4fc1bcc9",
      "name": "Prepare Response Data"
    },
    {
      "parameters": {
        "toolDescription": "\ud83d\udd0d VERIFICA HOR\u00c1RIOS DISPON\u00cdVEIS na agenda da empresa no Controlia.\n\n\u26a0\ufe0f USE ESTA FERRAMENTA SEMPRE (OBRIGAT\u00d3RIO):\n- Quando o cliente perguntar sobre hor\u00e1rios dispon\u00edveis (OBRIGAT\u00d3RIO)\n- ANTES de criar qualquer evento (OBRIGAT\u00d3RIO)\n- ANTES de atualizar qualquer evento (OBRIGAT\u00d3RIO)\n- Quando o cliente mencionar interesse em agendar (OBRIGAT\u00d3RIO)\n\n\ud83d\udcca COMO INTERPRETAR OS RESULTADOS:\n- Se retornar array vazio []: N\u00e3o h\u00e1 eventos agendados nos pr\u00f3ximos 15 dias = AMPLA DISPONIBILIDADE\n- Se retornar eventos: Analise os hor\u00e1rios (start_at e end_at) para identificar:\n  * Hor\u00e1rios ocupados (evitar sugerir)\n  * Janelas de tempo livres (pode sugerir)\n\n\ud83c\udfaf O QUE FAZER COM OS RESULTADOS:\n1. Se vazio: Informe ao cliente que h\u00e1 ampla disponibilidade e sugira hor\u00e1rios padr\u00e3o (9h, 10h, 14h, 15h, 16h)\n2. Se houver eventos: Liste os hor\u00e1rios ocupados e sugira alternativas livres\n3. NUNCA invente hor\u00e1rios - use apenas os dados retornados pela ferramenta\n\nA ferramenta busca automaticamente os pr\u00f3ximos 15 dias a partir de agora.\n\n\u26a0\ufe0f REGRA ABSOLUTA: NUNCA responda sobre disponibilidade SEM usar esta ferramenta primeiro.",
        "url": "https://controliaa.vercel.app/api/calendar/events",
        "sendQuery": true,
        "queryParameters": {
          "parameters": [
            {
              "name": "start",
              "value": "={{ $now.setZone('America/Sao_Paulo').toUTC().toISO() }}"
            },
            {
              "name": "end",
              "value": "={{ $now.setZone('America/Sao_Paulo').plus({ hours: 360 }).toUTC().toISO() }}"
            },
            {
              "name": "status",
              "value": "scheduled"
            },
            {
              "name": "company_id",
              "value": "={{ $('Webhook').first().json.body.controlia.company_id }}"
            }
          ]
        },
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Content-Type",
              "value": "application/json"
            },
            {
              "name": "Authorization",
              "value": "<redacted-credential>"
            },
            {
              "name": "x-company-id",
              "value": "={{ $('Webhook').first().json.body.controlia.company_id }}"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.httpRequestTool",
      "typeVersion": 4.3,
      "position": [
        11232,
        992
      ],
      "id": "1098e88a-b94f-4c68-b0d8-326ad858997b",
      "name": "Busca Disponibilidades",
      "rewireOutputLogTo": "ai_tool"
    },
    {
      "parameters": {
        "toolDescription": "\ud83d\udd04 ATUALIZA um evento existente no calend\u00e1rio da empresa no Controlia.\n\n\u26a0\ufe0f REGRAS OBRIGAT\u00d3RIAS ANTES DE USAR:\n\n1. **OBRIGAT\u00d3RIO**: Voc\u00ea DEVE ter usado \"Busca Disponibilidades\" ANTES desta ferramenta\n2. **OBRIGAT\u00d3RIO**: Verifique que o novo hor\u00e1rio desejado N\u00c3O est\u00e1 na lista de eventos retornados\n3. **OBRIGAT\u00d3RIO**: Confirme com o cliente a nova data/hora antes de atualizar\n4. **OBRIGAT\u00d3RIO**: Voc\u00ea precisa do ID do evento (agendamento_id) que est\u00e1 armazenado na DataTable\n5. **OBRIGAT\u00d3RIO**: Voc\u00ea precisa ter uma nova data de agendamento (campo data_agendamento da DataTable ou mencionada pelo cliente)\n\n\ud83d\udccb QUANDO USAR:\n- Cliente solicitou altera\u00e7\u00e3o de data/hora de um agendamento existente\n- Novo hor\u00e1rio est\u00e1 livre (confirmado pela \"Busca Disponibilidades\")\n- Cliente confirmou a nova data/hora\n- Voc\u00ea tem o agendamento_id do evento que deseja atualizar\n\n\u274c N\u00c3O USE SE:\n- N\u00e3o verificou disponibilidade do novo hor\u00e1rio primeiro\n- Novo hor\u00e1rio est\u00e1 ocupado\n- N\u00e3o tem agendamento_id (informe ao cliente e ofere\u00e7a criar novo evento)\n- Cliente n\u00e3o confirmou a mudan\u00e7a\n\n\ud83d\udd34 PAR\u00c2METROS:\n- event_id: ID do evento a atualizar (use o agendamento_id da DataTable)\n- start_at: Nova data/hora de in\u00edcio no formato ISO 8601 UTC\n- end_at: Nova data/hora de t\u00e9rmino (1 hora ap\u00f3s start_at) no formato ISO 8601 UTC\n\n\ud83d\udca1 IMPORTANTE:\n- O evento ter\u00e1 dura\u00e7\u00e3o de 1 hora a partir da nova data de in\u00edcio\n- Sempre verifique disponibilidade antes de atualizar\n- Confirme com o cliente antes de fazer qualquer altera\u00e7\u00e3o",
        "method": "PATCH",
        "url": "=https://controliaa.vercel.app/api/calendar/events/{{ /*n8n-auto-generated-fromAI*/ $fromAI('event_id', `ID do evento que deseja atualizar. Obtenha este ID do campo agendamento_id da DataTable ou do resultado anterior de cria\u00e7\u00e3o de evento.`, 'string') }}",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Content-Type",
              "value": "application/json"
            },
            {
              "name": "Authorization",
              "value": "<redacted-credential>"
            },
            {
              "name": "x-company-id",
              "value": "={{ $('Webhook').first().json.body.controlia.company_id }}"
            }
          ]
        },
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={\n  \"company_id\": \"{{ $('Webhook').first().json.body.controlia.company_id }}\",\n  \"title\": \"Consulta com {{ $('Webhook').first().json.body.message.from.first_name || 'Cliente' }}\",\n  \"description\": \"Consulta atualizada via atendimento\",\n  \"start_at\": \"{{ /*n8n-auto-generated-fromAI*/ $fromAI('start_at', `Nova data e hora de in\u00edcio do evento no formato ISO 8601 (ex: 2026-01-15T10:00:00Z). Deve ser uma data futura.`, 'string') }}\",\n  \"end_at\": \"{{ /*n8n-auto-generated-fromAI*/ $fromAI('end_at', `Nova data e hora de t\u00e9rmino do evento no formato ISO 8601 (ex: 2026-01-15T11:00:00Z). Deve ser 1 hora ap\u00f3s o start_at.`, 'string') }}\",\n  \"is_all_day\": false,\n  \"location\": \"Online/Telefone\",\n  \"contact_id\": \"{{ $('Webhook').first().json.body.controlia.contact_id }}\",\n  \"visibility\": \"company\"\n}",
        "options": {}
      },
      "type": "n8n-nodes-base.httpRequestTool",
      "typeVersion": 4.3,
      "position": [
        11552,
        992
      ],
      "id": "e64d00ff-dc11-44a9-bd9e-2ac693a937e1",
      "name": "Atualiza Eventos"
    },
    {
      "parameters": {
        "toolDescription": "\u2705 CRIA UM NOVO AGENDAMENTO no calend\u00e1rio.\n\n\u26a0\ufe0f USE ESTA FERRAMENTA QUANDO:\n- O cliente confirmar uma data/hora para agendamento (ex: \"sim, quero\", \"confirmo\", \"est\u00e1 bom\", \"pode ser\")\n- Ap\u00f3s voc\u00ea verificar disponibilidade e o hor\u00e1rio estiver livre\n- O cliente mencionar diretamente uma data/hora que deseja agendar\n\n\ud83d\udccb FLUXO OBRIGAT\u00d3RIO:\n1. Ap\u00f3s criar o evento com esta ferramenta\n2. Voc\u00ea DEVE usar imediatamente \"Data table Update\" para salvar o ID retornado\n3. Confirme com o cliente a data, hora e dura\u00e7\u00e3o (1 hora)\n\n\ud83d\udd34 PAR\u00c2METROS OBRIGAT\u00d3RIOS (VOC\u00ca DEVE FORNECER):\n- start_at: Data/hora de in\u00edcio no formato ISO 8601 (ex: 2026-01-15T10:00:00Z). Deve ser uma data FUTURA. Use a data mencionada pelo cliente ou da conversa sobre agendamento.\n- end_at: Data/hora de t\u00e9rmino no formato ISO 8601 (ex: 2026-01-15T11:00:00Z). Deve ser exatamente 1 hora ap\u00f3s start_at.\n\n\ud83d\udca1 IMPORTANTE: Se o cliente mencionou uma data espec\u00edfica, use essa data. Se mencionou apenas hor\u00e1rio, use o dia atual ou pr\u00f3ximo dia dispon\u00edvel. Sempre calcule end_at = start_at + 1 hora.",
        "method": "POST",
        "url": "https://controliaa.vercel.app/api/calendar/events",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Content-Type",
              "value": "application/json"
            },
            {
              "name": "Authorization",
              "value": "<redacted-credential>"
            },
            {
              "name": "x-company-id",
              "value": "={{ $('Webhook').first().json.body.controlia.company_id }}"
            }
          ]
        },
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={\n  \"company_id\": \"{{ $('Webhook').first().json.body.controlia.company_id }}\",\n  \"title\": \"Consulta com {{ $('Webhook').first().json.body.message.from.first_name || 'Cliente' }}\",\n  \"description\": \"Consulta agendada via atendimento\",\n  \"start_at\": \"{{ /*n8n-auto-generated-fromAI*/ ($fromAI('start_at', `Data e hora de in\u00edcio do evento no formato ISO 8601 (ex: 2026-01-15T10:00:00Z). Deve ser uma data futura no hor\u00e1rio de S\u00e3o Paulo. Use a data mencionada pelo cliente ou da \u00faltima resposta sobre agendamento.`, 'string') || $now.setZone('America/Sao_Paulo').plus({ hours: 1 }).toUTC().toISO()) }}\",\n  \"end_at\": \"{{ /*n8n-auto-generated-fromAI*/ ($fromAI('end_at', `Data e hora de t\u00e9rmino do evento no formato ISO 8601 (ex: 2026-01-15T11:00:00Z). Deve ser 1 hora ap\u00f3s o start_at. Se start_at for fornecido, calcule end_at = start_at + 1 hora.`, 'string') || $now.setZone('America/Sao_Paulo').plus({ hours: 2 }).toUTC().toISO()) }}\",\n  \"is_all_day\": false,\n  \"location\": \"Online/Telefone\",\n  \"contact_id\": \"{{ $('Webhook').first().json.body.controlia.contact_id }}\",\n  \"visibility\": \"company\"\n}",
        "options": {}
      },
      "type": "n8n-nodes-base.httpRequestTool",
      "typeVersion": 4.3,
      "position": [
        11408,
        992
      ],
      "id": "91130f50-306f-4975-b6a0-6d3ee26665d0",
      "name": "Cria Evento"
    },
    {
      "parameters": {
        "toolDescription": "\ud83d\uddd1\ufe0f EXCLUI um evento do calend\u00e1rio da empresa no Controlia.\n\n\u26a0\ufe0f REGRAS OBRIGAT\u00d3RIAS ANTES DE USAR:\n\n1. **OBRIGAT\u00d3RIO**: SEMPRE confirme com o cliente ANTES de excluir o agendamento\n2. **OBRIGAT\u00d3RIO**: Voc\u00ea precisa do ID do evento (agendamento_id) que est\u00e1 armazenado na DataTable\n3. **OBRIGAT\u00d3RIO**: Garanta que o cliente confirmou explicitamente a exclus\u00e3o\n\n\ud83d\udccb QUANDO USAR:\n- Cliente solicitou cancelamento de um agendamento existente\n- Cliente confirmou explicitamente que deseja excluir (\"sim, cancela\", \"pode cancelar\", \"quero excluir\")\n- Voc\u00ea tem o agendamento_id do evento que deseja excluir\n\n\u274c N\u00c3O USE SE:\n- Cliente n\u00e3o confirmou explicitamente a exclus\u00e3o\n- N\u00e3o tem agendamento_id (informe ao cliente que n\u00e3o h\u00e1 agendamento para excluir)\n- H\u00e1 d\u00favida sobre a inten\u00e7\u00e3o do cliente (sempre confirme primeiro)\n\n\ud83d\udd34 PAR\u00c2METROS:\n- event_id: ID do evento a excluir (use o agendamento_id da DataTable)\n\n\ud83d\udca1 IMPORTANTE:\n- SEMPRE confirme com o cliente antes de excluir\n- Ap\u00f3s excluir, informe ao cliente que o agendamento foi cancelado\n- O agendamento_id ser\u00e1 removido automaticamente ou voc\u00ea pode atualizar a DataTable",
        "method": "DELETE",
        "url": "=https://controliaa.vercel.app/api/calendar/events/{{ /*n8n-auto-generated-fromAI*/ $fromAI('event_id', `ID do evento que deseja atualizar. Obtenha este ID do campo agendamento_id da DataTable ou do resultado anterior de cria\u00e7\u00e3o de evento.`, 'string') }}",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "<redacted-credential>"
            },
            {
              "name": "x-company-id",
              "value": "={{ $('Webhook').first().json.body.controlia.company_id }}"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.httpRequestTool",
      "typeVersion": 4.3,
      "position": [
        11696,
        992
      ],
      "id": "72cfb0a3-6433-4918-8f43-4d697142614a",
      "name": "Exclui Eventos"
    },
    {
      "parameters": {
        "promptType": "define",
        "text": "={{ $('Webhook').first().json.body.message.text }}",
        "options": {
          "systemMessage": "={{ $('Concatenador #IA de Atendimento e Triagem').first().json.content_prompt_concatenado }}\n\n# CONTEXTO ATUAL (REAL-TIME)\n- Data/Hora Agora: {{ $now.setZone('America/Sao_Paulo').setLocale('pt-BR').toFormat(\"cccc, dd 'de' MMMM 'de' yyyy, HH:mm\") }}\n- Fuso Hor\u00e1rio da Empresa: Am\u00e9rica/S\u00e3o Paulo (UTC-3).\n\n# STATUS DA TRIAGEM (MEM\u00d3RIA)\nAnalise o que j\u00e1 sabemos sobre o contato atual:\n- Nome: {{ $('Get row(s)').first().json.nome_completo || \"N\u00e3o informado\" }}\n- Interesse (O que busca): {{ $('Get row(s)').first().json.interesse || \"N\u00e3o informado\" }}\n- Contexto do Projeto (J\u00e1 tem sistema ou \u00e9 novo?): {{ $('Get row(s)').first().json.historico_tratamento || \"N\u00e3o informado\" }}\n- Data da Reuni\u00e3o: {{ $('Get row(s)').first().json.data_agendamento || \"N\u00e3o agendado\" }}\n- ID do Agendamento (Sistema): {{ $('Get row(s)').first().json.agendamento_id || \"null\" }}\n\nContexto da Conversa:\n\nData/Hora Atual da conversa: {{ $now.setZone('America/Sao_Paulo').setLocale('pt-BR').toFormat('cccc') }}, {{ $now.setZone('America/Sao_Paulo').setLocale('pt-BR').toFormat(\"dd 'de' LLLL 'de' yyyy HH:mm'hrs'\") }}\n\nIdentifique o g\u00eanero atrav\u00e9s do nome: {{ $('Webhook').first().json.body.message.from.first_name }}. De acordo com esse nome utilize artigos e pronomes adequados (Ex: \"Seja bem-vindo, Sr.\" ou \"Seja bem-vinda, Sra.\").\n\n\u00daltima intera\u00e7\u00e3o:\n\nA \u00faltima pergunta do usu\u00e1rio foi: {{ $('Get row(s)').first().json.ultima_pergunta_contato || \"Nenhuma\" }}.\nSua \u00faltima resposta foi: {{ $('Get row(s)').first().json.ultima_resposta_ia || \"Nenhuma\" }}.\n\n# \u26a0\ufe0f REGRA ABSOLUTA: SEMPRE CONSULTE A AGENDA \u26a0\ufe0f\n\n## QUANDO USAR \"Busca Disponibilidades\" (OBRIGAT\u00d3RIO):\n\nVoc\u00ea DEVE usar \"Busca Disponibilidades\" SEMPRE que:\n\n1. **Cliente pergunta sobre hor\u00e1rios dispon\u00edveis:**\n   - \"Quais hor\u00e1rios voc\u00ea tem dispon\u00edveis?\"\n   - \"Tem hor\u00e1rio livre?\"\n   - \"Quando voc\u00ea pode me atender?\"\n   - \"Qual sua disponibilidade?\"\n   - \"Quais dias voc\u00ea est\u00e1 livre?\"\n   - Qualquer pergunta similar sobre hor\u00e1rios ou disponibilidade\n   \n2. **Cliente menciona interesse em agendar:**\n   - \"Quero agendar uma reuni\u00e3o\"\n   - \"Posso marcar uma consulta?\"\n   - \"Gostaria de agendar\"\n   - \"Quero marcar um hor\u00e1rio\"\n   \n3. **ANTES de criar QUALQUER evento:**\n   - Mesmo que o cliente j\u00e1 tenha confirmado uma data/hora\n   - Mesmo que voc\u00ea j\u00e1 tenha consultado anteriormente na mesma conversa\n   - Esta \u00e9 uma regra OBRIGAT\u00d3RIA de seguran\u00e7a\n\n4. **ANTES de atualizar um evento existente:**\n   - Verifique se o novo hor\u00e1rio est\u00e1 dispon\u00edvel\n\n**IMPORTANTE**: \n- NUNCA responda sobre disponibilidade de hor\u00e1rios SEM usar \"Busca Disponibilidades\" primeiro\n- NUNCA assuma que um hor\u00e1rio est\u00e1 livre sem consultar\n- NUNCA invente hor\u00e1rios dispon\u00edveis - use APENAS os resultados da ferramenta\n- Se \"Busca Disponibilidades\" retornar vazio (nenhum evento), informe que h\u00e1 disponibilidade ampla\n- Se retornar eventos, informe os hor\u00e1rios ocupados e sugira alternativas livres\n\n# \u26a0\ufe0f REGRAS OBRIGAT\u00d3RIAS PARA FERRAMENTAS DE AGENDAMENTO \u26a0\ufe0f\n\n## REGRA 1: SEMPRE USAR \"Busca Disponibilidades\" QUANDO:\n- O cliente perguntar sobre hor\u00e1rios dispon\u00edveis (OBRIGAT\u00d3RIO)\n- O cliente mencionar interesse em agendar uma data/hora espec\u00edfica (OBRIGAT\u00d3RIO)\n- ANTES de criar QUALQUER evento (OBRIGAT\u00d3RIO)\n- ANTES de atualizar QUALQUER evento (OBRIGAT\u00d3RIO)\n\n**A\u00c7\u00c3O OBRIGAT\u00d3RIA**: Se o cliente pedir hor\u00e1rios dispon\u00edveis ou mencionar interesse em agendar, voc\u00ea DEVE usar \"Busca Disponibilidades\" IMEDIATAMENTE, SEM EXCE\u00c7\u00c3O.\n\n## REGRA 2: SEMPRE USAR \"Cria Evento\" QUANDO:\n- O cliente confirmar uma data/hora para agendamento (ex: \"sim, quero agendar\", \"confirmo\", \"est\u00e1 bom\", \"pode ser nesse hor\u00e1rio\")\n- Ap\u00f3s voc\u00ea ter verificado disponibilidade e o hor\u00e1rio estiver livre (confirmado por \"Busca Disponibilidades\")\n- Cliente deu consentimento expl\u00edcito\n\n**A\u00c7\u00c3O OBRIGAT\u00d3RIA**: Se o cliente confirmar uma data AP\u00d3S voc\u00ea ter verificado disponibilidade, voc\u00ea DEVE usar \"Cria Evento\" para criar o agendamento.\n\n## REGRA 3: FLUXO OBRIGAT\u00d3RIO DE AGENDAMENTO:\n\n1. Cliente menciona interesse em agendar OU pergunta sobre hor\u00e1rios\n   \u2192 **VOC\u00ca DEVE USAR \"Busca Disponibilidades\"** (OBRIGAT\u00d3RIO)\n\n2. Ap\u00f3s verificar disponibilidade:\n   - Se livre (array vazio ou hor\u00e1rio n\u00e3o est\u00e1 na lista): **VOC\u00ca DEVE USAR \"Cria Evento\"** se cliente confirmar\n   - Se ocupado: Informe ao cliente e sugira alternativas livres\n\n3. Ap\u00f3s criar evento com sucesso:\n   \u2192 **VOC\u00ca DEVE USAR \"Data table Update\"** para salvar o ID do agendamento (OBRIGAT\u00d3RIO)\n\n## REGRA 4: INTERPRETA\u00c7\u00c3O DE CONFIRMA\u00c7\u00c3O:\n\nConsidere como CONFIRMA\u00c7\u00c3O de agendamento:\n- \"Sim\", \"Confirmo\", \"Pode ser\", \"Est\u00e1 bom\", \"Perfeito\", \"\u00d3timo\"\n- \"Quero agendar para [data/hora]\"\n- \"Pode ser amanh\u00e3 \u00e0s 10h\"\n- Qualquer resposta positiva ap\u00f3s voc\u00ea sugerir um hor\u00e1rio\n\nQuando houver confirma\u00e7\u00e3o, voc\u00ea DEVE usar \"Cria Evento\" APENAS se j\u00e1 verificou disponibilidade primeiro.\n\n## REGRA 5: N\u00c3O PULE ETAPAS\n\nNUNCA crie um evento sem antes verificar disponibilidade. Esta \u00e9 uma regra ABSOLUTA.\n\n## EXEMPLOS DE USO CORRETO:\n\n**Cen\u00e1rio 1 - Cliente pergunta hor\u00e1rios:**\nCliente: \"quais hor\u00e1rios voc\u00ea tem dispon\u00edveis?\"\n\u2192 Voc\u00ea DEVE usar \"Busca Disponibilidades\" AGORA (OBRIGAT\u00d3RIO)\n\u2192 Analise os resultados\n\u2192 Se vazio: informe ampla disponibilidade e sugira hor\u00e1rios\n\u2192 Se houver eventos: liste ocupados e sugira livres\n\u2192 Se o cliente confirmar, use \"Cria Evento\"\n\n**Cen\u00e1rio 2 - Cliente menciona data espec\u00edfica:**\nCliente: \"quero agendar para amanh\u00e3 \u00e0s 10h\"\n\u2192 Voc\u00ea DEVE usar \"Busca Disponibilidades\" primeiro para verificar (OBRIGAT\u00d3RIO)\n\u2192 Se livre (hor\u00e1rio n\u00e3o est\u00e1 na lista), use \"Cria Evento\" imediatamente\n\u2192 Use \"Data table Update\" para salvar o ID\n\n**Cen\u00e1rio 3 - Cliente confirma ap\u00f3s verifica\u00e7\u00e3o:**\nVoc\u00ea: \"Tenho disponibilidade amanh\u00e3 \u00e0s 10h, 14h ou 16h\" (baseado em \"Busca Disponibilidades\")\nCliente: \"Pode ser \u00e0s 14h\"\n\u2192 Voc\u00ea DEVE usar \"Cria Evento\" AGORA (j\u00e1 verificou disponibilidade anteriormente)\n\u2192 Use \"Data table Update\" para salvar o ID\n\n## LEMBRE-SE:\n- NUNCA responda sobre hor\u00e1rios sem consultar \"Busca Disponibilidades\" primeiro\n- NUNCA invente hor\u00e1rios dispon\u00edveis - use apenas os dados da ferramenta\n- Sempre verifique disponibilidade antes de criar qualquer evento\n- Se o cliente confirmar, crie o evento imediatamente (ap\u00f3s verifica\u00e7\u00e3o)\n- Sempre salve o ID do agendamento ap\u00f3s criar"
        }
      },
      "type": "@n8n/n8n-nodes-langchain.agent",
      "typeVersion": 3.1,
      "position": [
        11712,
        784
      ],
      "id": "618b7f3c-6dee-4953-8574-55e2e61bdac8",
      "name": "AI Agent - Respostas"
    },
    {
      "parameters": {
        "model": "mistralai/mistral-7b-instruct:free",
        "options": {}
      },
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenRouter",
      "typeVersion": 1,
      "position": [
        10608,
        992
      ],
      "id": "2f561187-e5ec-407e-85ac-06c234f1429f",
      "name": "OpenRouter Chat Model",
      "executeOnce": true,
      "credentials": {
        "openRouterApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "model": "mistralai/mistral-7b-instruct",
        "options": {}
      },
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenRouter",
      "typeVersion": 1,
      "position": [
        10928,
        992
      ],
      "id": "07cb6d03-79b9-4941-9297-a1baf69cfc44",
      "name": "OpenRouter Chat Model1",
      "credentials": {
        "openRouterApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "model": {
          "__rl": true,
          "value": "gpt-4o-mini",
          "mode": "list",
          "cachedResultName": "gpt-4o-mini"
        },
        "builtInTools": {},
        "options": {}
      },
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "typeVersion": 1.3,
      "position": [
        10448,
        992
      ],
      "id": "29e15938-bca7-4a4c-a53d-24fc0a60d1b4",
      "name": "OpenAI Chat Model",
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "model": {
          "__rl": true,
          "value": "gpt-4o-mini",
          "mode": "list",
          "cachedResultName": "gpt-4o-mini"
        },
        "builtInTools": {},
        "options": {}
      },
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "typeVersion": 1.3,
      "position": [
        10768,
        992
      ],
      "id": "5bf372e9-9793-42c7-9fdc-13549ccf4dad",
      "name": "OpenAI Chat Model1",
      "executeOnce": true,
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "model": "text-embedding-3-small",
        "options": {}
      },
      "type": "@n8n/n8n-nodes-langchain.embeddingsOpenAi",
      "typeVersion": 1,
      "position": [
        12000,
        992
      ],
      "id": "c53f087f-41cd-4a9b-aef5-c9a2ba5b10fc",
      "name": "Embeddings OpenAI1",
      "rewireOutputLogTo": "ai_tool",
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "mode": "retrieve-as-tool",
        "toolDescription": "Busca informa\u00e7\u00f5es relevantes na base de conhecimento da empresa para responder a perguntas do cliente. Use esta ferramenta quando o cliente fizer perguntas sobre produtos, servi\u00e7os, pol\u00edticas, procedimentos ou qualquer informa\u00e7\u00e3o espec\u00edfica da empresa que voc\u00ea n\u00e3o tenha certeza. Retorna trechos de documentos relevantes.",
        "tableName": {
          "__rl": true,
          "value": "document_chunks",
          "mode": "list",
          "cachedResultName": "document_chunks"
        },
        "filters": {
          "filterType": "manual",
          "matchType": "allMatch",
          "conditions": [
            {
              "keyName": "company_id",
              "condition": "equal",
              "keyValue": "={{ $('Webhook').first().json.body.controlia.company_id }}"
            },
            {
              "keyName": "is_indexed",
              "condition": "equal",
              "keyValue": "true"
            }
          ]
        },
        "options": {
          "topK": 5,
          "similarityThreshold": 0.7
        }
      },
      "type": "@n8n/n8n-nodes-langchain.vectorStoreSupabase",
      "typeVersion": 1.3,
      "position": [
        12144,
        976
      ],
      "id": "341a3a32-4bbb-4983-b3ec-b2b8a0c8d6d2",
      "name": "Supabase Vector Store",
      "credentials": {
        "supabaseApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "sessionIdType": "customKey",
        "sessionKey": "={{ $('Webhook').first().json.body.controlia.conversation_id }}_assistente",
        "contextWindowLength": 10
      },
      "type": "@n8n/n8n-nodes-langchain.memoryBufferWindow",
      "typeVersion": 1.3,
      "position": [
        11088,
        992
      ],
      "id": "483d6058-d78b-48f8-8990-f09107dab01d",
      "name": "Simple Memory"
    },
    {
      "parameters": {
        "modelName": "models/gemma-3-4b-it",
        "options": {}
      },
      "type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
      "typeVersion": 1,
      "position": [
        10448,
        1152
      ],
      "id": "ef818f33-c0eb-4008-912b-35db40ce8ed1",
      "name": "Google Gemini Chat Model",
      "alwaysOutputData": true,
      "credentials": {
        "googlePalmApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "options": {}
      },
      "type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
      "typeVersion": 1,
      "position": [
        10608,
        1152
      ],
      "id": "e7257fc4-7620-48ad-9d74-bd4ca19be734",
      "name": "Google Gemini Chat Model1",
      "alwaysOutputData": true,
      "credentials": {
        "googlePalmApi": {
          "name": "<your credential>"
        }
      }
    }
  ],
  "connections": {
    "Webhook": {
      "main": [
        [
          {
            "node": "Define:Mensagem e Session_id",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Criar/atualizar sessionId": {
      "main": [
        [
          {
            "node": "Get row(s)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get row(s)": {
      "main": [
        [
          {
            "node": "#Prompt IA de Atendimento e Triagem",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "AtualizaVariaveisExtrator": {
      "main": [
        [
          {
            "node": "AI Agent - Respostas",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "AtualizaPerguntaResposta": {
      "main": [
        [
          {
            "node": "Prepare Response Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Data table Update": {
      "ai_tool": [
        [
          {
            "node": "AI Agent - Respostas",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Get row(s)1": {
      "main": [
        [
          {
            "node": "AtualizaPerguntaResposta",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Processar Prompt Extractor": {
      "main": [
        [
          {
            "node": "Information Extractor",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Information Extractor": {
      "main": [
        [
          {
            "node": "AtualizaVariaveisExtrator",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Define:Mensagem e Session_id": {
      "main": [
        [
          {
            "node": "Criar/atualizar sessionId",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "#Prompt IA de Atendimento e Triagem": {
      "main": [
        [
          {
            "node": "Concatenador #IA de Atendimento e Triagem",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Concatenador #IA de Atendimento e Triagem": {
      "main": [
        [
          {
            "node": "#Prompt Extra\u00e7\u00e3o de Dados",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "#Prompt Extra\u00e7\u00e3o de Dados": {
      "main": [
        [
          {
            "node": "Processar Prompt Extractor",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Prepare Response Data": {
      "main": [
        [
          {
            "node": "HTTP Request (Enviar Resposta)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Busca Disponibilidades": {
      "ai_tool": [
        [
          {
            "node": "AI Agent - Respostas",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Atualiza Eventos": {
      "ai_tool": [
        [
          {
            "node": "AI Agent - Respostas",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Cria Evento": {
      "ai_tool": [
        [
          {
            "node": "AI Agent - Respostas",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Exclui Eventos": {
      "ai_tool": [
        [
          {
            "node": "AI Agent - Respostas",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "AI Agent - Respostas": {
      "main": [
        [
          {
            "node": "Get row(s)1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "OpenRouter Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "Information Extractor",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "OpenRouter Chat Model1": {
      "ai_languageModel": [
        [
          {
            "node": "AI Agent - Respostas",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Embeddings OpenAI1": {
      "ai_embedding": [
        [
          {
            "node": "Supabase Vector Store",
            "type": "ai_embedding",
            "index": 0
          }
        ]
      ]
    },
    "Supabase Vector Store": {
      "ai_tool": [
        [
          {
            "node": "AI Agent - Respostas",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Simple Memory": {
      "ai_memory": [
        [
          {
            "node": "AI Agent - Respostas",
            "type": "ai_memory",
            "index": 0
          }
        ]
      ]
    },
    "Google Gemini Chat Model": {
      "ai_languageModel": [
        []
      ]
    },
    "Google Gemini Chat Model1": {
      "ai_languageModel": [
        []
      ]
    }
  },
  "meta": {
    "templateId": "self-building-ai-agent",
    "templateCredsSetupCompleted": true
  }
}