AutomationFlowsAI & RAG › Agendamento Instituto Ariana Borges - Corrigido

Agendamento Instituto Ariana Borges - Corrigido

Agendamento Instituto Ariana Borges - Corrigido. Uses lmChatGoogleGemini, googleCalendar, informationExtractor. Webhook trigger; 14 nodes.

Webhook trigger★★★★☆ complexityAI-powered14 nodesGoogle Gemini ChatGoogle CalendarInformation Extractor
AI & RAG Trigger: Webhook Nodes: 14 Complexity: ★★★★☆ AI nodes: yes Added:

This workflow follows the Informationextractor → Google Gemini Chat recipe pattern — see all workflows that pair these two integrations.

The workflow JSON

Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →

Download .json
{
  "name": "Agendamento Instituto Ariana Borges - Corrigido",
  "nodes": [
    {
      "parameters": {
        "options": {}
      },
      "type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
      "typeVersion": 1,
      "position": [
        7648,
        5792
      ],
      "id": "056cd582-4b49-4ae2-b1c5-03c1f732272a",
      "name": "Google Gemini Chat Model1",
      "credentials": {
        "googlePalmApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "respondWith": "json",
        "responseBody": "={{ JSON.stringify({ available: $json.available, message: $json.message, suggestedTimes: $json.suggestedTimes }) }}",
        "options": {
          "responseCode": 200,
          "responseHeaders": {
            "entries": [
              {
                "name": "Access-Control-Allow-Origin",
                "value": "*"
              }
            ]
          }
        }
      },
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1.2,
      "position": [
        8368,
        6016
      ],
      "id": "7cbff091-0c1c-4062-b6aa-3557dfd82174",
      "name": "Responder - Disponibilidade1"
    },
    {
      "parameters": {
        "respondWith": "json",
        "responseBody": "={{ JSON.stringify({ success: false, message: 'N\u00e3o foi poss\u00edvel completar o agendamento. Por favor, tente novamente ou entre em contato via WhatsApp.', error: $json.message || 'Erro desconhecido' }) }}",
        "options": {
          "responseCode": 500,
          "responseHeaders": {
            "entries": [
              {
                "name": "Access-Control-Allow-Origin",
                "value": "*"
              }
            ]
          }
        }
      },
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1.2,
      "position": [
        8368,
        5776
      ],
      "id": "60124c6a-20ae-4503-9f48-4f00f2988982",
      "name": "Responder - Erro1"
    },
    {
      "parameters": {
        "respondWith": "json",
        "responseBody": "={{ JSON.stringify({ success: true, message: 'Tudo certo! Voc\u00ea est\u00e1 agendado(a) para ' + $('Processar Resposta da IA1').item.json.interpretedDate + '. \ud83c\udf89', booking: { customer: $('Processar Resposta da IA1').item.json.customerName, service: $('Processar Resposta da IA1').item.json.serviceType, dateTime: $('Processar Resposta da IA1').item.json.interpretedDate, calendarEventId: $json.id } }) }}",
        "options": {
          "responseCode": 200,
          "responseHeaders": {
            "entries": [
              {
                "name": "Access-Control-Allow-Origin",
                "value": "*"
              }
            ]
          }
        }
      },
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1.2,
      "position": [
        8368,
        5584
      ],
      "id": "1579ba20-6257-4fcc-a1ac-e34e93225905",
      "name": "Responder - Agendamento Confirmado1"
    },
    {
      "parameters": {
        "jsCode": "const aiResponse = $input.first().json.output;\nconst preferredTimeframe = $input.all().find(item => item.json.preferredTimeframe)?.json.preferredTimeframe || '';\nlet availabilityCheck;\n\ntry {\n  // Check if aiResponse is already an object or a string\n  if (typeof aiResponse === 'object') {\n    availabilityCheck = aiResponse;\n  } else if (typeof aiResponse === 'string') {\n    const cleanJson = aiResponse.replace(/```json\\n?|```/g, '').trim();\n    availabilityCheck = JSON.parse(cleanJson);\n  } else {\n    throw new Error('Formato de resposta inesperado');\n  }\n} catch (error) {\n  availabilityCheck = {\n    available: true,\n    requestedDateTime: new Date().toISOString(),\n    message: \"Estamos verificando a disponibilidade.\",\n    suggestedTimes: []\n  };\n}\n\n// Formatar o hor\u00e1rio solicitado de forma leg\u00edvel\nlet requestedTimeFormatted = preferredTimeframe;\nif (availabilityCheck.requestedDateTime) {\n  try {\n    const dt = new Date(availabilityCheck.requestedDateTime);\n    const daysOfWeek = ['Domingo', 'Segunda-feira', 'Ter\u00e7a-feira', 'Quarta-feira', 'Quinta-feira', 'Sexta-feira', 'S\u00e1bado'];\n    const day = daysOfWeek[dt.getDay()];\n    const date = dt.getDate();\n    const month = dt.getMonth() + 1;\n    const hour = dt.getHours();\n    requestedTimeFormatted = `${day}, ${date}/${month} \u00e0s ${hour}h`;\n  } catch (e) {\n    // Manter o formato original se falhar\n  }\n}\n\n// Gerar hor\u00e1rios de fallback se IA n\u00e3o retornou\nif (!availabilityCheck.suggestedTimes || availabilityCheck.suggestedTimes.length === 0) {\n  const now = new Date();\n  const tomorrow = new Date(now);\n  tomorrow.setDate(tomorrow.getDate() + 1);\n  \n  const dayAfter = new Date(now);\n  dayAfter.setDate(dayAfter.getDate() + 2);\n  \n  const daysOfWeek = ['Domingo', 'Segunda-feira', 'Ter\u00e7a-feira', 'Quarta-feira', 'Quinta-feira', 'Sexta-feira', 'S\u00e1bado'];\n  \n  availabilityCheck.suggestedTimes = [\n    `${daysOfWeek[tomorrow.getDay()]}, ${tomorrow.getDate()}/${tomorrow.getMonth() + 1} \u00e0s 9h`,\n    `${daysOfWeek[tomorrow.getDay()]}, ${tomorrow.getDate()}/${tomorrow.getMonth() + 1} \u00e0s 14h`,\n    `${daysOfWeek[dayAfter.getDay()]}, ${dayAfter.getDate()}/${dayAfter.getMonth() + 1} \u00e0s 10h`\n  ];\n}\n\nconst calendarEvents = $input.all().filter(item => item.json.id).map(item => ({\n  start: item.json.start?.dateTime,\n  end: item.json.end?.dateTime,\n  summary: item.json.summary\n}));\n\nconst requestedDateTime = availabilityCheck.requestedDateTime;\nconst hasConflict = calendarEvents.some(event => {\n  if (!event.start || !requestedDateTime) return false;\n  return new Date(event.start).toISOString() === new Date(requestedDateTime).toISOString();\n});\n\nlet finalMessage;\nif (hasConflict) {\n  finalMessage = `\ud83d\ude14 Infelizmente ${requestedTimeFormatted} j\u00e1 est\u00e1 ocupado.`;\n  if (availabilityCheck.suggestedTimes?.length > 0) {\n    finalMessage += `\\n\\nHor\u00e1rios dispon\u00edveis:\\n${availabilityCheck.suggestedTimes.map(t => `\u2022 ${t}`).join('\\n')}`;\n  }\n} else {\n  finalMessage = `\u2705 \u2728 \u00d3tima not\u00edcia! ${requestedTimeFormatted} est\u00e1 dispon\u00edvel!`;\n  if (availabilityCheck.suggestedTimes?.length > 0) {\n    finalMessage += `\\n\\nOutros hor\u00e1rios dispon\u00edveis:\\n${availabilityCheck.suggestedTimes.map(t => `\u2022 ${t}`).join('\\n')}`;\n  }\n}\n\nreturn {\n  json: {\n    available: !hasConflict,\n    message: finalMessage,\n    requestedDateTime: requestedDateTime,\n    suggestedTimes: availabilityCheck.suggestedTimes || []\n  }\n};"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        8144,
        6016
      ],
      "id": "bdff1360-b42c-4340-8485-70231f9a1e31",
      "name": "Processar Disponibilidade1"
    },
    {
      "parameters": {
        "operation": "getAll",
        "calendar": {
          "__rl": true,
          "value": "24ce01fc2a4267089544e584a637f9c021ad6c10ba81a0d8eaa44f66f6767d83@group.calendar.google.com",
          "mode": "list",
          "cachedResultName": "Site 2026"
        },
        "options": {
          "timeZone": "America/Sao_Paulo"
        }
      },
      "type": "n8n-nodes-base.googleCalendar",
      "typeVersion": 1.3,
      "position": [
        7920,
        6016
      ],
      "id": "56556c14-ae2b-430d-b3b4-d531219d70cc",
      "name": "Google Calendar - Listar Eventos1",
      "credentials": {
        "googleCalendarOAuth2Api": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "calendar": {
          "__rl": true,
          "value": "24ce01fc2a4267089544e584a637f9c021ad6c10ba81a0d8eaa44f66f6767d83@group.calendar.google.com",
          "mode": "list",
          "cachedResultName": "Site 2026"
        },
        "start": "={{$json.startDateTime}}",
        "end": "={{$json.endDateTime}}",
        "options": {
          "description": "={{$json.eventDescription}}",
          "summary": "={{$json.eventSummary}}",
          "attendees": [
            "={{$json.customerEmail}}"
          ],
          "sendUpdates": "all",
          "timeZone": "America/Sao_Paulo"
        }
      },
      "type": "n8n-nodes-base.googleCalendar",
      "typeVersion": 1.3,
      "position": [
        8144,
        5680
      ],
      "id": "7d661366-eda9-4961-9fe7-6a851f9bd160",
      "name": "Google Calendar - Criar Evento1",
      "credentials": {
        "googleCalendarOAuth2Api": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "jsCode": "const aiResponse = $input.item.json.output;\n\nlet parsedDate;\ntry {\n  // Check if aiResponse is already an object or a string\n  if (typeof aiResponse === 'object') {\n    parsedDate = aiResponse;\n  } else if (typeof aiResponse === 'string') {\n    const cleanJson = aiResponse.replace(/```json\\n?|```/g, '').trim();\n    parsedDate = JSON.parse(cleanJson);\n  } else {\n    throw new Error('Formato de resposta inesperado');\n  }\n} catch (error) {\n  throw new Error('Erro ao parsear resposta da IA: ' + error.message);\n}\n\nif (!parsedDate.startDateTime || !parsedDate.endDateTime) {\n  throw new Error('IA n\u00e3o retornou datas v\u00e1lidas');\n}\n\nreturn {\n  json: {\n    customerName: $input.item.json.customerName,\n    customerPhone: $input.item.json.customerPhone,\n    customerEmail: $input.item.json.customerEmail,\n    serviceType: $input.item.json.serviceType,\n    description: $input.item.json.description,\n    startDateTime: parsedDate.startDateTime,\n    endDateTime: parsedDate.endDateTime,\n    interpretedDate: parsedDate.interpretedDate,\n    eventSummary: `${$input.item.json.serviceType} - ${$input.item.json.customerName}`,\n    eventDescription: `\ud83d\udccb Agendamento\\n\\n\ud83d\udc64 Cliente: ${$input.item.json.customerName}\\n\ud83d\udce7 Email: ${$input.item.json.customerEmail}\\n\ud83d\udcf1 Telefone: ${$input.item.json.customerPhone}\\n\\n\ud83c\udf1f Servi\u00e7o: ${$input.item.json.serviceType}\\n\ud83d\udcdd ${$input.item.json.description}`\n  }\n};"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        7920,
        5680
      ],
      "id": "f14f0ca3-edb5-42e7-8653-f82e37612337",
      "name": "Processar Resposta da IA1"
    },
    {
      "parameters": {
        "text": "={{ $json.preferredTimeframe }}",
        "schemaType": "fromJson",
        "jsonSchemaExample": "{\n  \"available\": true,\n  \"requestedDateTime\": \"YYYY-MM-DDTHH:mm:00-03:00\",\n  \"message\": \"mensagem amig\u00e1vel sobre disponibilidade\",\n  \"suggestedTimes\": [\"hor\u00e1rio1\", \"hor\u00e1rio2\", \"hor\u00e1rio3\"]\n}",
        "options": {
          "systemPromptTemplate": "Voc\u00ea \u00e9 um assistente que verifica disponibilidade de agenda.\n\nDATA ATUAL: {{$json.currentDate}}\nTIMEZONE: America/Sao_Paulo\nHOR\u00c1RIO COMERCIAL: 9h \u00e0s 19h (Segunda \u00e0 Quarta)\nFECHADO: Quinta, Sexta, S\u00e1bado e Domingo\n\nSua tarefa:\n1. Interpretar o hor\u00e1rio solicitado\n2. Converter para data ISO 8601 com timezone -03:00\n3. Verificar se est\u00e1 dentro do hor\u00e1rio comercial (Segunda \u00e0 Quarta, 9h \u00e0s 19h)\n4. OBRIGAT\u00d3RIO: Sugerir SEMPRE pelo menos 3 hor\u00e1rios alternativos dispon\u00edveis\n\nFormato de resposta (JSON):\n- available: boolean (true se o hor\u00e1rio est\u00e1 dentro do hor\u00e1rio comercial E \u00e9 Segunda/Ter\u00e7a/Quarta, false caso contr\u00e1rio)\n- requestedDateTime: string ISO 8601 (exemplo: 2026-01-30T14:00:00-03:00)\n- message: string com mensagem amig\u00e1vel sobre a disponibilidade\n- suggestedTimes: array de strings - OBRIGAT\u00d3RIO incluir pelo menos 3 hor\u00e1rios (exemplos: Segunda-feira \u00e0s 9h, Ter\u00e7a-feira \u00e0s 14h, Quarta-feira \u00e0s 10h)\n\nIMPORTANTE: \n- O campo suggestedTimes NUNCA pode estar vazio. Sempre sugira hor\u00e1rios pr\u00f3ximos ao solicitado.\n- S\u00f3 aceite hor\u00e1rios de Segunda \u00e0 Quarta, das 9h \u00e0s 19h\n- Rejeite qualquer hor\u00e1rio fora deste per\u00edodo\n\nRetorne APENAS o JSON sem markdown."
        }
      },
      "type": "@n8n/n8n-nodes-langchain.informationExtractor",
      "typeVersion": 1,
      "position": [
        7648,
        6016
      ],
      "id": "d1a33f5c-1bb9-46b5-9d3a-ee2a4795c57c",
      "name": "IA - Verificar Disponibilidade1"
    },
    {
      "parameters": {
        "text": "={{ $json.preferredTimeframe }}",
        "schemaType": "fromJson",
        "jsonSchemaExample": "{\n  \"startDateTime\": \"YYYY-MM-DDTHH:mm:00-03:00\",\n  \"endDateTime\": \"YYYY-MM-DDTHH:mm:00-03:00\",\n  \"interpretedDate\": \"descri\u00e7\u00e3o leg\u00edvel\"\n}",
        "options": {
          "systemPromptTemplate": "Voc\u00ea \u00e9 um assistente que converte texto em datas no formato ISO 8601.\n\nDATA ATUAL DE REFER\u00caNCIA: {{$json.currentDate}}\nTIMEZONE: America/Sao_Paulo (UTC-03:00)\nHOR\u00c1RIO COMERCIAL: 9h \u00e0s 19h (Segunda \u00e0 Quarta)\nFECHADO: Quinta, Sexta, S\u00e1bado e Domingo\n\nSua tarefa:\n1. Interpretar o texto de hor\u00e1rio preferido\n2. Converter para formato ISO 8601 com timezone -03:00\n3. Dura\u00e7\u00e3o padr\u00e3o: 1 hora\n4. Se for \"manh\u00e3\": 9h, \"tarde\": 14h, \"qualquer hor\u00e1rio\": 14h\n\nFormato de resposta (JSON):\n- startDateTime: string ISO 8601 (exemplo: 2026-01-30T14:00:00-03:00)\n- endDateTime: string ISO 8601 (1 hora depois do start)\n- interpretedDate: string leg\u00edvel (exemplo: Ter\u00e7a-feira, 30 de janeiro \u00e0s 14h)\n\nRetorne APENAS o JSON sem markdown."
        }
      },
      "type": "@n8n/n8n-nodes-langchain.informationExtractor",
      "typeVersion": 1,
      "position": [
        7648,
        5568
      ],
      "id": "aac6e532-5ebb-487e-ac12-ed72d8f17c4a",
      "name": "IA - Converter Texto para Data1"
    },
    {
      "parameters": {
        "jsCode": "const preferredTimeframe = $input.item.json.preferred_timeframe;\nconst currentDate = new Date().toISOString();\n\nreturn {\n  json: {\n    preferredTimeframe,\n    currentDate\n  }\n};"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        7344,
        6016
      ],
      "id": "23e66ba8-85c8-4a22-a842-b1db88564e26",
      "name": "Extrair Dados de Disponibilidade1"
    },
    {
      "parameters": {
        "jsCode": "const customerName = $input.item.json.customer_name;\nconst customerPhone = $input.item.json.customer_phone;\nconst customerEmail = $input.item.json.customer_email;\nconst serviceType = $input.item.json.service_type;\nconst description = $input.item.json.description;\nconst preferredTimeframe = $input.item.json.preferred_timeframe;\n\nreturn {\n  json: {\n    customerName,\n    customerPhone,\n    customerEmail,\n    serviceType,\n    description,\n    preferredTimeframe,\n    currentDate: new Date().toISOString()\n  }\n};"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        7344,
        5680
      ],
      "id": "d0c753bf-8322-4088-8291-de445f49b4b2",
      "name": "Extrair Dados do Booking1"
    },
    {
      "parameters": {
        "httpMethod": "POST",
        "path": "book_appointment",
        "responseMode": "responseNode",
        "options": {
          "responseHeaders": {
            "entries": [
              {
                "name": "Access-Control-Allow-Origin",
                "value": "*"
              }
            ]
          }
        }
      },
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 2,
      "position": [
        7120,
        5680
      ],
      "id": "82829b5d-965c-4d3e-a51f-a1bd2f991833",
      "name": "Webhook - Agendar1"
    },
    {
      "parameters": {
        "httpMethod": "POST",
        "path": "get_availability",
        "responseMode": "responseNode",
        "options": {
          "responseHeaders": {
            "entries": [
              {
                "name": "Access-Control-Allow-Origin",
                "value": "*"
              }
            ]
          }
        }
      },
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 2,
      "position": [
        7120,
        6016
      ],
      "id": "1e27ebc3-c6cd-46d4-8896-df2c434efd3b",
      "name": "Webhook - Verificar Disponibilidade1"
    }
  ],
  "connections": {
    "Google Gemini Chat Model1": {
      "ai_languageModel": [
        [
          {
            "node": "IA - Verificar Disponibilidade1",
            "type": "ai_languageModel",
            "index": 0
          },
          {
            "node": "IA - Converter Texto para Data1",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Processar Disponibilidade1": {
      "main": [
        [
          {
            "node": "Responder - Disponibilidade1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Google Calendar - Listar Eventos1": {
      "main": [
        [
          {
            "node": "Processar Disponibilidade1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Google Calendar - Criar Evento1": {
      "main": [
        [
          {
            "node": "Responder - Agendamento Confirmado1",
            "type": "main",
            "index": 0
          }
        ]
      ],
      "error": [
        [
          {
            "node": "Responder - Erro1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Processar Resposta da IA1": {
      "main": [
        [
          {
            "node": "Google Calendar - Criar Evento1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "IA - Verificar Disponibilidade1": {
      "main": [
        [
          {
            "node": "Google Calendar - Listar Eventos1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "IA - Converter Texto para Data1": {
      "main": [
        [
          {
            "node": "Processar Resposta da IA1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extrair Dados de Disponibilidade1": {
      "main": [
        [
          {
            "node": "IA - Verificar Disponibilidade1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extrair Dados do Booking1": {
      "main": [
        [
          {
            "node": "IA - Converter Texto para Data1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Webhook - Agendar1": {
      "main": [
        [
          {
            "node": "Extrair Dados do Booking1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Webhook - Verificar Disponibilidade1": {
      "main": [
        [
          {
            "node": "Extrair Dados de Disponibilidade1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "settings": {
    "executionOrder": "v1"
  },
  "staticData": null,
  "tags": [],
  "triggerCount": 0,
  "meta": {
    "templateCredsSetupCompleted": true
  }
}

Credentials you'll need

Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.

Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

Agendamento Instituto Ariana Borges - Corrigido. Uses lmChatGoogleGemini, googleCalendar, informationExtractor. Webhook trigger; 14 nodes.

Source: https://github.com/designrique/site-ariana-borges/blob/bb6e58b46e36bdb3d7fb3d9e471c7b11bd4c21c3/guias/n8n-workflow-agendamento-corrigido.json.bak — original creator credit. Request a take-down →

More AI & RAG workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

AI & RAG

Who is this for? Event organizers, conference planners, and marketing teams fighting registration drop-off who want 4-field forms with LinkedIn-level attendee intelligence. What problem is this workfl

Data Table, HubSpot, Email Send +4
AI & RAG

This workflow contains community nodes that are only compatible with the self-hosted version of n8n.

@Brightdata/N8N Nodes Brightdata, Information Extractor, Google Gemini Chat +2
AI & RAG

This n8n template automates scraping content from Skool communities using the Olostep API. It collects structured data from Skool pages and stores it in a clean format, making it easy to analyze commu

N8N Nodes Olostep, Form Trigger, HTTP Request +3
AI & RAG

This n8n template monitors specified GitHub repositories. When a new release is published, it automatically fetches the information, uses AI (Google Gemini by default) to summarize and translate it in

Slack, Information Extractor, Google Gemini Chat +2
AI & RAG

It is ideal for businesses handling vendor invoices, reimbursement forms, or bulk document intake.

HTTP Request, Information Extractor, Google Gemini Chat +3