{
  "name": "Agente de WhatsApp para Leads (soyjpprieto)",
  "nodes": [
    {
      "name": "📋 FLUJO UNIFICADO",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1888,
        16
      ],
      "parameters": {
        "width": 520,
        "height": 200,
        "content": "### 🎯 Recordatorios + Auto-Respuesta IA\n\n**Calendly:** Espera 5 min → si lead escribió primero salta Template 1 → reminders 24h/1h/15min\n\n**WhatsApp:** Confirmaciones → respuesta personalizada | Preguntas → Agente IA (Claude)"
      },
      "typeVersion": 1
    },
    {
      "name": "⏳ 5 MIN INTELIGENTE",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -736,
        144
      ],
      "parameters": {
        "width": 380,
        "height": 120,
        "content": "### ⏳ Lógica 5 minutos\nSi el lead escribió por WA → `Contactó_WA=SÍ` en Sheets\nEste check lo detecta y salta el Template 1"
      },
      "typeVersion": 1
    },
    {
      "name": "✅ CONFIRMACIÓN WA",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1056,
        640
      ],
      "parameters": {
        "width": 380,
        "height": 100,
        "content": "### ✅ Lead confirmó\nRespuesta personalizada + marca Confirmado=SÍ y Contactó_WA=SÍ"
      },
      "typeVersion": 1
    },
    {
      "name": "🤖 IA RESPONDE",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1264,
        1168
      ],
      "parameters": {
        "width": 380,
        "height": 110,
        "content": "### 🤖 Agente Claude\nBusca contexto de cita → responde libre (ventana 24h abierta)"
      },
      "typeVersion": 1
    },
    {
      "name": "📅 Cal.com Trigger",
      "type": "n8n-nodes-base.webhook",
      "position": [
        -2336,
        432
      ],
      "webhookId": "21598350-a1c1-4e94-b7b6-4dc5131735df",
      "parameters": {
        "path": "calcom-booking",
        "options": {},
        "httpMethod": "POST"
      },
      "typeVersion": 2
    },
    {
      "name": "📦 Extraer Datos Cal.com",
      "type": "n8n-nodes-base.code",
      "position": [
        -1504,
        656
      ],
      "parameters": {
        "mode": "runOnceForEachItem",
        "jsCode": "\n// Cal.com sends booking data in this structure\nconst payload = $json.body?.payload || $json.payload || $json.body || $json;\n\n// Basic info\nconst name      = payload.responses?.name?.value || payload.attendees?.[0]?.name || \"Cliente\";\nconst firstName = name.split(\" \")[0] || \"amigo\";\nconst email     = payload.responses?.email?.value || payload.attendees?.[0]?.email || \"\";\n\n// Phone from custom field\nlet phone = payload.responses?.phone?.value || \"\";\nphone = phone.replace(/[\\s\\-\\(\\)\\+]/g, \"\");\nif (phone.startsWith(\"00\")) phone = phone.substring(2);\nif (phone.length === 10 && phone.startsWith(\"3\")) phone = \"57\" + phone;\nelse if (phone.length === 10 && /^[2-9]/.test(phone)) phone = \"1\" + phone;\n\n// Event timing\nconst startTime = payload.startTime || payload.responses?.startTime || \"\";\nif (!startTime) throw new Error(\"No se encontró startTime en el payload de Cal.com\");\n\nconst eventDate = new Date(startTime);\nconst timezone  = payload.attendees?.[0]?.timeZone || \"America/Bogota\";\n\nconst date_formatted = eventDate.toLocaleDateString(\"es-CO\", {\n  weekday: \"long\", year: \"numeric\", month: \"long\", day: \"numeric\", timeZone: timezone\n});\nconst time_formatted = eventDate.toLocaleTimeString(\"es-CO\", {\n  hour: \"2-digit\", minute: \"2-digit\", timeZone: timezone\n});\n\nconst time_24h_before   = new Date(eventDate.getTime() - 24*60*60*1000).toISOString();\nconst time_2h_before    = new Date(eventDate.getTime() -  2*60*60*1000).toISOString();\nconst time_1h_before    = new Date(eventDate.getTime() -    60*60*1000).toISOString();\nconst time_15min_before = new Date(eventDate.getTime() -  15*60*1000).toISOString();\n\n// Meeting link\nconst meetingLink    = payload.videoCallUrl || payload.metadata?.videoCallUrl || \"\";\nconst rescheduleLink = payload.rescheduleLink || payload.rescheduleUid \n  ? \"https://cal.com/TU_USUARIO/TU_EVENTO?rescheduleUid=\" + (payload.rescheduleUid || \"\") \n  : \"https://cal.com/TU_USUARIO/TU_EVENTO\";\nconst cancelLink     = \"\";\n\nconst meetCodeMatch = meetingLink.match(/meet\\.google\\.com\\/([a-z]{3}-[a-z]{4}-[a-z]{3})/i);\nconst meet_code     = meetCodeMatch ? meetCodeMatch[1] : meetingLink.split(\"/\").pop() || \"\";\n\n// Cal.com booking UID for reschedule/cancel operations\nconst bookingUid = payload.uid || payload.booking?.uid || \"\";\n\nreturn {\n  name, firstName, email, phone,\n  event_name: payload.title || \"Discovery Call\",\n  date_formatted, time_formatted,\n  start_time_iso: startTime,\n  time_24h_before, time_2h_before, time_1h_before, time_15min_before,\n  meeting_link: meetingLink, meet_code,\n  reschedule_link: rescheduleLink, cancel_link: cancelLink, timezone,\n  booking_uid: bookingUid\n};\n"
      },
      "typeVersion": 2
    },
    {
      "name": "📊 Registrar Agendamiento",
      "type": "n8n-nodes-base.googleSheets",
      "maxTries": 3,
      "position": [
        -1008,
        432
      ],
      "parameters": {
        "columns": {
          "value": {
            "Cliente": "={{ $json.name }}",
            "Mensaje": "=Agendamiento: {{ $json.event_name }}",
            "Teléfono": "={{ $json.phone }}",
            "Confirmado": "=NO",
            "Fecha/hora": "={{ $json.date_formatted }} – {{ $json.time_formatted }}",
            "Contactó_WA": "=NO"
          },
          "schema": [
            {
              "id": "Cliente",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Cliente",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Teléfono",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Teléfono",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Fecha/hora",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Fecha/hora",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Mensaje",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Mensaje",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Confirmado",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Confirmado",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Contactó_WA",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Contactó_WA",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Recordatorios_Enviados",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Recordatorios_Enviados",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": true
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultName": "Hoja 1"
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "TU_ID_DE_GOOGLE_SHEET"
        }
      },
      "retryOnFail": true,
      "typeVersion": 4.7,
      "waitBetweenTries": 3000,
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "Google Sheets account"
        }
      }
    },
    {
      "name": "⏳ Esperar 1 min",
      "type": "n8n-nodes-base.wait",
      "position": [
        -704,
        400
      ],
      "webhookId": "d56d87aa-bfdc-4264-ae2a-f88c5d9b4384",
      "parameters": {
        "unit": "minutes",
        "amount": 1
      },
      "typeVersion": 1.1
    },
    {
      "name": "🔍 Verificar si Contactó",
      "type": "n8n-nodes-base.googleSheets",
      "maxTries": 3,
      "position": [
        -400,
        400
      ],
      "parameters": {
        "options": {
          "returnFirstMatch": false
        },
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultName": "Hoja 1"
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "TU_ID_DE_GOOGLE_SHEET"
        }
      },
      "retryOnFail": true,
      "typeVersion": 4.7,
      "waitBetweenTries": 3000,
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "Google Sheets account"
        }
      }
    },
    {
      "name": "📝 Analizar Contacto",
      "type": "n8n-nodes-base.code",
      "position": [
        -96,
        400
      ],
      "parameters": {
        "jsCode": "const d = $(\"📦 Extraer Datos Cal.com\").item.json;\nconst phone = d.phone;\nconst fechaHora = `${d.date_formatted} – ${d.time_formatted}`;\nconst rows  = $input.all();\nconst matches = rows.filter(row => {\n  const t = (row.json[\"Teléfono\"] || \"\").replace(/[\\s\\-\\(\\)\\+]/g, \"\");\n  const phoneMatches = t === phone || t.includes(phone) || phone.includes(t);\n  const fechaMatches = (row.json[\"Fecha/hora\"] || \"\") === fechaHora;\n  return phoneMatches && fechaMatches;\n});\nmatches.sort((a, b) => (b.json.row_number || 0) - (a.json.row_number || 0));\nconst match = matches[0];\nconst val = match ? (match.json[\"Contactó_WA\"] || \"NO\").toUpperCase() : \"NO\";\nconst ya_contacto = val === \"SÍ\" || val === \"SI\" || val === \"YES\";\nreturn { ...d, ya_contacto };"
      },
      "typeVersion": 2
    },
    {
      "name": "¿Ya Contactó?",
      "type": "n8n-nodes-base.if",
      "position": [
        208,
        400
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": false,
            "typeValidation": "loose"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "c01",
              "operator": {
                "type": "boolean",
                "operation": "equals"
              },
              "leftValue": "={{ $json.ya_contacto }}",
              "rightValue": true
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "name": "📱 WA - Confirmación",
      "type": "n8n-nodes-base.whatsApp",
      "maxTries": 3,
      "position": [
        512,
        560
      ],
      "webhookId": "50e2dc69-feb4-4e4b-808f-253ed6bff25e",
      "parameters": {
        "template": "llamada_confirmacion|es_CO",
        "components": {
          "component": [
            {
              "bodyParameters": {
                "parameter": [
                  {
                    "text": "={{$json.firstName}}"
                  },
                  {
                    "text": "={{$json.date_formatted}}"
                  },
                  {
                    "text": "={{$json.time_formatted}}"
                  },
                  {
                    "text": "={{$json.meeting_link}}"
                  }
                ]
              }
            }
          ]
        },
        "phoneNumberId": "TU_PHONE_NUMBER_ID_DE_WHATSAPP",
        "recipientPhoneNumber": "={{$json.phone}}"
      },
      "retryOnFail": true,
      "typeVersion": 1.1,
      "waitBetweenTries": 3000,
      "onError": "continueRegularOutput",
      "credentials": {
        "whatsAppApi": {
          "name": "Soyjpprieto - WhatsApp account"
        }
      }
    },
    {
      "name": "🔁 Recuperar Datos",
      "type": "n8n-nodes-base.code",
      "position": [
        1104,
        400
      ],
      "parameters": {
        "jsCode": "return $('📦 Extraer Datos Cal.com').item.json;"
      },
      "typeVersion": 2
    },
    {
      "name": "⏰ Esperar hasta 24h Antes",
      "type": "n8n-nodes-base.wait",
      "position": [
        1408,
        400
      ],
      "webhookId": "85b7d143-e1d7-4cbc-9849-9d6118a08b2e",
      "parameters": {
        "resume": "specificTime",
        "dateTime": "={{ $json.time_24h_before }}"
      },
      "typeVersion": 1.1
    },
    {
      "name": "🔍 Buscar en Sheets",
      "type": "n8n-nodes-base.googleSheets",
      "maxTries": 3,
      "position": [
        1712,
        400
      ],
      "parameters": {
        "options": {
          "returnFirstMatch": false
        },
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultName": "Hoja 1"
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "TU_ID_DE_GOOGLE_SHEET"
        }
      },
      "retryOnFail": true,
      "typeVersion": 4.7,
      "waitBetweenTries": 3000,
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "Google Sheets account"
        }
      }
    },
    {
      "name": "📝 Extraer Datos 24h",
      "type": "n8n-nodes-base.code",
      "position": [
        2000,
        400
      ],
      "parameters": {
        "jsCode": "const rows  = $input.all();\nconst d     = $('📦 Extraer Datos Cal.com').item.json;\nconst phone = d.phone;\nconst fechaHora = `${d.date_formatted} – ${d.time_formatted}`;\nconst sortedRows = [...rows].sort((a, b) => (b.json.row_number || 0) - (a.json.row_number || 0));\nconst match = sortedRows.find(row => {\n  const t = (row.json['Teléfono'] || '').replace(/[\\s\\-\\(\\)\\+]/g, '');\n  const phoneMatches = t === phone || t.includes(phone) || phone.includes(t);\n  const fechaMatches = (row.json['Fecha/hora'] || '') === fechaHora;\n  return phoneMatches && fechaMatches;\n});\nconst confirmado  = match ? (match.json['Confirmado'] || 'NO').toUpperCase() : 'NO';\nconst ya_confirmo = confirmado === 'SÍ' || confirmado === 'SI' || confirmado === 'YES';\nreturn {\n  ya_confirmo, phone,\n  firstName: d.firstName, email: d.email,\n  date_formatted: d.date_formatted, time_formatted: d.time_formatted,\n  meeting_link: d.meeting_link, meet_code: d.meet_code,\n  reschedule_link: d.reschedule_link,\n  time_1h_before: d.time_1h_before, time_15min_before: d.time_15min_before\n};"
      },
      "typeVersion": 2
    },
    {
      "name": "¿Ya Confirmó?",
      "type": "n8n-nodes-base.if",
      "position": [
        2304,
        400
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": false,
            "typeValidation": "loose"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "c01",
              "operator": {
                "type": "boolean",
                "operation": "equals"
              },
              "leftValue": "={{ $json.ya_confirmo }}",
              "rightValue": true
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "name": "📱 WA - 24h (Ya Confirmó)",
      "type": "n8n-nodes-base.whatsApp",
      "maxTries": 3,
      "position": [
        2608,
        272
      ],
      "webhookId": "3dfb5f99-27d1-408d-9ea2-0242f67fdc07",
      "parameters": {
        "template": "llamada_recordatorio_24h|es_CO",
        "components": {
          "component": [
            {
              "bodyParameters": {
                "parameter": [
                  {
                    "text": "={{$json.firstName}}"
                  },
                  {
                    "text": "={{$json.date_formatted}}"
                  },
                  {
                    "text": "={{$json.time_formatted}}"
                  },
                  {
                    "text": "={{$json.meeting_link}}"
                  }
                ]
              }
            }
          ]
        },
        "phoneNumberId": "TU_PHONE_NUMBER_ID_DE_WHATSAPP",
        "recipientPhoneNumber": "={{$json.phone}}"
      },
      "retryOnFail": true,
      "typeVersion": 1.1,
      "waitBetweenTries": 3000,
      "onError": "continueRegularOutput",
      "credentials": {
        "whatsAppApi": {
          "name": "Soyjpprieto - WhatsApp account"
        }
      }
    },
    {
      "name": "📱 WA - 24h (Sin Confirmar)",
      "type": "n8n-nodes-base.whatsApp",
      "maxTries": 3,
      "position": [
        2608,
        544
      ],
      "webhookId": "1e946137-3701-4221-80c7-3c63b15270f2",
      "parameters": {
        "template": "llamada_recordatorio_24h|es_CO",
        "components": {
          "component": [
            {
              "bodyParameters": {
                "parameter": [
                  {
                    "text": "={{$json.firstName}}"
                  },
                  {
                    "text": "={{$json.date_formatted}}"
                  },
                  {
                    "text": "={{$json.time_formatted}}"
                  },
                  {
                    "text": "={{$json.meeting_link}}"
                  }
                ]
              }
            }
          ]
        },
        "phoneNumberId": "TU_PHONE_NUMBER_ID_DE_WHATSAPP",
        "recipientPhoneNumber": "={{$json.phone}}"
      },
      "retryOnFail": true,
      "typeVersion": 1.1,
      "waitBetweenTries": 3000,
      "onError": "continueRegularOutput",
      "credentials": {
        "whatsAppApi": {
          "name": "Soyjpprieto - WhatsApp account"
        }
      }
    },
    {
      "name": "⏰ Esperar hasta 1h Antes",
      "type": "n8n-nodes-base.wait",
      "position": [
        3552,
        432
      ],
      "webhookId": "545e678a-ffd2-4c8f-a706-6ee10ef02b95",
      "parameters": {
        "resume": "specificTime",
        "dateTime": "={{ $json.time_1h_before }}"
      },
      "typeVersion": 1.1
    },
    {
      "name": "📱 WA - Recordatorio 1h",
      "type": "n8n-nodes-base.whatsApp",
      "maxTries": 3,
      "position": [
        4352,
        464
      ],
      "webhookId": "4cc84611-5670-4b55-a2e4-1bdf274665e8",
      "parameters": {
        "template": "llamada_recordatorio_1h|es_CO",
        "components": {
          "component": [
            {
              "bodyParameters": {
                "parameter": [
                  {
                    "text": "={{$json.firstName}}"
                  },
                  {
                    "text": "={{$json.meeting_link}}"
                  }
                ]
              }
            }
          ]
        },
        "phoneNumberId": "TU_PHONE_NUMBER_ID_DE_WHATSAPP",
        "recipientPhoneNumber": "={{$json.phone}}"
      },
      "retryOnFail": true,
      "typeVersion": 1.1,
      "waitBetweenTries": 3000,
      "onError": "continueRegularOutput",
      "credentials": {
        "whatsAppApi": {
          "name": "Soyjpprieto - WhatsApp account"
        }
      }
    },
    {
      "name": "⏰ Esperar hasta 15min Antes",
      "type": "n8n-nodes-base.wait",
      "position": [
        4800,
        464
      ],
      "webhookId": "cc27f892-4d3c-4a21-a158-ce7449321110",
      "parameters": {
        "resume": "specificTime",
        "dateTime": "={{ $json.time_15min_before }}"
      },
      "typeVersion": 1.1
    },
    {
      "name": "📱 WA - Recordatorio 15min",
      "type": "n8n-nodes-base.whatsApp",
      "maxTries": 3,
      "position": [
        5040,
        432
      ],
      "webhookId": "4a2a5a0f-a973-4a64-84ee-0999f49dd383",
      "parameters": {
        "template": "llamada_recordatorio_15min|es_CO",
        "components": {
          "component": [
            {
              "bodyParameters": {
                "parameter": [
                  {
                    "text": "={{$json.firstName}}"
                  }
                ]
              }
            }
          ]
        },
        "phoneNumberId": "TU_PHONE_NUMBER_ID_DE_WHATSAPP",
        "recipientPhoneNumber": "={{$json.phone}}"
      },
      "retryOnFail": true,
      "typeVersion": 1.1,
      "waitBetweenTries": 3000,
      "onError": "continueRegularOutput",
      "credentials": {
        "whatsAppApi": {
          "name": "Soyjpprieto - WhatsApp account"
        }
      }
    },
    {
      "name": "📊 Log Final",
      "type": "n8n-nodes-base.googleSheets",
      "maxTries": 3,
      "position": [
        5312,
        432
      ],
      "parameters": {
        "columns": {
          "value": {
            "Cliente": "={{ $json.firstName }}",
            "Mensaje": "=Recordatorios completados",
            "Teléfono": "={{ $json.phone }}",
            "Confirmado": "=COMPLETADO",
            "Fecha/hora": "={{ $json.date_formatted }} – {{ $json.time_formatted }}",
            "Contactó_WA": "=COMPLETADO"
          },
          "schema": [
            {
              "id": "Cliente",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Cliente",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Teléfono",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Teléfono",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Fecha/hora",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Fecha/hora",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Mensaje",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Mensaje",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Confirmado",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Confirmado",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Contactó_WA",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Contactó_WA",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": true
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultName": "Hoja 1"
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "TU_ID_DE_GOOGLE_SHEET"
        }
      },
      "retryOnFail": true,
      "typeVersion": 4.7,
      "waitBetweenTries": 3000,
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "Google Sheets account"
        }
      }
    },
    {
      "name": "📱 WhatsApp Trigger",
      "type": "n8n-nodes-base.whatsAppTrigger",
      "position": [
        -2832,
        1744
      ],
      "webhookId": "c5de3d04-fbe2-45e0-b420-a539532c2b7e",
      "parameters": {
        "options": {},
        "updates": [
          "messages"
        ]
      },
      "typeVersion": 1,
      "credentials": {
        "whatsAppTriggerApi": {
          "name": "WhatsApp OAuth account"
        }
      }
    },
    {
      "name": "🔄 Extraer Mensaje WA",
      "type": "n8n-nodes-base.code",
      "position": [
        -2640,
        1760
      ],
      "parameters": {
        "jsCode": "const item = $input.first();\nconst j = item.json;\n\n// La información llega en listas (arrays) llamadas \"messages\" y \"contacts\"\nconst messages = j.messages || [];\nconst contacts = j.contacts || [];\n\n// Ignorar eventos que no son mensajes reales (ej: status callbacks de \"sent/delivered/read\")\nif (messages.length === 0) {\n  return [];\n}\n\n// Tomamos el primer elemento de cada lista\nconst msg = messages[0] || {};\nconst contact = contacts[0] || {};\n\n// 1. Extraer Teléfono\nconst phone = msg.from || \"\";\n\n// 2. Extraer Nombre del remitente\nconst senderName = (contact.profile && contact.profile.name) ? contact.profile.name : \"Cliente\";\n\n// 3. Extraer Texto del mensaje\nlet text = \"\";\nif (msg.type === \"text\" && msg.text && msg.text.body) {\n    text = msg.text.body;\n} else if (msg.type === \"button\" && msg.button && msg.button.text) {\n    // Quick Reply button tap (ej: botón \"Confirmar\" del template de confirmación)\n    text = msg.button.text;\n} else if (msg.text) {\n    text = msg.text;\n}\n\n// 4. Evaluar si es confirmación usando palabras clave inteligentes\nconst lowerText = text.toLowerCase();\n\n// Expresiones que indican que no puede asistir o quiere reagendar\nconst isNegative = lowerText.includes(\"no puedo\") || \n                   lowerText.includes(\"no podre\") || \n                   lowerText.includes(\"no podré\") || \n                   lowerText.includes(\"cancelar\") || \n                   lowerText.includes(\"reagendar\") || \n                   lowerText.includes(\"cambiar\") || \n                   lowerText.includes(\"otro día\") || \n                   lowerText.includes(\"otro dia\") || \n                   lowerText.includes(\"ya no alcanzo\") ||\n                   lowerText.includes(\"me surgio\") ||\n                   lowerText.includes(\"me surgió\") ||\n                   (lowerText.includes(\"no\") && (lowerText.includes(\"asistir\") || lowerText.includes(\"ir\")));\n\n// Expresiones comunes de confirmación\nconst hasPositiveKeywords = lowerText.includes(\"confirm\") || \n                            lowerText.includes(\"ok\") || \n                            lowerText.includes(\"listo\") || \n                            lowerText.includes(\"perfecto\") || \n                            lowerText.includes(\"dale\") || \n                            lowerText.includes(\"de acuerdo\") ||\n                            lowerText === \"si\" || \n                            lowerText === \"sí\" ||\n                            lowerText.startsWith(\"si \") ||\n                            lowerText.startsWith(\"sí \") ||\n                            lowerText.includes(\"nos vemos\");\n\n// Es confirmación SOLAMENTE si tiene palabras positivas y NO tiene palabras de cancelación/reagendamiento\nconst isConfirmation = !isNegative && hasPositiveKeywords;\n\nreturn [{ json: { phone, text, senderName, lowerText, isConfirmation } }];"
      },
      "typeVersion": 2
    },
    {
      "name": "¿Es Confirmación?",
      "type": "n8n-nodes-base.if",
      "position": [
        -1664,
        1632
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": false,
            "typeValidation": "loose"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "c01",
              "operator": {
                "type": "string",
                "operation": "contains"
              },
              "leftValue": "={{ $json.text.toLowerCase() }}",
              "rightValue": "confirm"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "name": "🔍 Buscar Cita en Sheets",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        -1424,
        1504
      ],
      "parameters": {
        "options": {
          "returnFirstMatch": false
        },
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultName": "Hoja 1"
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "TU_ID_DE_GOOGLE_SHEET"
        }
      },
      "typeVersion": 4.7,
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "Google Sheets account"
        }
      }
    },
    {
      "name": "📝 Preparar Respuesta",
      "type": "n8n-nodes-base.code",
      "position": [
        -768,
        1296
      ],
      "parameters": {
        "jsCode": "\nconst phone      = $(\"🔄 Extraer Mensaje WA\").item.json.phone;\nconst senderName = $(\"🔄 Extraer Mensaje WA\").item.json.senderName;\nconst rows = $input.all();\nconst sortedRows = [...rows].sort((a, b) => (b.json.row_number || 0) - (a.json.row_number || 0));\nconst match = sortedRows.find(row => {\n  const t = (row.json[\"Teléfono\"] || \"\").replace(/[\\s\\-\\(\\)\\+]/g, \"\");\n  return t === phone || t.includes(phone) || phone.includes(t);\n});\nif (!match) return {\n  found: false, phone, senderName,\n  response: `¡Hola ${senderName}! 🎉\\n\\nHemos recibido tu confirmación. ¡Perfecto!\\n\\nTe esperamos en tu llamada. 🙌`\n};\nreturn {\n  found: true, phone, senderName,\n  row_number: match.json.row_number,\n  response: `¡Hola ${senderName}! 🎉\\n\\n✅ *¡Confirmado!* Tu llamada está apuntada:\\n\\n📅 *${match.json[\"Fecha/hora\"] || \"\"}*\\n\\n¡Te esperamos con todo listo! 🙌\\n\\n¡Nos vemos pronto! 🚀`\n};\n"
      },
      "typeVersion": 2
    },
    {
      "name": "✅ Actualizar Confirmado + Contactó",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        -400,
        1216
      ],
      "parameters": {
        "columns": {
          "value": {
            "Confirmado": "=SÍ",
            "row_number": "={{ $json.row_number }}",
            "Contactó_WA": "=SÍ"
          },
          "schema": [
            {
              "id": "Cliente",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Cliente",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Teléfono",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Teléfono",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Fecha/hora",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Fecha/hora",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Mensaje",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Mensaje",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Confirmado",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Confirmado",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Contactó_WA",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Contactó_WA",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "row_number"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": true
        },
        "options": {},
        "operation": "update",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultName": "Hoja 1"
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "TU_ID_DE_GOOGLE_SHEET"
        }
      },
      "typeVersion": 4.7,
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "Google Sheets account"
        }
      }
    },
    {
      "name": "📱 Responder WA Confirmación",
      "type": "n8n-nodes-base.whatsApp",
      "position": [
        176,
        1248
      ],
      "webhookId": "8e0011ce-2bf3-44c6-abdf-2b918b31fa66",
      "parameters": {
        "textBody": "={{ $('📝 Preparar Respuesta').item.json.response }}",
        "operation": "send",
        "phoneNumberId": "TU_PHONE_NUMBER_ID_DE_WHATSAPP",
        "additionalFields": {},
        "recipientPhoneNumber": "={{ $('📝 Preparar Respuesta').item.json.phone }}"
      },
      "typeVersion": 1.1,
      "credentials": {
        "whatsAppApi": {
          "name": "Soyjpprieto - WhatsApp account"
        }
      }
    },
    {
      "name": "🔍 Buscar Contexto IA",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        -1456,
        1824
      ],
      "parameters": {
        "options": {
          "returnFirstMatch": false
        },
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultName": "Hoja 1"
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "TU_ID_DE_GOOGLE_SHEET"
        }
      },
      "typeVersion": 4.7,
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "Google Sheets account"
        }
      }
    },
    {
      "name": "✅ Marcar Contactó WA",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        -928,
        1856
      ],
      "parameters": {
        "columns": {
          "value": {
            "row_number": "={{ $json.row_number }}",
            "Contactó_WA": "=SÍ"
          },
          "schema": [
            {
              "id": "Cliente",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Cliente",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Teléfono",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Teléfono",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Fecha/hora",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Fecha/hora",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Mensaje",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Mensaje",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Confirmado",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Confirmado",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Contactó_WA",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Contactó_WA",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "row_number"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": true
        },
        "options": {},
        "operation": "update",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultName": "Hoja 1"
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "TU_ID_DE_GOOGLE_SHEET"
        }
      },
      "executeOnce": true,
      "typeVersion": 4.7,
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "Google Sheets account"
        }
      }
    },
    {
      "name": "📝 Preparar Prompt IA",
      "type": "n8n-nodes-base.code",
      "position": [
        -1168,
        1808
      ],
      "parameters": {
        "jsCode": "const phone      = $(\"🔄 Extraer Mensaje WA\").item.json.phone;\nconst text       = $(\"🔄 Extraer Mensaje WA\").item.json.text;\nconst senderName = $(\"🔄 Extraer Mensaje WA\").item.json.senderName;\nconst rows = $input.all();\nconst sortedRows = [...rows].sort((a, b) => (b.json.row_number || 0) - (a.json.row_number || 0));\nconst match = sortedRows.find(row => {\n  const t = (row.json[\"Teléfono\"] || \"\").replace(/[\\s\\-\\(\\)\\+]/g, \"\");\n  return t === phone || t.includes(phone) || phone.includes(t);\n});\nconst rowNumber   = match ? match.json.row_number  : null;\nconst fechaCita   = match ? (match.json[\"Fecha/hora\"] || \"no registrada\") : \"no registrada\";\nconst bookingUid  = match ? (match.json[\"booking_uid\"] || \"\")            : \"\";\nreturn { phone, senderName, userMessage: text, fechaCita, row_number: rowNumber, booking_uid: bookingUid };\n"
      },
      "typeVersion": 2
    },
    {
      "name": "📱 Responder WA (IA)",
      "type": "n8n-nodes-base.whatsApp",
      "position": [
        176,
        1872
      ],
      "webhookId": "315829f5-18e6-46a2-9da4-fe3c6d54c077",
      "parameters": {
        "textBody": "={{ $json.output }}",
        "operation": "send",
        "phoneNumberId": "TU_PHONE_NUMBER_ID_DE_WHATSAPP",
        "additionalFields": {},
        "recipientPhoneNumber": "={{ $('📝 Preparar Prompt IA').item.json.phone }}"
      },
      "typeVersion": 1.1,
      "credentials": {
        "whatsAppApi": {
          "name": "Soyjpprieto - WhatsApp account"
        }
      }
    },
    {
      "name": "📅 Obtener Slots Disponibles",
      "type": "@n8n/n8n-nodes-langchain.toolHttpRequest",
      "position": [
        -304,
        1984
      ],
      "parameters": {
        "url": "=https://api.cal.com/v2/slots?start={{ new Date().toISOString() }}&end={{ new Date(Date.now()+7*24*60*60*1000).toISOString() }}&eventTypeId=TU_EVENT_TYPE_ID&duration=30",
        "sendHeaders": true,
        "toolDescription": "Consulta los próximos horarios disponibles en el calendario de TU_NOMBRE para los siguientes 7 días. Úsala SIEMPRE antes de presentar opciones de reagendamiento. Devuelve slots disponibles; toma los primeros 3-5 y preséntaselos al cliente en formato legible (ej: Lunes 5 de mayo a las 10:00 AM).",
        "parametersHeaders": {
          "values": [
            {
              "name": "cal-api-version",
              "value": "2024-09-04",
              "valueProvider": "fieldValue"
            },
            {
              "name": "Authorization",
              "value": "=Bearer {{ $env.CAL_API_KEY }}",
              "valueProvider": "fieldValue"
            }
          ]
        }
      },
      "typeVersion": 1.1
    },
    {
      "name": "✅ Crear Reserva Cal.com",
      "type": "@n8n/n8n-nodes-langchain.toolHttpRequest",
      "position": [
        -448,
        2016
      ],
      "parameters": {
        "url": "=https://api.cal.com/v2/bookings",
        "method": "POST",
        "jsonBody": "{\n  \"start\": \"{start_time}\",\n  \"eventTypeId\": TU_EVENT_TYPE_ID,\n  \"attendee\": {\n    \"name\": \"{attendee_name}\",\n    \"email\": \"{attendee_email}\",\n    \"timeZone\": \"{attendee_timezone}\",\n    \"phoneNumber\": \"+{attendee_phone}\"\n  },\n  \"bookingFieldsResponses\": {\n    \"phone\": \"+{attendee_phone}\",\n    \"empresa\": \"No especificado\",\n    \"empleados\": \"Solo yo\",\n    \"facturacion\": \"{attendee_facturacion}\",\n    \"instagram\": \"No especificado\",\n    \"inversion_ads\": \"{attendee_inversion_ads}\",\n    \"notes\": \"{attendee_notes}\"\n  }\n}",
        "sendBody": true,
        "sendHeaders": true,
        "specifyBody": "json",
        "toolDescription": "Crea una nueva reserva en el calendario de TU_NOMBRE. Úsala cuando el cliente haya confirmado el horario que desea. Requiere el parámetro start_time en formato ISO 8601 (ej: 2026-05-06T15:00:00Z). Confirma al cliente la nueva fecha y hora tras crearlo exitosamente.",
        "parametersHeaders": {
          "values": [
            {
              "name": "cal-api-version",
              "value": "2024-08-13",
              "valueProvider": "fieldValue"
            },
            {
              "name": "Content-Type",
              "value": "application/json",
              "valueProvider": "fieldValue"
            },
            {
              "name": "Authorization",
              "value": "=Bearer {{ $env.CAL_API_KEY }}",
              "valueProvider": "fieldValue"
            }
          ]
        },
        "placeholderDefinitions": {
          "values": [
            {
              "name": "start_time",
              "type": "string",
              "description": "Fecha y hora de inicio del nuevo slot elegido por el cliente, en formato ISO 8601 UTC (ej: 2026-05-06T15:00:00Z)"
            },
            {
              "name": "attendee_name",
              "type": "string",
              "description": "Nombre completo del cliente que agenda"
            },
            {
              "name": "attendee_email",
              "type": "string",
              "description": "Email del cliente que agenda"
            },
            {
              "name": "attendee_timezone",
              "type": "string",
              "description": "Zona horaria IANA del cliente (ej: America/Bogota)"
            },
            {
              "name": "attendee_phone",
              "type": "string",
              "description": "Número de teléfono del cliente TAL CUAL aparece en CONTEXTO DEL CLIENTE (Teléfono WhatsApp), SIN el signo + y sin espacios (ej: 1XXXXXXXXXX, no +1XXXXXXXXXX). El signo + se agrega automáticamente en la plantilla de la reserva, así que NO lo incluyas tú ni le pidas el teléfono al cliente."
            },
            {
              "name": "attendee_facturacion",
              "type": "string",
              "description": "Ingreso de facturación mensual de la empresa del cliente. DEBE ser EXACTAMENTE uno de estos valores textuales: '$5.000 USD - $10.000 USD', '$10.001 USD - $15.000 USD', '$15.001 USD - $20.000 USD', '$20.001 USD - $30.000 USD', 'Mas de $30.000 USD'."
            },
            {
              "name": "attendee_inversion_ads",
              "type": "string",
              "description": "Cuánto invierte el cliente en anuncios publicitarios al mes. DEBE ser EXACTAMENTE uno de estos valores textuales: 'Entre $1.000 USD a $3.000 USD', 'Entre $3.001 USD a $5.000 USD', 'Entre $5.001 USD a $10.000 USD', 'Entre $10.001 USD a $20.000 USD', 'Mas de $20.000 USD'."
            },
            {
              "name": "attendee_notes",
              "type": "string",
              "description": "Breve descripción de qué vende o a qué se dedica el negocio del cliente, en sus propias palabras."
            }
          ]
        }
      },
      "typeVersion": 1.1
    },
    {
      "name": "Es No-Show?",
      "type": "n8n-nodes-base.if",
      "position": [
        -1936,
        416
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": false,
            "typeValidation": "loose"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "c01",
              "operator": {
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $json.body.triggerEvent || '' }}",
              "rightValue": "BOOKING_NO_SHOW_UPDATED"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "name": "📦 Datos No-Show",
      "type": "n8n-nodes-base.code",
      "position": [
        -1568,
        96
      ],
      "parameters": {
        "jsCode": "\nconst payload = ($json.body || {}).payload || $json.payload || $json;\n\n// Extract info\nconst attendee = (payload.attendees || [])[0] || {};\nconst responses = payload.responses || {};\n\nconst name = attendee.name || responses.name?.value || \"Cliente\";\nconst email = attendee.email || responses.email?.value || \"\";\nconst firstName = name.split(\" \")[0] || \"amigo\";\n\nlet phone = responses.phone?.value || \"\";\nphone = phone.replace(/[\\s\\-\\(\\)\\+]/g, \"\");\nif (phone.startsWith(\"00\")) phone = phone.substring(2);\nif (phone.length === 10 && phone.startsWith(\"3\")) phone = \"57\" + phone;\nelse if (phone.length === 10 && /^[2-9]/.test(phone)) phone = \"1\" + phone;\n\nconst bookingUid = payload.uid || \"\";\nconst rescheduleLink = bookingUid \n  ? \"https://cal.com/booking/\" + bookingUid + \"?reschedule=true\"\n  : \"https://cal.com/TU_USUARIO/TU_EVENTO\";\n\nreturn {\n    name, firstName, phone, email, booking_uid: bookingUid, reschedule_link: rescheduleLink\n};\n"
      },
      "typeVersion": 2
    },
    {
      "name": "📱 WA - No Show",
      "type": "n8n-nodes-base.whatsApp",
      "maxTries": 3,
      "position": [
        -1312,
        32
      ],
      "webhookId": "65cdc8d4-ed65-4a1b-a798-cce4b4289bfb",
      "parameters": {
        "template": "no_show_recordatorio|es_CO",
        "components": {
          "component": [
            {
              "bodyParameters": {
                "parameter": [
                  {
                    "text": "={{$json.firstName}}"
                  }
                ]
              }
            }
          ]
        },
        "phoneNumberId": "TU_PHONE_NUMBER_ID_DE_WHATSAPP",
        "recipientPhoneNumber": "={{$json.phone}}"
      },
      "retryOnFail": true,
      "typeVersion": 1.1,
      "waitBetweenTries": 3000,
      "onError": "continueRegularOutput",
      "credentials": {
        "whatsAppApi": {
          "name": "Soyjpprieto - WhatsApp account"
        }
      }
    },
    {
      "name": "🔁 Recuperar Datos1",
      "type": "n8n-nodes-base.code",
      "position": [
        3296,
        432
      ],
      "parameters": {
        "jsCode": "return $('📦 Extraer Datos Cal.com').item.json;"
      },
      "typeVersion": 2
    },
    {
      "name": "🔁 Recuperar Datos2",
      "type": "n8n-nodes-base.code",
      "position": [
        4576,
        464
      ],
      "parameters": {
        "jsCode": "return $('📦 Extraer Datos Cal.com').item.json;"
      },
      "typeVersion": 2
    },
    {
      "name": "¿Es Reserva Creada?",
      "type": "n8n-nodes-base.if",
      "position": [
        -2160,
        416
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "a153df06-15f5-4f27-a530-bbe81641c7ab",
              "operator": {
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $json.body.triggerEvent }}",
              "rightValue": "BOOKING_CREATED"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "name": "📧 Email - Confirmación",
      "type": "n8n-nodes-base.gmail",
      "onError": "continueRegularOutput",
      "maxTries": 3,
      "position": [
        512,
        704
      ],
      "webhookId": "46fcba60-f3dd-4f95-9b87-504a5830b12e",
      "parameters": {
        "sendTo": "={{ $json.email }}",
        "message": "=Hola {{ $json.firstName }},<br><br>Tu sesión estratégica quedó agendada para el {{ $json.date_formatted }} a las {{ $json.time_formatted }}.<br><br>Link de la llamada: {{ $json.meeting_link }}<br><br>Nos vemos ahí.<br>TU_NOMBRE",
        "options": {},
        "subject": "Tu llamada con TU_NOMBRE está confirmada"
      },
      "retryOnFail": true,
      "typeVersion": 2.1,
      "waitBetweenTries": 3000,
      "credentials": {
        "gmailOAuth2": {
          "name": "Gmail account"
        }
      }
    },
    {
      "name": "📧 Email - Recordatorio 24h",
      "type": "n8n-nodes-base.gmail",
      "onError": "continueRegularOutput",
      "maxTries": 3,
      "position": [
        2000,
        560
      ],
      "webhookId": "330ee33a-242c-4cfc-91ce-a32d1a061e56",
      "parameters": {
        "sendTo": "={{ $json.email }}",
        "message": "=Hola {{ $json.firstName }},<br><br>Te recordamos tu sesión estratégica de mañana {{ $json.date_formatted }} a las {{ $json.time_formatted }}.<br><br>Link de la llamada: {{ $json.meeting_link }}<br><br>Si necesitas reagendar: {{ $json.reschedule_link }}",
        "options": {},
        "subject": "Recordatorio: tu llamada es mañana"
      },
      "retryOnFail": true,
      "typeVersion": 2.1,
      "waitBetweenTries": 3000,
      "credentials": {
        "gmailOAuth2": {
          "name": "Gmail account"
        }
      }
    },
    {
      "name": "📧 Email - No Show",
      "type": "n8n-nodes-base.gmail",
      "onError": "continueRegularOutput",
      "maxTries": 3,
      "position": [
        -1312,
        160
      ],
      "webhookId": "c1b49240-8d00-41ab-9826-ed98793fe236",
      "parameters": {
        "sendTo": "={{ $json.email }}",
        "message": "=Hola {{ $json.firstName }},<br><br>Notamos que no pudiste conectarte a tu llamada de hoy.<br><br>Si quieres reagendar, aquí tienes el link: {{ $json.reschedule_link }}<br><br>TU_NOMBRE",
        "options": {},
        "subject": "Se nos fue la señal"
      },
      "retryOnFail": true,
      "typeVersion": 2.1,
      "waitBetweenTries": 3000,
      "credentials": {
        "gmailOAuth2": {
          "name": "Gmail account"
        }
      }
    },
    {
      "name": "📓 Notion - Buscar Lead",
      "type": "n8n-nodes-base.httpRequest",
      "onError": "continueRegularOutput",
      "maxTries": 3,
      "position": [
        -1312,
        288
      ],
      "parameters": {
        "url": "=https://api.notion.com/v1/data_sources/TU_DATA_SOURCE_ID_DE_NOTION/query",
        "method": "POST",
        "options": {},
        "jsonBody": "={{ { \"filter\": { \"property\": \"Booking UID\", \"rich_text\": { \"equals\": $json.booking_uid } } } }}",
        "sendBody": true,
        "sendHeaders": true,
        "specifyBody": "json",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "headerParameters": {
          "parameters": [
            {
              "name": "Notion-Version",
              "value": "2025-09-03"
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        }
      },
      "retryOnFail": true,
      "typeVersion": 4.2,
      "waitBetweenTries": 3000,
      "credentials": {
        "httpHeaderAuth": {
          "name": "Notion Api"
        }
      }
    },
    {
      "name": "📓 Notion - Marcar No-show",
      "type": "n8n-nodes-base.httpRequest",
      "onError": "continueRegularOutput",
      "maxTries": 3,
      "position": [
        -1120,
        288
      ],
      "parameters": {
        "url": "=https://api.notion.com/v1/pages/{{ $json.results[0].id }}",
        "method": "PATCH",
        "options": {},
        "jsonBody": "={{ { \"properties\": { \"Call #1 Outcome\": { \"select\": { \"name\": \"No-show\" } } } } }}",
        "sendBody": true,
        "sendHeaders": true,
        "specifyBody": "json",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "headerParameters": {
          "parameters": [
            {
              "name": "Notion-Version",
              "value": "2025-09-03"
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        }
      },
      "retryOnFail": true,
      "typeVersion": 4.2,
      "waitBetweenTries": 3000,
      "credentials": {
        "httpHeaderAuth": {
          "name": "Notion Api"
        }
      }
    },
    {
      "name": "⏰ Esperar hasta 2h Antes",
      "type": "n8n-nodes-base.wait",
      "position": [
        1312,
        912
      ],
      "webhookId": "afba3590-1441-406c-a3fb-307faef4e519",
      "parameters": {
        "resume": "specificTime",
        "dateTime": "={{ $json.time_2h_before }}"
      },
      "typeVersion": 1.1
    },
    {
      "name": "🔍 Buscar en Sheets (2h)",
      "type": "n8n-nodes-base.googleSheets",
      "maxTries": 3,
      "position": [
        1520,
        912
      ],
      "parameters": {
        "options": {
          "returnFirstMatch": false
        },
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultName": "Hoja 1"
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "TU_ID_DE_GOOGLE_SHEET"
        }
      },
      "retryOnFail": true,
      "typeVersion": 4.7,
      "waitBetweenTries": 3000,
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "Google Sheets account"
        }
      }
    },
    {
      "name": "📝 Verificar Confirmación 2h",
      "type": "n8n-nodes-base.code",
      "position": [
        1744,
        912
      ],
      "parameters": {
        "jsCode": "const rows  = $input.all();\nconst d     = $('📦 Extraer Datos Cal.com').item.json;\nconst phone = d.phone;\nconst fechaHora = `${d.date_formatted} – ${d.time_formatted}`;\nconst sortedRows = [...rows].sort((a, b) => (b.json.row_number || 0) - (a.json.row_number || 0));\nconst match = sortedRows.find(row => {\n  const t = (row.json['Teléfono'] || '').replace(/[\\s\\-\\(\\)\\+]/g, '');\n  const phoneMatches = t === phone || t.includes(phone) || phone.includes(t);\n  const fechaMatches = (row.json['Fecha/hora'] || '') === fechaHora;\n  return phoneMatches && fechaMatches;\n});\nconst confirmado  = match ? (match.json['Confirmado'] || 'NO').toUpperCase() : 'NO';\nconst ya_confirmo = confirmado === 'SÍ' || confirmado === 'SI' || confirmado === 'YES';\nreturn {\n  ya_confirmo, matched: !!match, phone,\n  firstName: d.firstName, email: d.email,\n  date_formatted: d.date_formatted, time_formatted: d.time_formatted,\n  reschedule_link: d.reschedule_link,\n  booking_uid: d.booking_uid\n};"
      },
      "typeVersion": 2
    },
    {
      "name": "¿Sigue Sin Confirmar?",
      "type": "n8n-nodes-base.if",
      "position": [
        1968,
        912
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": false,
            "typeValidation": "loose"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "c01",
              "operator": {
                "type": "boolean",
                "operation": "equals"
              },
              "leftValue": "={{ $json.ya_confirmo }}",
              "rightValue": false
            },
            {
              "id": "c02",
              "operator": {
                "type": "boolean",
                "operation": "equals"
              },
              "leftValue": "={{ $json.matched }}",
              "rightValue": true
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "name": "❌ Cancelar Reserva Cal.com",
      "type": "n8n-nodes-base.httpRequest",
      "onError": "continueErrorOutput",
      "maxTries": 3,
      "position": [
        2192,
        800
      ],
      "parameters": {
        "url": "=https://api.cal.com/v2/bookings/{{ $json.booking_uid }}/cancel",
        "method": "POST",
        "options": {},
        "jsonBody": "={{ { \"cancellationReason\": \"No confirmó a tiempo\" } }}",
        "sendBody": true,
        "sendHeaders": true,
        "specifyBody": "json",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "headerParameters": {
          "parameters": [
            {
              "name": "cal-api-version",
              "value": "2024-08-13"
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        }
      },
      "retryOnFail": true,
      "typeVersion": 4.2,
      "waitBetweenTries": 3000,
      "credentials": {
        "httpHeaderAuth": {
          "name": "CAL.COM API"
        }
      }
    },
    {
      "name": "📱 WA - Cancelación",
      "type": "n8n-nodes-base.whatsApp",
      "onError": "continueRegularOutput",
      "maxTries": 3,
      "position": [
        2400,
        704
      ],
      "webhookId": "c5906eca-26ea-4eb3-b178-5a4de329d805",
      "parameters": {
        "template": "cita_cancelada_sin_confirmar|es_CO",
        "components": {
          "component": [
            {
              "bodyParameters": {
                "parameter": [
                  {
                    "text": "={{$json.firstName}}"
                  }
                ]
              }
            }
          ]
        },
        "phoneNumberId": "TU_PHONE_NUMBER_ID_DE_WHATSAPP",
        "recipientPhoneNumber": "={{$json.phone}}"
      },
      "retryOnFail": true,
      "typeVersion": 1.1,
      "waitBetweenTries": 3000,
      "credentials": {
        "whatsAppApi": {
          "name": "Soyjpprieto - WhatsApp account"
        }
      }
    },
    {
      "name": "📧 Email - Cancelación",
      "type": "n8n-nodes-base.gmail",
      "onError": "continueRegularOutput",
      "maxTries": 3,
      "position": [
        2400,
        848
      ],
      "webhookId": "c26ac7b2-e807-485c-b5a9-f4e0bf1024a2",
      "parameters": {
        "sendTo": "={{ $json.email }}",
        "message": "=Hola {{ $json.firstName }},<br><br>Tu sesión no fue confirmada a tiempo y por eso la cancelamos automáticamente.<br><br>Si quieres agendar de nuevo: {{ $json.reschedule_link }}<br><br>TU_NOMBRE",
        "options": {},
        "subject": "Tu sesión fue cancelada"
      },
      "retryOnFail": true,
      "typeVersion": 2.1,
      "waitBetweenTries": 3000,
      "credentials": {
        "gmailOAuth2": {
          "name": "Gmail account"
        }
      }
    },
    {
      "name": "📓 Notion - Buscar Lead (Cancelación)",
      "type": "n8n-nodes-base.httpRequest",
      "onError": "continueRegularOutput",
      "maxTries": 3,
      "position": [
        2400,
        992
      ],
      "parameters": {
        "url": "=https://api.notion.com/v1/data_sources/TU_DATA_SOURCE_ID_DE_NOTION/query",
        "method": "POST",
        "options": {},
        "jsonBody": "={{ { \"filter\": { \"property\": \"Booking UID\", \"rich_text\": { \"equals\": $json.booking_uid } } } }}",
        "sendBody": true,
        "sendHeaders": true,
        "specifyBody": "json",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "headerParameters": {
          "parameters": [
            {
              "name": "Notion-Version",
              "value": "2025-09-03"
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        }
      },
      "retryOnFail": true,
      "typeVersion": 4.2,
      "waitBetweenTries": 3000,
      "credentials": {
        "httpHeaderAuth": {
          "name": "Notion Api"
        }
      }
    },
    {
      "name": "📓 Notion - Marcar Cancelado",
      "type": "n8n-nodes-base.httpRequest",
      "onError": "continueRegularOutput",
      "maxTries": 3,
      "position": [
        2624,
        992
      ],
      "parameters": {
        "url": "=https://api.notion.com/v1/pages/{{ $json.results[0].id }}",
        "method": "PATCH",
        "options": {},
        "jsonBody": "={{ { \"properties\": { \"Status\": { \"status\": { \"name\": \"Closed-Lost\" } }, \"Lost Reason\": { \"select\": { \"name\": \"Ghosted\" } } } } }}",
        "sendBody": true,
        "sendHeaders": true,
        "specifyBody": "json",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "headerParameters": {
          "parameters": [
            {
              "name": "Notion-Version",
              "value": "2025-09-03"
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        }
      },
      "retryOnFail": true,
      "typeVersion": 4.2,
      "waitBetweenTries": 3000,
      "credentials": {
        "httpHeaderAuth": {
          "name": "Notion Api"
        }
      }
    },
    {
      "name": "🔍 Verificar Sigue Confirmado (1h)",
      "type": "n8n-nodes-base.googleSheets",
      "maxTries": 3,
      "position": [
        3744,
        432
      ],
      "parameters": {
        "options": {
          "returnFirstMatch": false
        },
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultName": "Hoja 1"
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "TU_ID_DE_GOOGLE_SHEET"
        }
      },
      "retryOnFail": true,
      "typeVersion": 4.7,
      "waitBetweenTries": 3000,
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "Google Sheets account"
        }
      }
    },
    {
      "name": "📝 Sigue Confirmado 1h",
      "type": "n8n-nodes-base.code",
      "position": [
        3920,
        448
      ],
      "parameters": {
        "jsCode": "const rows  = $input.all();\nconst d     = $('📦 Extraer Datos Cal.com').item.json;\nconst phone = d.phone;\nconst fechaHora = `${d.date_formatted} – ${d.time_formatted}`;\nconst sortedRows = [...rows].sort((a, b) => (b.json.row_number || 0) - (a.json.row_number || 0));\nconst match = sortedRows.find(row => {\n  const t = (row.json['Teléfono'] || '').replace(/[\\s\\-\\(\\)\\+]/g, '');\n  const phoneMatches = t === phone || t.includes(phone) || phone.includes(t);\n  const fechaMatches = (row.json['Fecha/hora'] || '') === fechaHora;\n  return phoneMatches && fechaMatches;\n});\nconst confirmado = match ? (match.json['Confirmado'] || 'NO').toUpperCase() : 'NO';\nconst ya_confirmo = confirmado === 'SÍ' || confirmado === 'SI' || confirmado === 'YES';\nreturn { ya_confirmo, ...d };"
      },
      "typeVersion": 2
    },
    {
      "name": "¿Sigue Confirmado?",
      "type": "n8n-nodes-base.if",
      "position": [
        4112,
        480
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": false,
            "typeValidation": "loose"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "c01",
              "operator": {
                "type": "boolean",
                "operation": "equals"
              },
              "leftValue": "={{ $json.ya_confirmo }}",
              "rightValue": true
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "name": "🧠 Memoria Conversación WA",
      "type": "@n8n/n8n-nodes-langchain.memoryBufferWindow",
      "position": [
        -592,
        2080
      ],
      "parameters": {
        "sessionKey": "={{ $('📝 Preparar Prompt IA').item.json.phone }}",
        "sessionIdType": "customKey",
        "contextWindowLength": 20
      },
      "typeVersion": 1.3
    },
    {
      "name": "🔍 TG - Buscar Routing",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -1648,
        2512
      ],
      "parameters": {
        "url": "=https://TU_DOMINIO_N8N/api/v1/data-tables/TU_ID_DE_DATA_TABLE/rows",
        "options": {},
        "sendQuery": true,
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "queryParameters": {
          "parameters": [
            {
              "name": "filter",
              "value": "={{ JSON.stringify({type:\"and\",filters:[{columnName:\"phone\",condition:\"eq\",value:$json.phone}]}) }}"
            }
          ]
        }
      },
      "typeVersion": 4.2,
      "credentials": {
        "httpHeaderAuth": {
          "name": "n8n Internal API (self)"
        }
      }
    },
    {
      "name": "🔀 TG - Existe?",
      "type": "n8n-nodes-base.if",
      "position": [
        -1424,
        2512
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 1,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "loose"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "c1",
              "operator": {
                "type": "number",
                "operation": "gt"
              },
              "leftValue": "={{ $json.data.length }}",
              "rightValue": 0
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "name": "📋 TG - Datos Existentes",
      "type": "n8n-nodes-base.code",
      "position": [
        -1184,
        2400
      ],
      "parameters": {
        "mode": "runOnceForEachItem",
        "jsCode": "const phone = $('🔄 Extraer Mensaje WA').item.json.phone;\nconst text = $('🔄 Extraer Mensaje WA').item.json.text;\nconst senderName = $('🔄 Extraer Mensaje WA').item.json.senderName;\nconst row = $json.data[0];\nconst isConfirmation = $('🔄 Extraer Mensaje WA').item.json.isConfirmation;\nreturn { json: { phone, text, senderName, topicId: row.topicId, modoManual: !!row.modoManual, isConfirmation } };"
      },
      "typeVersion": 2
    },
    {
      "name": "📌 TG - Crear Topic",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -1184,
        2624
      ],
      "parameters": {
        "url": "=https://api.telegram.org/bot{{ $env.TELEGRAM_BOT_TOKEN }}/createForumTopic",
        "method": "POST",
        "options": {},
        "jsonBody": "={{ JSON.stringify({ chat_id: TU_CHAT_ID_DE_TELEGRAM, name: $('🔄 Extraer Mensaje WA').item.json.senderName + \" (\" + $('🔄 Extraer Mensaje WA').item.json.phone + \")\" }) }}",
        "sendBody": true,
        "specifyBody": "json"
      },
      "typeVersion": 4.2
    },
    {
      "name": "💾 TG - Guardar Nueva Fila",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -944,
        2624
      ],
      "parameters": {
        "url": "=https://TU_DOMINIO_N8N/api/v1/data-tables/TU_ID_DE_DATA_TABLE/rows/upsert",
        "method": "POST",
        "options": {},
        "jsonBody": "={{ JSON.stringify({ filter: { type: \"and\", filters: [{ columnName: \"phone\", condition: \"eq\", value: $('🔄 Extraer Mensaje WA').item.json.phone }] }, data: { phone: $('🔄 Extraer Mensaje WA').item.json.phone, name: $('🔄 Extraer Mensaje WA').item.json.senderName, topicId: $json.result.message_thread_id, modoManual: false }, returnData: true }) }}",
        "sendBody": true,
        "specifyBody": "json",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth"
      },
      "typeVersion": 4.2,
      "credentials": {
        "httpHeaderAuth": {
          "name": "n8n Internal API (self)"
        }
      }
    },
    {
      "name": "📋 TG - Datos Nuevos",
      "type": "n8n-nodes-base.code",
      "position": [
        -704,
        2624
      ],
      "parameters": {
        "mode": "runOnceForEachItem",
        "jsCode": "const phone = $('🔄 Extraer Mensaje WA').item.json.phone;\nconst text = $('🔄 Extraer Mensaje WA').item.json.text;\nconst senderName = $('🔄 Extraer Mensaje WA').item.json.senderName;\nconst row = Array.isArray($json) ? $json[0] : $json;\nconst isConfirmation = $('🔄 Extraer Mensaje WA').item.json.isConfirmation;\nreturn { json: { phone, text, senderName, topicId: row.topicId, modoManual: false, isConfirmation } };"
      },
      "typeVersion": 2
    },
    {
      "name": "🔗 TG - Merge",
      "type": "n8n-nodes-base.noOp",
      "position": [
        -464,
        2512
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "name": "📤 TG - Reenviar Mensaje",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -224,
        2512
      ],
      "parameters": {
        "url": "=https://api.telegram.org/bot{{ $env.TELEGRAM_BOT_TOKEN }}/sendMessage",
        "method": "POST",
        "options": {},
        "jsonBody": "={{ JSON.stringify({ chat_id: TU_CHAT_ID_DE_TELEGRAM, message_thread_id: $json.topicId, text: $json.senderName + \": \" + $json.text }) }}",
        "sendBody": true,
        "specifyBody": "json"
      },
      "typeVersion": 4.2
    },
    {
      "name": "📋 TG - Recombinar",
      "type": "n8n-nodes-base.code",
      "position": [
        32,
        2512
      ],
      "parameters": {
        "mode": "runOnceForEachItem",
        "jsCode": "return { json: $('🔗 TG - Merge').item.json };"
      },
      "typeVersion": 2
    },
    {
      "name": "🔀 TG - Modo Manual?",
      "type": "n8n-nodes-base.if",
      "position": [
        272,
        2512
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 1,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "loose"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "c1",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              },
              "leftValue": "={{ $json.modoManual }}",
              "rightValue": true
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "name": "📲 Telegram Trigger",
      "type": "n8n-nodes-base.telegramTrigger",
      "position": [
        -1648,
        2912
      ],
      "webhookId": "42f615ac-2d75-42e7-97c0-3b443fdd8a55",
      "parameters": {
        "updates": [
          "message"
        ],
        "additionalFields": {}
      },
      "typeVersion": 1.1,
      "credentials": {
        "telegramApi": {
          "name": "Telegram - David WA Manager"
        }
      }
    },
    {
      "name": "🔀 TG - Es Mensaje de Humano?",
      "type": "n8n-nodes-base.if",
      "position": [
        -1424,
        2912
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 1,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "loose"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "c1",
              "operator": {
                "type": "boolean",
                "operation": "notEquals"
              },
              "leftValue": "={{ $json.message.from.is_bot }}",
              "rightValue": true
            },
            {
              "id": "c2",
              "operator": {
                "type": "string",
                "operation": "exists"
              },
              "leftValue": "={{ $json.message.text }}",
              "rightValue": ""
            },
            {
              "id": "c3",
              "operator": {
                "type": "number",
                "operation": "exists"
              },
              "leftValue": "={{ $json.message.message_thread_id }}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "name": "🔀 TG - Es Comando Reanudar?",
      "type": "n8n-nodes-base.if",
      "position": [
        -1184,
        2912
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 1,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "loose"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "c1",
              "operator": {
                "type": "string",
                "operation": "startsWith"
              },
              "leftValue": "={{ $json.message.text }}",
              "rightValue": "/reanudar"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "name": "🔍 TG - Buscar por Topic (reanudar)",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -944,
        2800
      ],
      "parameters": {
        "url": "=https://TU_DOMINIO_N8N/api/v1/data-tables/TU_ID_DE_DATA_TABLE/rows",
        "options": {},
        "sendQuery": true,
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "queryParameters": {
          "parameters": [
            {
              "name": "filter",
              "value": "={{ JSON.stringify({type:\"and\",filters:[{columnName:\"topicId\",condition:\"eq\",value:$json.message.message_thread_id}]}) }}"
            }
          ]
        }
      },
      "typeVersion": 4.2,
      "credentials": {
        "httpHeaderAuth": {
          "name": "n8n Internal API (self)"
        }
      }
    },
    {
      "name": "🔀 TG - Encontrado? (reanudar)",
      "type": "n8n-nodes-base.if",
      "position": [
        -704,
        2800
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 1,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "loose"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "c1",
              "operator": {
                "type": "number",
                "operation": "gt"
              },
              "leftValue": "={{ $json.data.length }}",
              "rightValue": 0
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "name": "✅ TG - Reactivar Bot",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -464,
        2768
      ],
      "parameters": {
        "url": "=https://TU_DOMINIO_N8N/api/v1/data-tables/TU_ID_DE_DATA_TABLE/rows/upsert",
        "method": "POST",
        "options": {},
        "jsonBody": "={{ JSON.stringify({ filter: { type: \"and\", filters: [{ columnName: \"phone\", condition: \"eq\", value: $json.data[0].phone }] }, data: { phone: $json.data[0].phone, name: $json.data[0].name, topicId: $json.data[0].topicId, modoManual: false }, returnData: true }) }}",
        "sendBody": true,
        "specifyBody": "json",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth"
      },
      "typeVersion": 4.2,
      "credentials": {
        "httpHeaderAuth": {
          "name": "n8n Internal API (self)"
        }
      }
    },
    {
      "name": "💬 TG - Confirmar Reactivación",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -224,
        2768
      ],
      "parameters": {
        "url": "=https://api.telegram.org/bot{{ $env.TELEGRAM_BOT_TOKEN }}/sendMessage",
        "method": "POST",
        "options": {},
        "jsonBody": "={{ JSON.stringify({ chat_id: TU_CHAT_ID_DE_TELEGRAM, message_thread_id: $('🔀 TG - Es Comando Reanudar?').item.json.message.message_thread_id, text: \"✅ Bot reactivado para esta conversación.\" }) }}",
        "sendBody": true,
        "specifyBody": "json"
      },
      "typeVersion": 4.2
    },
    {
      "name": "🔍 TG - Buscar por Topic (responder)",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -944,
        3008
      ],
      "parameters": {
        "url": "=https://TU_DOMINIO_N8N/api/v1/data-tables/TU_ID_DE_DATA_TABLE/rows",
        "options": {},
        "sendQuery": true,
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "queryParameters": {
          "parameters": [
            {
              "name": "filter",
              "value": "={{ JSON.stringify({type:\"and\",filters:[{columnName:\"topicId\",condition:\"eq\",value:$json.message.message_thread_id}]}) }}"
            }
          ]
        }
      },
      "typeVersion": 4.2,
      "credentials": {
        "httpHeaderAuth": {
          "name": "n8n Internal API (self)"
        }
      }
    },
    {
      "name": "🔀 TG - Encontrado? (responder)",
      "type": "n8n-nodes-base.if",
      "position": [
        -704,
        3008
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 1,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "loose"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "c1",
              "operator": {
                "type": "number",
                "operation": "gt"
              },
              "leftValue": "={{ $json.data.length }}",
              "rightValue": 0
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "name": "🔒 TG - Activar Modo Manual",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -464,
        3008
      ],
      "parameters": {
        "url": "=https://TU_DOMINIO_N8N/api/v1/data-tables/TU_ID_DE_DATA_TABLE/rows/upsert",
        "method": "POST",
        "options": {},
        "jsonBody": "={{ JSON.stringify({ filter: { type: \"and\", filters: [{ columnName: \"phone\", condition: \"eq\", value: $json.data[0].phone }] }, data: { phone: $json.data[0].phone, name: $json.data[0].name, topicId: $json.data[0].topicId, modoManual: true }, returnData: true }) }}",
        "sendBody": true,
        "specifyBody": "json",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth"
      },
      "typeVersion": 4.2,
      "credentials": {
        "httpHeaderAuth": {
          "name": "n8n Internal API (self)"
        }
      }
    },
    {
      "name": "📱 TG - Enviar a Cliente WA",
      "type": "n8n-nodes-base.whatsApp",
      "position": [
        -224,
        3008
      ],
      "webhookId": "3badd72b-642b-4e3b-98b6-577c8475f995",
      "parameters": {
        "textBody": "={{ $('🔀 TG - Es Comando Reanudar?').item.json.message.text }}",
        "operation": "send",
        "phoneNumberId": "TU_PHONE_NUMBER_ID_DE_WHATSAPP",
        "additionalFields": {},
        "recipientPhoneNumber": "={{ $json.data[0].phone }}"
      },
      "typeVersion": 1,
      "credentials": {
        "whatsAppApi": {
          "name": "Soyjpprieto - WhatsApp account"
        }
      }
    },
    {
      "name": "📤 TG - Reenviar Respuesta Bot",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        432,
        1872
      ],
      "parameters": {
        "url": "=https://api.telegram.org/bot{{ $env.TELEGRAM_BOT_TOKEN }}/sendMessage",
        "method": "POST",
        "options": {},
        "jsonBody": "={{ JSON.stringify({ chat_id: TU_CHAT_ID_DE_TELEGRAM, message_thread_id: $('📋 TG - Recombinar').item.json.topicId, text: \"🤖 Bot: \" + $('🤖 Agente IA - Bob').item.json.output }) }}",
        "sendBody": true,
        "specifyBody": "json"
      },
      "typeVersion": 4.2
    },
    {
      "name": "🔒 Pausar Bot (Escalar)",
      "type": "@n8n/n8n-nodes-langchain.toolHttpRequest",
      "position": [
        -448,
        2208
      ],
      "parameters": {
        "url": "=https://TU_DOMINIO_N8N/api/v1/data-tables/TU_ID_DE_DATA_TABLE/rows/upsert",
        "method": "POST",
        "jsonBody": "={{ JSON.stringify({ filter: { type: \"and\", filters: [{ columnName: \"phone\", condition: \"eq\", value: $('🔄 Extraer Mensaje WA').item.json.phone }] }, data: { phone: $('🔄 Extraer Mensaje WA').item.json.phone, name: $('🔄 Extraer Mensaje WA').item.json.senderName, topicId: $('📋 TG - Recombinar').item.json.topicId, modoManual: true }, returnData: true }) }}",
        "sendBody": true,
        "sendHeaders": true,
        "specifyBody": "json",
        "toolDescription": "Úsala INMEDIATAMENTE, junto con 'Alertar al Dueño', cuando el cliente pida explícitamente hablar con una persona real o con TU_NOMBRE directamente, o insista más de una vez sin quedar conforme con tus respuestas. No requiere parámetros.",
        "parametersHeaders": {
          "values": [
            {
              "name": "Content-Type",
              "value": "application/json",
              "valueProvider": "fieldValue"
            },
            {
              "name": "X-N8N-API-KEY",
              "value": "={{ $env.N8N_INTERNAL_KEY }}",
              "valueProvider": "fieldValue"
            }
          ]
        },
        "placeholderDefinitions": {
          "values": []
        }
      },
      "typeVersion": 1.1
    },
    {
      "name": "🆘 Alertar al Dueño",
      "type": "@n8n/n8n-nodes-langchain.toolHttpRequest",
      "position": [
        -208,
        2208
      ],
      "parameters": {
        "url": "=https://api.telegram.org/bot{{ $env.TELEGRAM_BOT_TOKEN }}/sendMessage",
        "method": "POST",
        "jsonBody": "={{ JSON.stringify({ chat_id: TU_CHAT_ID_DE_TELEGRAM, message_thread_id: $('📋 TG - Recombinar').item.json.topicId, text: \"🆘 URGENTE: \" + $('🔄 Extraer Mensaje WA').item.json.senderName + \" está pidiendo hablar contigo directamente. Por favor responde en este tema.\" }) }}",
        "sendBody": true,
        "specifyBody": "json",
        "toolDescription": "Úsala JUNTO CON 'Pausar Bot (Escalar)' cuando el cliente pida hablar con una persona real o con TU_NOMBRE. Envía una alerta urgente a TU_NOMBRE para que responda personalmente en Telegram. No requiere parámetros.",
        "placeholderDefinitions": {
          "values": []
        }
      },
      "typeVersion": 1.1
    },
    {
      "name": "🔁 Recuperar Datos3",
      "type": "n8n-nodes-base.code",
      "position": [
        2304,
        800
      ],
      "parameters": {
        "jsCode": "return $('📦 Extraer Datos Cal.com').item.json;"
      },
      "typeVersion": 2
    },
    {
      "name": "¿Faltan menos de 24h?",
      "type": "n8n-nodes-base.if",
      "position": [
        1264,
        400
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "c01",
              "operator": {
                "type": "number",
                "operation": "lt"
              },
              "leftValue": "={{ new Date($json.start_time_iso).getTime() - Date.now() }}",
              "rightValue": 86400000
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "name": "🤖 Agente IA - Bob",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        -688,
        1808
      ],
      "parameters": {
        "text": "={{ $(\"📝 Preparar Prompt IA\").item.json.userMessage }}",
        "options": {
          "systemMessage": "=Eres el asistente virtual y setter experto de TU_NOMBRE (TU_DESCRIPCION_DEL_NEGOCIO).\n\nCONTEXTO DEL CLIENTE:\n- Nombre: {{ $(\"📝 Preparar Prompt IA\").item.json.senderName }}\n- Teléfono (WhatsApp): {{ $(\"📝 Preparar Prompt IA\").item.json.phone }}\n- Cita agendada: {{ $(\"📝 Preparar Prompt IA\").item.json.fechaCita }}\n\nREGLAS DE COMPORTAMIENTO:\n1. Responde SIEMPRE en el idioma del cliente. Sé breve y cálido (máximo 4 líneas por mensaje, salvo cuando debas listar opciones).\n\n2. FLUJO PARA AGENDAR O REAGENDAR (síguelo en este orden exacto, un paso a la vez, sin saltarte ninguno):\n   a) Usa la herramienta 'Obtener Slots Disponibles' para consultar los horarios libres. Los horarios que recibas vienen en UTC.\n   b) Primero presenta 2-3 opciones de DÍA (sin horas todavía). Espera a que el cliente elija un día.\n   c) Cuando el cliente elija el día, pregúntale en qué ciudad o zona horaria está, para poder mostrarle las horas en su hora local. Espera su respuesta antes de continuar.\n   d) Con la ciudad/zona horaria que te dio, convierte correctamente los horarios (que están en UTC) a su hora local y presenta 2-3 opciones de HORA ya convertidas a esa zona. Espera a que elija una.\n   e) Cuando el cliente confirme día y hora, pídele su nombre completo y correo electrónico (la zona horaria ya la obtuviste en el paso c, no la vuelvas a pedir). Espera a que te dé ambos datos.\n   f) Después pídele estas 3 cosas, todas en un solo mensaje para que sea rápido:\n      1. Cuál es la facturación mensual de su negocio — dale estas opciones exactas: '$5.000 USD - $10.000 USD', '$10.001 USD - $15.000 USD', '$15.001 USD - $20.000 USD', '$20.001 USD - $30.000 USD', 'Mas de $30.000 USD'\n      2. Cuánto invierte al mes en anuncios publicitarios — dale estas opciones exactas: 'Entre $1.000 USD a $3.000 USD', 'Entre $3.001 USD a $5.000 USD', 'Entre $5.001 USD a $10.000 USD', 'Entre $10.001 USD a $20.000 USD', 'Mas de $20.000 USD'\n      3. Qué vende o a qué se dedica su negocio (respuesta libre y breve)\n      Espera a que te dé los 3 datos. Si el cliente responde con algo que no coincide exactamente con las opciones dadas para facturación o inversión en ads, pídele que elija una de las opciones listadas antes de continuar.\n   g) Solo cuando tengas día, hora, nombre completo, correo, zona horaria y los 3 datos del paso f, usa la herramienta 'Crear Reserva Cal.com' con esos datos exactos. El número de teléfono para la reserva NO se lo pidas al cliente: usa el que ya tienes en CONTEXTO DEL CLIENTE (Teléfono WhatsApp).\n   h) NUNCA le digas al cliente que su cita 'quedó agendada' o 'confirmada' sin haber llamado a la herramienta 'Crear Reserva Cal.com' Y que la respuesta de esa herramienta contenga explícitamente un identificador de reserva real (un campo como 'uid', 'id' o 'bookingUid' dentro de los datos de una reserva creada). Una respuesta HTTP exitosa por sí sola NO es suficiente evidencia — verifica que el contenido sea realmente una reserva creada, no otro tipo de dato. Si la herramienta falla, da error, o su respuesta no contiene ese identificador de reserva, dile al cliente que hubo un problema técnico y que TU_NOMBRE se lo confirmará personalmente en breve — NUNCA inventes ni asumas que la reserva se creó.\n\n3. Si el cliente pide explícitamente hablar con una persona real o con TU_NOMBRE directamente, o insiste más de una vez sin quedar conforme con tus respuestas (por ejemplo, repite la misma solicitud 3 o más veces), usa AMBAS herramientas 'Pausar Bot (Escalar)' y 'Alertar al Dueño' en ese momento. Después de usarlas, dile al cliente que TU_NOMBRE se pondrá en contacto con él directamente en breve, y NO sigas intentando resolver la solicitud tú mismo a partir de ahí.\n\n3. Si el cliente pregunta sobre servicios → explica que TU_NOMBRE ayuda a TU_CLIENTE_IDEAL con TU_SERVICIO. Si no sabes algo, di que TU_NOMBRE le responderá personalmente.\n4. Si el cliente confirma asistencia a una cita que YA estaba agendada previamente (no una nueva que estés creando tú) → felicítale y recuérdale la fecha.\n5. NUNCA inventes horarios disponibles ni confirmaciones de reserva sin haber consultado la herramienta correspondiente primero y recibido una respuesta real y exitosa."
        },
        "promptType": "define"
      },
      "typeVersion": 1.7
    },
    {
      "name": "¿Ya estaba cancelada?",
      "type": "n8n-nodes-base.if",
      "position": [
        2416,
        944
      ],
      "parameters": {
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "operator": {
                "type": "string",
                "operation": "contains"
              },
              "leftValue": "={{ JSON.stringify($json).toLowerCase() }}",
              "rightValue": "already"
            },
            {
              "operator": {
                "type": "string",
                "operation": "contains"
              },
              "leftValue": "={{ JSON.stringify($json).toLowerCase() }}",
              "rightValue": "cancel"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "name": "✅ No-op (ya estaba cancelada)",
      "type": "n8n-nodes-base.noOp",
      "position": [
        2640,
        880
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "name": "🛑 Error Inesperado - Cancelación",
      "type": "n8n-nodes-base.stopAndError",
      "position": [
        2640,
        1020
      ],
      "parameters": {
        "errorType": "errorMessage",
        "errorMessage": "=Cancelación en Cal.com falló con un error inesperado (no era 'ya cancelada'): {{ JSON.stringify($json) }}"
      },
      "typeVersion": 1
    },
    {
      "name": "📓 Notion Log - Mensaje Cliente",
      "type": "n8n-nodes-base.executeWorkflow",
      "typeVersion": 1.2,
      "position": [
        -2440,
        2010
      ],
      "onError": "continueRegularOutput",
      "retryOnFail": true,
      "maxTries": 2,
      "waitBetweenTries": 2000,
      "parameters": {
        "source": "database",
        "workflowId": {
          "__rl": true,
          "value": "TU_ID_DEL_SUBFLUJO_LOGGER",
          "mode": "id"
        },
        "workflowInputs": {
          "mappingMode": "defineBelow",
          "value": {
            "phone": "={{ $json.phone }}",
            "name": "={{ $json.senderName }}",
            "sender": "Cliente",
            "text": "={{ $json.text }}"
          }
        },
        "options": {
          "waitForSubWorkflow": false
        }
      },
      "disabled": true
    },
    {
      "name": "📓 Notion Log - Mensaje Bot",
      "type": "n8n-nodes-base.executeWorkflow",
      "typeVersion": 1.2,
      "position": [
        376,
        2122
      ],
      "onError": "continueRegularOutput",
      "retryOnFail": true,
      "maxTries": 2,
      "waitBetweenTries": 2000,
      "parameters": {
        "source": "database",
        "workflowId": {
          "__rl": true,
          "value": "TU_ID_DEL_SUBFLUJO_LOGGER",
          "mode": "id"
        },
        "workflowInputs": {
          "mappingMode": "defineBelow",
          "value": {
            "phone": "={{ $('📝 Preparar Prompt IA').item.json.phone }}",
            "name": "={{ $('🔄 Extraer Mensaje WA').item.json.senderName }}",
            "sender": "Bot",
            "text": "={{ $('🤖 Agente IA - Bob').item.json.output }}"
          }
        },
        "options": {
          "waitForSubWorkflow": false
        }
      },
      "disabled": true
    },
    {
      "name": "📓 Notion Log - Mensaje Humano",
      "type": "n8n-nodes-base.executeWorkflow",
      "typeVersion": 1.2,
      "position": [
        -24,
        3258
      ],
      "onError": "continueRegularOutput",
      "retryOnFail": true,
      "maxTries": 2,
      "waitBetweenTries": 2000,
      "parameters": {
        "source": "database",
        "workflowId": {
          "__rl": true,
          "value": "TU_ID_DEL_SUBFLUJO_LOGGER",
          "mode": "id"
        },
        "workflowInputs": {
          "mappingMode": "defineBelow",
          "value": {
            "phone": "={{ $json.data[0].phone }}",
            "name": "={{ $json.data[0].name }}",
            "sender": "Humano",
            "text": "={{ $('🔀 TG - Es Comando Reanudar?').item.json.message.text }}"
          }
        },
        "options": {
          "waitForSubWorkflow": false
        }
      },
      "disabled": true
    },
    {
      "name": "OpenRouter Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenRouter",
      "typeVersion": 1,
      "position": [
        -720,
        2020
      ],
      "parameters": {
        "model": "google/gemini-3.6-flash",
        "options": {}
      },
      "credentials": {
        "openRouterApi": {
          "name": "OpenRouter account"
        }
      }
    }
  ],
  "connections": {
    "📊 Registrar Agendamiento": {
      "main": [
        [
          {
            "node": "⏳ Esperar 1 min",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "⏳ Esperar 1 min": {
      "main": [
        [
          {
            "node": "🔍 Verificar si Contactó",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "🔍 Verificar si Contactó": {
      "main": [
        [
          {
            "node": "📝 Analizar Contacto",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "📝 Analizar Contacto": {
      "main": [
        [
          {
            "node": "¿Ya Contactó?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "¿Ya Contactó?": {
      "main": [
        [
          {
            "node": "🔁 Recuperar Datos",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "📱 WA - Confirmación",
            "type": "main",
            "index": 0
          },
          {
            "node": "📧 Email - Confirmación",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "📱 WA - Confirmación": {
      "main": [
        [
          {
            "node": "🔁 Recuperar Datos",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "⏰ Esperar hasta 24h Antes": {
      "main": [
        [
          {
            "node": "🔍 Buscar en Sheets",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "🔍 Buscar en Sheets": {
      "main": [
        [
          {
            "node": "📝 Extraer Datos 24h",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "📝 Extraer Datos 24h": {
      "main": [
        [
          {
            "node": "¿Ya Confirmó?",
            "type": "main",
            "index": 0
          },
          {
            "node": "📧 Email - Recordatorio 24h",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "¿Ya Confirmó?": {
      "main": [
        [
          {
            "node": "📱 WA - 24h (Ya Confirmó)",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "📱 WA - 24h (Sin Confirmar)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "📱 WA - 24h (Ya Confirmó)": {
      "main": [
        [
          {
            "node": "🔁 Recuperar Datos1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "📱 WA - 24h (Sin Confirmar)": {
      "main": [
        [
          {
            "node": "🔁 Recuperar Datos1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "⏰ Esperar hasta 1h Antes": {
      "main": [
        [
          {
            "node": "🔍 Verificar Sigue Confirmado (1h)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "📱 WA - Recordatorio 1h": {
      "main": [
        [
          {
            "node": "🔁 Recuperar Datos2",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "⏰ Esperar hasta 15min Antes": {
      "main": [
        [
          {
            "node": "📱 WA - Recordatorio 15min",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "📱 WA - Recordatorio 15min": {
      "main": [
        [
          {
            "node": "📊 Log Final",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "🔄 Extraer Mensaje WA": {
      "main": [
        [
          {
            "node": "🔍 TG - Buscar Routing",
            "type": "main",
            "index": 0
          },
          {
            "node": "📓 Notion Log - Mensaje Cliente",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "¿Es Confirmación?": {
      "main": [
        [
          {
            "node": "🔍 Buscar Cita en Sheets",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "🔍 Buscar Contexto IA",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "🔍 Buscar Cita en Sheets": {
      "main": [
        [
          {
            "node": "📝 Preparar Respuesta",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "📝 Preparar Respuesta": {
      "main": [
        [
          {
            "node": "✅ Actualizar Confirmado + Contactó",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "✅ Actualizar Confirmado + Contactó": {
      "main": [
        [
          {
            "node": "📱 Responder WA Confirmación",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "🔍 Buscar Contexto IA": {
      "main": [
        [
          {
            "node": "📝 Preparar Prompt IA",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "✅ Marcar Contactó WA": {
      "main": [
        [
          {
            "node": "🤖 Agente IA - Bob",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "📝 Preparar Prompt IA": {
      "main": [
        [
          {
            "node": "✅ Marcar Contactó WA",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "📱 WhatsApp Trigger": {
      "main": [
        [
          {
            "node": "🔄 Extraer Mensaje WA",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "📅 Obtener Slots Disponibles": {
      "ai_tool": [
        [
          {
            "node": "🤖 Agente IA - Bob",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "📅 Cal.com Trigger": {
      "main": [
        [
          {
            "node": "¿Es Reserva Creada?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "✅ Crear Reserva Cal.com": {
      "ai_tool": [
        [
          {
            "node": "🤖 Agente IA - Bob",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "📦 Extraer Datos Cal.com": {
      "main": [
        [
          {
            "node": "📊 Registrar Agendamiento",
            "type": "main",
            "index": 0
          },
          {
            "node": "⏰ Esperar hasta 2h Antes",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "📦 Datos No-Show": {
      "main": [
        [
          {
            "node": "📱 WA - No Show",
            "type": "main",
            "index": 0
          },
          {
            "node": "📧 Email - No Show",
            "type": "main",
            "index": 0
          },
          {
            "node": "📓 Notion - Buscar Lead",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Es No-Show?": {
      "main": [
        [
          {
            "node": "📦 Datos No-Show",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "📦 Extraer Datos Cal.com",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "🔁 Recuperar Datos1": {
      "main": [
        [
          {
            "node": "⏰ Esperar hasta 1h Antes",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "🔁 Recuperar Datos2": {
      "main": [
        [
          {
            "node": "⏰ Esperar hasta 15min Antes",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "¿Es Reserva Creada?": {
      "main": [
        [
          {
            "node": "Es No-Show?",
            "type": "main",
            "index": 0
          }
        ],
        []
      ]
    },
    "📓 Notion - Buscar Lead": {
      "main": [
        [
          {
            "node": "📓 Notion - Marcar No-show",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "⏰ Esperar hasta 2h Antes": {
      "main": [
        [
          {
            "node": "🔍 Buscar en Sheets (2h)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "🔍 Buscar en Sheets (2h)": {
      "main": [
        [
          {
            "node": "📝 Verificar Confirmación 2h",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "📝 Verificar Confirmación 2h": {
      "main": [
        [
          {
            "node": "¿Sigue Sin Confirmar?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "¿Sigue Sin Confirmar?": {
      "main": [
        [
          {
            "node": "❌ Cancelar Reserva Cal.com",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "📓 Notion - Buscar Lead (Cancelación)": {
      "main": [
        [
          {
            "node": "📓 Notion - Marcar Cancelado",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "🔍 Verificar Sigue Confirmado (1h)": {
      "main": [
        [
          {
            "node": "📝 Sigue Confirmado 1h",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "📝 Sigue Confirmado 1h": {
      "main": [
        [
          {
            "node": "¿Sigue Confirmado?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "¿Sigue Confirmado?": {
      "main": [
        [
          {
            "node": "📱 WA - Recordatorio 1h",
            "type": "main",
            "index": 0
          }
        ],
        []
      ]
    },
    "🧠 Memoria Conversación WA": {
      "ai_memory": [
        [
          {
            "node": "🤖 Agente IA - Bob",
            "type": "ai_memory",
            "index": 0
          }
        ]
      ]
    },
    "🔍 TG - Buscar Routing": {
      "main": [
        [
          {
            "node": "🔀 TG - Existe?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "🔀 TG - Existe?": {
      "main": [
        [
          {
            "node": "📋 TG - Datos Existentes",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "📌 TG - Crear Topic",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "📋 TG - Datos Existentes": {
      "main": [
        [
          {
            "node": "🔗 TG - Merge",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "📌 TG - Crear Topic": {
      "main": [
        [
          {
            "node": "💾 TG - Guardar Nueva Fila",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "💾 TG - Guardar Nueva Fila": {
      "main": [
        [
          {
            "node": "📋 TG - Datos Nuevos",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "📋 TG - Datos Nuevos": {
      "main": [
        [
          {
            "node": "🔗 TG - Merge",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "🔗 TG - Merge": {
      "main": [
        [
          {
            "node": "📤 TG - Reenviar Mensaje",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "📤 TG - Reenviar Mensaje": {
      "main": [
        [
          {
            "node": "📋 TG - Recombinar",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "📋 TG - Recombinar": {
      "main": [
        [
          {
            "node": "🔀 TG - Modo Manual?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "🔀 TG - Modo Manual?": {
      "main": [
        [],
        [
          {
            "node": "¿Es Confirmación?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "📲 Telegram Trigger": {
      "main": [
        [
          {
            "node": "🔀 TG - Es Mensaje de Humano?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "🔀 TG - Es Mensaje de Humano?": {
      "main": [
        [
          {
            "node": "🔀 TG - Es Comando Reanudar?",
            "type": "main",
            "index": 0
          }
        ],
        []
      ]
    },
    "🔀 TG - Es Comando Reanudar?": {
      "main": [
        [
          {
            "node": "🔍 TG - Buscar por Topic (reanudar)",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "🔍 TG - Buscar por Topic (responder)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "🔍 TG - Buscar por Topic (reanudar)": {
      "main": [
        [
          {
            "node": "🔀 TG - Encontrado? (reanudar)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "🔀 TG - Encontrado? (reanudar)": {
      "main": [
        [
          {
            "node": "✅ TG - Reactivar Bot",
            "type": "main",
            "index": 0
          }
        ],
        []
      ]
    },
    "✅ TG - Reactivar Bot": {
      "main": [
        [
          {
            "node": "💬 TG - Confirmar Reactivación",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "🔍 TG - Buscar por Topic (responder)": {
      "main": [
        [
          {
            "node": "🔀 TG - Encontrado? (responder)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "🔀 TG - Encontrado? (responder)": {
      "main": [
        [
          {
            "node": "🔒 TG - Activar Modo Manual",
            "type": "main",
            "index": 0
          }
        ],
        []
      ]
    },
    "🔒 TG - Activar Modo Manual": {
      "main": [
        [
          {
            "node": "📱 TG - Enviar a Cliente WA",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "📱 Responder WA (IA)": {
      "main": [
        [
          {
            "node": "📤 TG - Reenviar Respuesta Bot",
            "type": "main",
            "index": 0
          },
          {
            "node": "📓 Notion Log - Mensaje Bot",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "🔒 Pausar Bot (Escalar)": {
      "ai_tool": [
        [
          {
            "node": "🤖 Agente IA - Bob",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "🆘 Alertar al Dueño": {
      "ai_tool": [
        [
          {
            "node": "🤖 Agente IA - Bob",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "❌ Cancelar Reserva Cal.com": {
      "main": [
        [
          {
            "node": "🔁 Recuperar Datos3",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "¿Ya estaba cancelada?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "🔁 Recuperar Datos3": {
      "main": [
        [
          {
            "node": "📱 WA - Cancelación",
            "type": "main",
            "index": 0
          },
          {
            "node": "📧 Email - Cancelación",
            "type": "main",
            "index": 0
          },
          {
            "node": "📓 Notion - Buscar Lead (Cancelación)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "🔁 Recuperar Datos": {
      "main": [
        [
          {
            "node": "¿Faltan menos de 24h?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "¿Faltan menos de 24h?": {
      "main": [
        [
          {
            "node": "🔁 Recuperar Datos1",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "⏰ Esperar hasta 24h Antes",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "🤖 Agente IA - Bob": {
      "main": [
        [
          {
            "node": "📱 Responder WA (IA)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "¿Ya estaba cancelada?": {
      "main": [
        [
          {
            "node": "✅ No-op (ya estaba cancelada)",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "🛑 Error Inesperado - Cancelación",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "📱 TG - Enviar a Cliente WA": {
      "main": [
        [
          {
            "node": "📓 Notion Log - Mensaje Humano",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "OpenRouter Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "🤖 Agente IA - Bob",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    }
  },
  "settings": {
    "executionOrder": "v1",
    "timezone": "America/Edmonton"
  }
}