AutomationFlowsAI & RAG › Reagendador

Reagendador

REAGENDADOR. Uses executeWorkflowTrigger, httpRequest, openAi. Event-driven trigger; 24 nodes.

Event trigger★★★★☆ complexityAI-powered24 nodesExecute Workflow TriggerHTTP RequestOpenAI
AI & RAG Trigger: Event Nodes: 24 Complexity: ★★★★☆ AI nodes: yes Added:

This workflow follows the Execute Workflow Trigger → HTTP Request 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": "REAGENDADOR",
  "nodes": [
    {
      "parameters": {
        "inputSource": "jsonExample",
        "jsonExample": "{\n  \"objetivo\": \"reagendar/cancelar\",\n  \"email\": \"ivanfuentes1024@gmail.com\",\n  \"name\": \"Ivan Fuentes\",\n  \"rescheduleDate\": \"2025-08-04T15:00:00-06:00\",\n  \"cancelDate\": \"2025-08-04T15:00:00-06:00\",\n  \"reason\": \"motivo de cancelacion/reagendar\"\n}"
      },
      "type": "n8n-nodes-base.executeWorkflowTrigger",
      "typeVersion": 1.1,
      "position": [
        -1296,
        528
      ],
      "id": "172c4f5c-8a1a-4cfe-9657-45f38d838e44",
      "name": "When Executed by Another Workflow"
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict",
            "version": 2
          },
          "conditions": [
            {
              "id": "ab387e66-7f32-486f-bbce-320c65a04ab1",
              "leftValue": "={{ $json.objetivo }}",
              "rightValue": "reagendar",
              "operator": {
                "type": "string",
                "operation": "equals",
                "name": "filter.operator.equals"
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        -1088,
        528
      ],
      "id": "4b519911-a679-40a2-9515-9db2e98cf6d8",
      "name": "If"
    },
    {
      "parameters": {
        "url": "https://api.cal.com/v2/bookings",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "sendQuery": true,
        "queryParameters": {
          "parameters": [
            {
              "name": "status",
              "value": "upcoming"
            },
            {
              "name": "attendeeEmail:",
              "value": "={{ $json.email }}"
            }
          ]
        },
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "cal-api-version",
              "value": "2024-06-11"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        -864,
        400
      ],
      "id": "cd89ed1d-a0ce-45c1-9455-6f923850cd32",
      "name": "HTTP Request",
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "jsCode": "// N8N Function Node - Formatear datos de bookings en un solo item\n// Extrae: fechas, nombre, correo, bookinguid e id\n\nconst inputData = $input.all();\nconst formattedBookings = [];\n\n// Procesar cada item de entrada\ninputData.forEach(item => {\n  const data = item.json;\n  \n  // Verificar si existe la estructura de datos esperada\n  if (data.status === \"success\" && data.data && data.data.bookings) {\n    \n    // Procesar cada booking\n    data.data.bookings.forEach(booking => {\n      const formattedBooking = {\n        id: booking.id,\n        bookingUid: booking.uid,\n        startTime: booking.startTime,\n        endTime: booking.endTime,\n        createdAt: booking.createdAt,\n        name: booking.responses?.name || booking.attendees?.[0]?.name || 'Sin nombre',\n        email: booking.responses?.email || booking.attendees?.[0]?.email || 'Sin email'\n      };\n      \n      formattedBookings.push(formattedBooking);\n    });\n  }\n});\n\n// Crear el string formateado legible\nlet formattedText = \"\ud83d\udcc5 CITAS AGENDADAS\\n\";\nformattedText += \"=\".repeat(30) + \"\\n\\n\";\n\nformattedBookings.forEach((booking, index) => {\n  formattedText += `\ud83d\udccb CITA #${index + 1}\\n`;\n  formattedText += `ID: ${booking.id}\\n`;\n  formattedText += `UID: ${booking.bookingUid}\\n`;\n  formattedText += `Nombre: ${booking.name}\\n`;\n  formattedText += `Email: ${booking.email}\\n`;\n  formattedText += `Fecha Inicio: ${new Date(booking.startTime).toLocaleString('es-CR', {timeZone: 'America/Costa_Rica'})}\\n`;\n  formattedText += `Fecha Fin: ${new Date(booking.endTime).toLocaleString('es-CR', {timeZone: 'America/Costa_Rica'})}\\n`;\n  formattedText += `Creado: ${new Date(booking.createdAt).toLocaleString('es-CR', {timeZone: 'America/Costa_Rica'})}\\n`;\n  formattedText += \"-\".repeat(40) + \"\\n\\n\";\n});\n\nformattedText += `\ud83d\udcca TOTAL DE CITAS: ${formattedBookings.length}`;\n\n// Crear el objeto con toda la informaci\u00f3n\nconst result = {\n  bookings: formattedBookings,\n  totalBookings: formattedBookings.length,\n  formattedString: formattedText,\n  jsonString: JSON.stringify(formattedBookings, null, 2)\n};\n\n// Retornar un solo item con toda la informaci\u00f3n\nreturn [{\n  json: result\n}];"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -640,
        400
      ],
      "id": "6e3fe596-6688-42fe-985f-c7033d6c52f7",
      "name": "Code"
    },
    {
      "parameters": {
        "modelId": {
          "__rl": true,
          "value": "gpt-5-mini",
          "mode": "list",
          "cachedResultName": "GPT-5-MINI"
        },
        "messages": {
          "values": [
            {
              "content": "=Buscador de Citas para Reagendar\n\nEres un experto asistente para encontrar y gestionar citas m\u00e9dicas. Tu funci\u00f3n es buscar citas agendadas para pacientes que desean reagendarlas.\n\n## Tu tarea:\n\n1. Buscar la cita del paciente usando su correo electr\u00f3nico y/o nombre\n\n2. Validar que la informaci\u00f3n coincida exactamente\n\n3. Responder en formato JSON estructurado\n\n## Criterios de b\u00fasqueda:\n\n- Prioridad 1: Buscar por correo electr\u00f3nico (considera peque\u00f1os errores como puntos o letras mal pero que haya una coincidencia alta)\n\n- Prioridad 2: Si no encuentra por correo, buscar por nombre (coincidencia parcial aceptable)\n\n- Sensibilidad: Ignorar may\u00fasculas/min\u00fasculas y acentos en nombres\n\n## Formato de respuesta:\n\n### \u2705 SI ENCUENTRA LA CITA:\n\n```json\n\n{\n\n  \"status\": \"found\",\n\n  \"message\": \"Cita encontrada exitosamente\",\n\n  \"appointment\": {\n\n    \"id\": \"ID_de_la_cita\",\n\n    \"bookingUid\": \"UID_de_la_cita\",\n\n    \"patientName\": \"Nombre del paciente\",\n\n    \"patientEmail\": \"correo@del.paciente\",\n\n    \"startTime\": \"fecha_y_hora_inicio\",\n\n    \"endTime\": \"fecha_y_hora_fin\",\n\n    \"createdAt\": \"fecha_creacion\",\n\n    \"appointmentType\": \"tipo_de_cita_si_disponible\"\n\n  }\n\n}\n\n```\n\n### \u274c SI NO ENCUENTRA LA CITA:\n\n```json\n\n{\n\n  \"status\": \"not_found\",\n\n  \"message\": \"No se encontr\u00f3 ninguna cita agendada\",\n\n  \"suggestions\": [\n\n    \"Verifique que el correo electr\u00f3nico est\u00e9 escrito correctamente\",\n\n    \"Intente con un correo electr\u00f3nico alternativo\",\n\n    \"Verifique que el nombre est\u00e9 completo (nombre y apellidos)\",\n\n    \"La cita podr\u00eda estar registrada bajo un nombre ligeramente diferente\"\n\n  ],\n\n  \"searchCriteria\": {\n\n    \"emailSearched\": \"correo_buscado\",\n\n    \"nameSearched\": \"nombre_buscado\"\n\n  }\n\n}\n\n```\n\n### \u26a0\ufe0f SI ENCUENTRA M\u00daLTIPLES CITAS:\n\n```json\n\n{\n\n  \"status\": \"multiple_found\",\n\n  \"message\": \"Se encontraron m\u00faltiples citas para este paciente\",\n\n  \"appointments\": [\n\n    {\n\n      \"id\": \"ID_cita_1\",\n\n      \"startTime\": \"fecha_1\",\n\n      \"endTime\": \"fecha_1_fin\"\n\n    },\n\n    {\n\n      \"id\": \"ID_cita_2\", \n\n      \"startTime\": \"fecha_2\",\n\n      \"endTime\": \"fecha_2_fin\"\n\n    }\n\n  ],\n\n  \"note\": \"Por favor especifique cu\u00e1l cita desea reagendar proporcionando la fecha de la cita\"\n\n}\n\n```\n\n## Instrucciones adicionales:\n\n- Siempre responde \u00fanicamente en formato JSON v\u00e1lido\n\n- No agregues texto adicional fuera del JSON\n\n- Valida que las fechas est\u00e9n en el futuro (citas pasadas no se pueden reagendar)\n\n- Si hay dudas sobre coincidencias parciales de nombres, incl\u00fayelas como posibles resultados\n\n## Datos requeridos para procesar:\n\n- Correo del paciente: [CORREO_A_BUSCAR]\n\n- Nombre del paciente: [NOMBRE_A_BUSCAR]  \n\n- Lista de citas agendadas: [JSON_CON_TODAS_LAS_CITAS]\n\nCuando tengas una cita duplicada el mismo dia a la misma hora elige el primero\n\nSi en el input te dicen una fecha de una cita y tienes multiples citas, solo da la de la fecha",
              "role": "system"
            },
            {
              "content": "=CITA A BUSCAR: \nEmail:{{ $('When Executed by Another Workflow').item.json.email }}\nNombre: {{ $('When Executed by Another Workflow').item.json.name }}\n\n{{ $json.formattedString }}"
            }
          ]
        },
        "jsonOutput": true,
        "options": {}
      },
      "type": "@n8n/n8n-nodes-langchain.openAi",
      "typeVersion": 1.8,
      "position": [
        -416,
        400
      ],
      "id": "ee0186c1-dc0f-4c6f-b5fe-a78d44e6866e",
      "name": "OpenAI",
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "rules": {
          "values": [
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict",
                  "version": 2
                },
                "conditions": [
                  {
                    "leftValue": "={{ $json.message.content.status }}",
                    "rightValue": "found",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    },
                    "id": "e0d43d36-b746-4abf-89f0-4ba1c97b484d"
                  }
                ],
                "combinator": "and"
              },
              "renameOutput": true,
              "outputKey": "SI ENCONTRO"
            },
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict",
                  "version": 2
                },
                "conditions": [
                  {
                    "id": "f376aae6-c7af-48a1-afeb-48b90c7d76bb",
                    "leftValue": "={{ $json.message.content.status }}",
                    "rightValue": "not_found",
                    "operator": {
                      "type": "string",
                      "operation": "equals",
                      "name": "filter.operator.equals"
                    }
                  }
                ],
                "combinator": "and"
              },
              "renameOutput": true,
              "outputKey": "NO ENCONTRO"
            },
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict",
                  "version": 2
                },
                "conditions": [
                  {
                    "id": "2cc33f75-89ef-4231-9159-0baec99447af",
                    "leftValue": "={{ $json.message.content.status }}",
                    "rightValue": "multiple_found",
                    "operator": {
                      "type": "string",
                      "operation": "equals",
                      "name": "filter.operator.equals"
                    }
                  }
                ],
                "combinator": "and"
              },
              "renameOutput": true,
              "outputKey": "ENCONTRO MULTIPLES"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.switch",
      "typeVersion": 3.2,
      "position": [
        -64,
        400
      ],
      "id": "8078fea4-5e3e-4a49-8e49-14ac61994513",
      "name": "Switch"
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "29114525-53f2-4c93-b81f-8662750fd70c",
              "name": "status",
              "value": "Se encontraron multiples, favor de especificar la fecha a reagendar",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        144,
        592
      ],
      "id": "aae655b5-2e58-45db-b1ec-f41e7827ac9f",
      "name": "Edit Fields"
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "29114525-53f2-4c93-b81f-8662750fd70c",
              "name": "status",
              "value": "No se encontro ninguna cita",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        224,
        432
      ],
      "id": "a919c456-c2d7-4a63-9038-3541e63621e7",
      "name": "Edit Fields1"
    },
    {
      "parameters": {
        "method": "POST",
        "url": "=https://api.cal.com/v2/bookings/{{ $('OpenAI').item.json.message.content.appointment.bookingUid }}/reschedule",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "cal-api-version",
              "value": "2024-08-13"
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        },
        "sendBody": true,
        "bodyParameters": {
          "parameters": [
            {
              "name": "start",
              "value": "={{ $('When Executed by Another Workflow').item.json.rescheduleDate }}"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        272,
        208
      ],
      "id": "840d7c35-ab8f-4117-b6a2-b1419a5e9efb",
      "name": "HTTP Request1",
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict",
            "version": 2
          },
          "conditions": [
            {
              "id": "332dee6d-73b2-409a-a08c-3fe713161079",
              "leftValue": "={{ $json.status }}",
              "rightValue": "success",
              "operator": {
                "type": "string",
                "operation": "equals",
                "name": "filter.operator.equals"
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        464,
        224
      ],
      "id": "23ee4080-4134-4ff6-899f-efddc12a3fa9",
      "name": "If1"
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "666ac12b-71e0-496c-9b70-ff342ddff3b6",
              "name": "status",
              "value": "=El evento se reagendo exitosamente para el  {{ $json.data.start.toDateTime().format('yyyy-MM-dd') }}",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        720,
        48
      ],
      "id": "b2cd3253-1956-4536-86c7-6bb34bbe0946",
      "name": "Edit Fields2"
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "24d6054a-3382-4310-870a-b9280986f21d",
              "name": "status",
              "value": "El evento no se pudo reagendar",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        752,
        352
      ],
      "id": "628c24ca-6808-4497-8bde-23570df4f374",
      "name": "Edit Fields3"
    },
    {
      "parameters": {
        "url": "https://api.cal.com/v2/bookings",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "sendQuery": true,
        "queryParameters": {
          "parameters": [
            {
              "name": "status",
              "value": "upcoming"
            },
            {
              "name": "attendeeEmail:",
              "value": "={{ $json.email }}"
            }
          ]
        },
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "cal-api-version",
              "value": "2024-06-11"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        -736,
        880
      ],
      "id": "3d4cc81f-3ec5-413b-9ad3-c13e79552fe1",
      "name": "HTTP Request2",
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "jsCode": "// N8N Function Node - Formatear datos de bookings en un solo item\n// Extrae: fechas, nombre, correo, bookinguid e id\n\nconst inputData = $input.all();\nconst formattedBookings = [];\n\n// Procesar cada item de entrada\ninputData.forEach(item => {\n  const data = item.json;\n  \n  // Verificar si existe la estructura de datos esperada\n  if (data.status === \"success\" && data.data && data.data.bookings) {\n    \n    // Procesar cada booking\n    data.data.bookings.forEach(booking => {\n      const formattedBooking = {\n        id: booking.id,\n        bookingUid: booking.uid,\n        startTime: booking.startTime,\n        endTime: booking.endTime,\n        createdAt: booking.createdAt,\n        name: booking.responses?.name || booking.attendees?.[0]?.name || 'Sin nombre',\n        email: booking.responses?.email || booking.attendees?.[0]?.email || 'Sin email'\n      };\n      \n      formattedBookings.push(formattedBooking);\n    });\n  }\n});\n\n// Crear el string formateado legible\nlet formattedText = \"\ud83d\udcc5 CITAS AGENDADAS\\n\";\nformattedText += \"=\".repeat(30) + \"\\n\\n\";\n\nformattedBookings.forEach((booking, index) => {\n  formattedText += `\ud83d\udccb CITA #${index + 1}\\n`;\n  formattedText += `ID: ${booking.id}\\n`;\n  formattedText += `UID: ${booking.bookingUid}\\n`;\n  formattedText += `Nombre: ${booking.name}\\n`;\n  formattedText += `Email: ${booking.email}\\n`;\n  formattedText += `Fecha Inicio: ${new Date(booking.startTime).toLocaleString('es-CR', {timeZone: 'America/Costa_Rica'})}\\n`;\n  formattedText += `Fecha Fin: ${new Date(booking.endTime).toLocaleString('es-CR', {timeZone: 'America/Costa_Rica'})}\\n`;\n  formattedText += `Creado: ${new Date(booking.createdAt).toLocaleString('es-CR', {timeZone: 'America/Costa_Rica'})}\\n`;\n  formattedText += \"-\".repeat(40) + \"\\n\\n\";\n});\n\nformattedText += `\ud83d\udcca TOTAL DE CITAS: ${formattedBookings.length}`;\n\n// Crear el objeto con toda la informaci\u00f3n\nconst result = {\n  bookings: formattedBookings,\n  totalBookings: formattedBookings.length,\n  formattedString: formattedText,\n  jsonString: JSON.stringify(formattedBookings, null, 2)\n};\n\n// Retornar un solo item con toda la informaci\u00f3n\nreturn [{\n  json: result\n}];"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -528,
        880
      ],
      "id": "d6298102-cf58-4fa3-9def-6d69492a63b6",
      "name": "Code1"
    },
    {
      "parameters": {
        "modelId": {
          "__rl": true,
          "value": "gpt-5-mini",
          "mode": "list",
          "cachedResultName": "GPT-5-MINI"
        },
        "messages": {
          "values": [
            {
              "content": "=# Prompt Mejorado - Buscador de Citas para Cancelar\n\nEres un experto asistente para encontrar y gestionar citas m\u00e9dicas. Tu funci\u00f3n es buscar citas agendadas para pacientes que desean cancelarlas.\n\n## Tu tarea:\n\n1. Buscar la cita del paciente usando su correo electr\u00f3nico y/o nombre\n\n2. Validar que la informaci\u00f3n coincida exactamente\n\n3. Verificar que la cita se pueda cancelar seg\u00fan las pol\u00edticas\n\n4. Responder en formato JSON estructurado\n\n## Criterios de b\u00fasqueda:\n\n- Prioridad 1: Buscar por correo electr\u00f3nico (coincidencia exacta)\n\n- Prioridad 2: Si no encuentra por correo, buscar por nombre (coincidencia parcial aceptable)\n\n- Sensibilidad: Ignorar may\u00fasculas/min\u00fasculas y acentos en nombres\n\n## Pol\u00edticas de cancelaci\u00f3n:\n\n- Tiempo m\u00ednimo: Citas deben cancelarse con al menos 2 horas de anticipaci\u00f3n\n\n- Estado v\u00e1lido: Solo citas con status \"ACCEPTED\" o \"CONFIRMED\" pueden cancelarse\n\n- Citas pasadas: No se pueden cancelar citas que ya ocurrieron\n\n## Formato de respuesta:\n\n### \u2705 SI ENCUENTRA LA CITA Y SE PUEDE CANCELAR:\n\n```json\n\n{\n\n  \"status\": \"found_cancellable\",\n\n  \"message\": \"Cita encontrada y disponible para cancelaci\u00f3n\",\n\n  \"appointment\": {\n\n    \"id\": \"ID_de_la_cita\",\n\n    \"bookingUid\": \"UID_de_la_cita\",\n\n    \"patientName\": \"Nombre del paciente\",\n\n    \"patientEmail\": \"correo@del.paciente\",\n\n    \"startTime\": \"fecha_y_hora_inicio\",\n\n    \"endTime\": \"fecha_y_hora_fin\",\n\n    \"createdAt\": \"fecha_creacion\",\n\n    \"appointmentType\": \"tipo_de_cita_si_disponible\",\n\n    \"currentStatus\": \"estado_actual\"\n\n  },\n\n  \"cancellationInfo\": {\n\n    \"canCancel\": true,\n\n    \"timeUntilAppointment\": \"tiempo_restante\",\n\n    \"cancellationDeadline\": \"fecha_limite_cancelacion\"\n\n  }\n\n}\n\n```\n\n### \u274c SI NO ENCUENTRA LA CITA:\n\n```json\n\n{\n\n  \"status\": \"not_found\",\n\n  \"message\": \"No se encontr\u00f3 ninguna cita agendada para cancelar\",\n\n  \"suggestions\": [\n\n    \"Verifique que el correo electr\u00f3nico est\u00e9 escrito correctamente\",\n\n    \"Intente con un correo electr\u00f3nico alternativo\",\n\n    \"Verifique que el nombre est\u00e9 completo (nombre y apellidos)\",\n\n    \"La cita podr\u00eda estar registrada bajo un nombre ligeramente diferente\",\n\n    \"Verifique que la cita no haya sido cancelada previamente\"\n\n  ],\n\n  \"searchCriteria\": {\n\n    \"emailSearched\": \"correo_buscado\",\n\n    \"nameSearched\": \"nombre_buscado\"\n\n  }\n\n}\n\n```\n\n### \ud83d\udccb SI ENCUENTRA M\u00daLTIPLES CITAS:\n\n```json\n\n{\n\n  \"status\": \"multiple_found\",\n\n  \"message\": \"Se encontraron m\u00faltiples citas para este paciente\",\n\n  \"appointments\": [\n\n    {\n\n      \"id\": \"ID_cita_1\",\n\n      \"startTime\": \"fecha_1\",\n\n      \"endTime\": \"fecha_1_fin\",\n\n      \"status\": \"estado_1\",\n\n      \"canCancel\": true\n\n    },\n\n    {\n\n      \"id\": \"ID_cita_2\", \n\n      \"startTime\": \"fecha_2\",\n\n      \"endTime\": \"fecha_2_fin\",\n\n      \"status\": \"estado_2\",\n\n      \"canCancel\": false\n\n    }\n\n  ],\n\n  \"note\": \"Por favor especifique cu\u00e1l cita desea cancelar proporcionando el ID o la fecha exacta\"\n\n}\n\n```\n\n### \ud83d\udeab SI LA CITA YA EST\u00c1 CANCELADA:\n\n```json\n\n{\n\n  \"status\": \"already_cancelled\",\n\n  \"message\": \"La cita ya ha sido cancelada previamente\",\n\n  \"appointment\": {\n\n    \"id\": \"ID_de_la_cita\",\n\n    \"patientName\": \"Nombre del paciente\",\n\n    \"startTime\": \"fecha_y_hora_inicio\",\n\n    \"currentStatus\": \"CANCELLED\",\n\n    \"cancelledAt\": \"fecha_de_cancelacion\"\n\n  }\n\n}\n\n```\n\n## Instrucciones adicionales:\n\n- Siempre responde \u00fanicamente en formato JSON v\u00e1lido\n\n- No agregues texto adicional fuera del JSON\n\n- Calcula el tiempo restante hasta la cita para validar pol\u00edticas de cancelaci\u00f3n\n\n- Verifica el estado actual de la cita (no cancelar citas ya canceladas)\n\n- Considera solo citas futuras como cancelables\n\n- Si hay dudas sobre coincidencias parciales de nombres, incl\u00fayelas como posibles resultados\n\n## Datos requeridos para procesar:\n\n- Correo del paciente: [CORREO_A_BUSCAR]\n\n- Nombre del paciente: [NOMBRE_A_BUSCAR]  \n\n- Lista de citas agendadas: [JSON_CON_TODAS_LAS_CITAS]",
              "role": "system"
            },
            {
              "content": "=CITA A BUSCAR: \nEmail:{{ $('When Executed by Another Workflow').item.json.email }}\nNombre: {{ $('When Executed by Another Workflow').item.json.name }}\n\n{{ $json.formattedString }}"
            }
          ]
        },
        "jsonOutput": true,
        "options": {}
      },
      "type": "@n8n/n8n-nodes-langchain.openAi",
      "typeVersion": 1.8,
      "position": [
        -304,
        880
      ],
      "id": "68045286-5d3a-4441-97d3-0dbac5338892",
      "name": "OpenAI1",
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "rules": {
          "values": [
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict",
                  "version": 2
                },
                "conditions": [
                  {
                    "leftValue": "={{ $json.message.content.status }}",
                    "rightValue": "found_cancellable",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    },
                    "id": "e0d43d36-b746-4abf-89f0-4ba1c97b484d"
                  }
                ],
                "combinator": "and"
              },
              "renameOutput": true,
              "outputKey": "SI ENCONTRO"
            },
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict",
                  "version": 2
                },
                "conditions": [
                  {
                    "id": "f376aae6-c7af-48a1-afeb-48b90c7d76bb",
                    "leftValue": "={{ $json.message.content.status }}",
                    "rightValue": "not_found",
                    "operator": {
                      "type": "string",
                      "operation": "equals",
                      "name": "filter.operator.equals"
                    }
                  }
                ],
                "combinator": "and"
              },
              "renameOutput": true,
              "outputKey": "NO ENCONTRO"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.switch",
      "typeVersion": 3.2,
      "position": [
        64,
        880
      ],
      "id": "0c82dd25-2e43-49d2-b5fc-d706897a1956",
      "name": "Switch1"
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "29114525-53f2-4c93-b81f-8662750fd70c",
              "name": "status",
              "value": "No se encontro ninguna cita para cancelar",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        368,
        1088
      ],
      "id": "ecaf9f7d-0a64-4bba-a0a7-68b909708e28",
      "name": "Edit Fields5"
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "666ac12b-71e0-496c-9b70-ff342ddff3b6",
              "name": "status",
              "value": "=El evento se a cancelado exitosamente",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        848,
        528
      ],
      "id": "3b3b888c-ce5c-49ef-8e22-ef1427df5ddc",
      "name": "Edit Fields6"
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "24d6054a-3382-4310-870a-b9280986f21d",
              "name": "status",
              "value": "El evento no se pudo cancelar volver a intentar",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        864,
        832
      ],
      "id": "b8047d04-a83f-4658-bb1c-90f485915f88",
      "name": "Edit Fields7"
    },
    {
      "parameters": {
        "method": "POST",
        "url": "=https://api.cal.com/v2/bookings/{{ $('OpenAI1').item.json.message.content.appointment.bookingUid }}/cancel",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "cal-api-version",
              "value": "2024-08-13"
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        },
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={\n  \"cancellationReason\": \"{{ $('When Executed by Another Workflow').item.json.reason }}\"\n}",
        "options": {}
      },
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        368,
        704
      ],
      "id": "d9f3d2a1-f3b8-4c28-aa14-ec69c018cd66",
      "name": "CANCELAR",
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      },
      "onError": "continueErrorOutput"
    },
    {
      "parameters": {
        "content": "## INPUT",
        "height": 200,
        "width": 260
      },
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        -1360,
        480
      ],
      "id": "fd8ddac8-b717-44b5-97d8-e90150ecbc66",
      "name": "Sticky Note"
    },
    {
      "parameters": {
        "content": "## VER CITAS",
        "height": 200,
        "width": 260,
        "color": 5
      },
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        -928,
        368
      ],
      "id": "e7a29c2f-38ff-4d64-9a18-fad81cb86751",
      "name": "Sticky Note1"
    },
    {
      "parameters": {
        "content": "## COMPARACI\u00d3N",
        "height": 200,
        "width": 540,
        "color": 3
      },
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        -640,
        368
      ],
      "id": "15969ea5-5d4f-4ab2-919e-d8ee324301c0",
      "name": "Sticky Note2"
    },
    {
      "parameters": {
        "content": "## REAGENDAMIENTO",
        "height": 640,
        "width": 840,
        "color": 6
      },
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        0,
        0
      ],
      "id": "5803a018-b443-4cac-bd91-14708851d482",
      "name": "Sticky Note3"
    }
  ],
  "connections": {
    "When Executed by Another Workflow": {
      "main": [
        [
          {
            "node": "If",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "If": {
      "main": [
        [
          {
            "node": "HTTP Request",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "HTTP Request2",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "HTTP Request": {
      "main": [
        [
          {
            "node": "Code",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Code": {
      "main": [
        [
          {
            "node": "OpenAI",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI": {
      "main": [
        [
          {
            "node": "Switch",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Switch": {
      "main": [
        [
          {
            "node": "HTTP Request1",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Edit Fields1",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Edit Fields",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "HTTP Request1": {
      "main": [
        [
          {
            "node": "If1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "If1": {
      "main": [
        [
          {
            "node": "Edit Fields2",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Edit Fields3",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "HTTP Request2": {
      "main": [
        [
          {
            "node": "Code1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Code1": {
      "main": [
        [
          {
            "node": "OpenAI1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI1": {
      "main": [
        [
          {
            "node": "Switch1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Switch1": {
      "main": [
        [
          {
            "node": "CANCELAR",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Edit Fields5",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "CANCELAR": {
      "main": [
        [
          {
            "node": "Edit Fields6",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Edit Fields7",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "active": true,
  "settings": {
    "executionOrder": "v1",
    "binaryMode": "separate"
  },
  "versionId": "8d8e82c3-ec88-4dec-a6dc-cf121d6c10cb",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "id": "puRlH1PWNqGxmqeE",
  "tags": []
}

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

REAGENDADOR. Uses executeWorkflowTrigger, httpRequest, openAi. Event-driven trigger; 24 nodes.

Source: https://gist.github.com/ivanfuentes1024-dot/7e58d6dee8b9257a33a956396f6b2e45 — 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

How it Works

Memory Buffer Window, Agent, Output Parser Structured +9
AI & RAG

The best content automation template in the market is now even better—with “deep research” on time-sensitive topics\! Unlike most n8n content automation templates that are mainly for “demo purposes,”

OpenAI, HTTP Request, XML +11
AI & RAG

Template Nodes Example. Uses CUSTOM, formTrigger, executeWorkflowTrigger, chatTrigger. Event-driven trigger; 70 nodes.

Custom, Form Trigger, Execute Workflow Trigger +23
AI & RAG

Template Carnaval - time instagram. Uses toolWorkflow, lmChatOpenAi, memoryBufferWindow, agent. Event-driven trigger; 56 nodes.

Tool Workflow, OpenAI Chat, Memory Buffer Window +10
AI & RAG

This workflow scans an RSS blog feed on a schedule, logs newly found posts to Google Sheets, uses OpenAI to generate role-based LinkedIn drafts, and emails approval links via Gmail; approved drafts ar

Execute Workflow Trigger, Gmail, RSS Feed Read +4