{
  "name": "Logixb2b — Formularios inteligentes leads (Apollo URL + Apify + IA)",
  "meta": {
    "templateCredsSetupCompleted": false,
    "description": "Manual Trigger → Config → Payload ICP demo → Agente IA URL Apollo (o demo) → validar URL → IF demoMode (simular leads) / HTTP Apify sync → map fields → opcional Agente IA companyBrief → Google Sheets Leads_Formulario → upsert CRM opcional → Slack resumen. Europe/Madrid. Placeholders REEMPLAZA_*. No envía SMTP."
  },
  "settings": {
    "executionOrder": "v1",
    "timezone": "Europe/Madrid"
  },
  "active": false,
  "pinData": {},
  "tags": [
    { "name": "Logixb2b" },
    { "name": "recursos" },
    { "name": "prospeccion" }
  ],
  "nodes": [
    {
      "id": "fl-sticky",
      "name": "INSTRUCCIONES (conectar + VPS)",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [-720, -80],
      "parameters": {
        "content": "## INSTRUCCIONES — Formularios inteligentes leads\n\n**Recurso:** `/recursos/formularios-inteligentes-leads-n8n`\n**Guía:** /generacion-leads-formularios-inteligentes-automatizacion\n**Zona:** Europe/Madrid · `active: false` al importar.\n\n### 1) Importar\n1. n8n → ⋯ → **Import from File** → este JSON.\n2. No pegues secretos en el lienzo.\n\n### 2) Credenciales a conectar\n- **Modelo OpenAI** (×2: URL Apollo + companyBrief): Credentials → OpenAI API (`REEMPLAZA` vía UI).\n- **Google Sheets** Append: OAuth Google; hoja con pestaña **Leads_Formulario**.\n- **HTTP Apify** (rama producción): header Bearer = token Apify (puedes moverlo a Header Auth).\n- **Slack webhook** / CRM HubSpot|Pipedrive: URLs y tokens en **Config Form Leads** (`REEMPLAZA_*`).\n\n### 3) Flujo del lienzo\n1. Manual Trigger (demo) → Config → Payload ICP.\n2. IF `demoMode`:\n   - **true** → URL Apollo de ejemplo (sin gastar tokens).\n   - **false** → **Agente IA URL Apollo** + Modelo OpenAI → Parse URL.\n3. Validar URL https/Apollo → IF inválida → Slack error (no Apify).\n4. IF `demoMode`:\n   - **true** → 3 leads demo (*-example.es).\n   - **false** → **HTTP Apify** `run-sync-get-dataset-items`.\n5. Mapear campos → IF email vacío skip.\n6. IF `enableCompanyBrief` → **Agente IA brief empresa** (opcional).\n7. Append Sheets **Leads_Formulario** → Upsert CRM (opcional) → Slack resumen.\n\n### 4) Producción formulario real\nSustituye Manual Trigger + Payload demo por **n8n Form Trigger** o Webhook con campos: `jobTitles`, `industryKeywords`, `employeeRanges`, `location`. Pon `demoMode=false`, plan API Apify y OpenAI.\n\n### 5) VPS UE 24/7\nDocker Compose + Postgres + HTTPS + `GENERIC_TIMEZONE=Europe/Madrid`.\n\n### 6) RGPD + EU AI Act\nMinimiza PII. LLM URL/brief = deployer Art. 4. /uso-responsable-de-ia-y-transparencia\n",
        "height": 1680,
        "width": 680,
        "color": 4
      }
    },
    {
      "id": "fl-trigger",
      "name": "Manual Trigger form leads",
      "type": "n8n-nodes-base.manualTrigger",
      "typeVersion": 1,
      "position": [0, 420],
      "parameters": {}
    },
    {
      "id": "fl-config",
      "name": "Config Form Leads",
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [260, 420],
      "parameters": {
        "mode": "manual",
        "duplicateItem": false,
        "assignments": {
          "assignments": [
            { "id": "a1", "name": "batchLabel", "value": "leads-form-demo-2026-08", "type": "string" },
            { "id": "a2", "name": "demoMode", "value": "true", "type": "string" },
            { "id": "a3", "name": "totalRecords", "value": "50", "type": "string" },
            { "id": "a4", "name": "enableCompanyBrief", "value": "true", "type": "string" },
            { "id": "a5", "name": "apifyActorId", "value": "REEMPLAZA_APIFY_ACTOR_ID", "type": "string" },
            { "id": "a6", "name": "apifyToken", "value": "REEMPLAZA_APIFY_TOKEN", "type": "string" },
            { "id": "a7", "name": "apifyRunUrl", "value": "https://api.apify.com/v2/acts/REEMPLAZA_APIFY_ACTOR_ID/run-sync-get-dataset-items", "type": "string" },
            { "id": "a8", "name": "openaiModel", "value": "gpt-4o-mini", "type": "string" },
            { "id": "a9", "name": "crmProvider", "value": "hubspot", "type": "string" },
            { "id": "a10", "name": "crmBaseUrl", "value": "https://api.hubapi.com", "type": "string" },
            { "id": "a11", "name": "crmToken", "value": "REEMPLAZA_HUBSPOT_TOKEN", "type": "string" },
            { "id": "a12", "name": "pipedriveBaseUrl", "value": "https://REEMPLAZA_TU_EMPRESA.pipedrive.com/api/v1", "type": "string" },
            { "id": "a13", "name": "pipedriveApiToken", "value": "REEMPLAZA_PIPEDRIVE_API_TOKEN", "type": "string" },
            { "id": "a14", "name": "enableCrmUpsert", "value": "false", "type": "string" },
            { "id": "a15", "name": "sheetsId", "value": "REEMPLAZA_SHEETS_ID", "type": "string" },
            { "id": "a16", "name": "slackWebhookUrl", "value": "https://hooks.example.com/services/REEMPLAZA_SLACK", "type": "string" },
            { "id": "a17", "name": "timezone", "value": "Europe/Madrid", "type": "string" }
          ]
        },
        "options": {}
      }
    },
    {
      "id": "fl-sample",
      "name": "Payload demo ICP",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [520, 420],
      "parameters": {
        "mode": "runOnceForAllItems",
        "language": "javaScript",
        "jsCode": "const cfg = $('Config Form Leads').first().json;\nreturn [{\n  json: {\n    jobTitles: 'CEO, Founder',\n    industryKeywords: 'marketing agency',\n    employeeRanges: '11-50',\n    location: 'Madrid',\n    batchLabel: cfg.batchLabel,\n    totalRecords: Number(cfg.totalRecords) || 50,\n    demoMode: String(cfg.demoMode) === 'true',\n    enableCompanyBrief: String(cfg.enableCompanyBrief) === 'true',\n    enableCrmUpsert: String(cfg.enableCrmUpsert) === 'true',\n    timezone: cfg.timezone || 'Europe/Madrid',\n    apifyToken: cfg.apifyToken,\n    apifyRunUrl: cfg.apifyRunUrl,\n    apifyActorId: cfg.apifyActorId,\n    sheetsId: cfg.sheetsId,\n    slackWebhookUrl: cfg.slackWebhookUrl,\n    crmProvider: cfg.crmProvider,\n    crmBaseUrl: cfg.crmBaseUrl,\n    crmToken: cfg.crmToken,\n    pipedriveBaseUrl: cfg.pipedriveBaseUrl,\n    pipedriveApiToken: cfg.pipedriveApiToken,\n    _generatedAt: new Date().toISOString()\n  }\n}];"
      }
    },
    {
      "id": "fl-if-demo-url",
      "name": "IF demoMode (URL)",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2,
      "position": [780, 420],
      "parameters": {
        "conditions": {
          "options": { "caseSensitive": true, "leftValue": "", "typeValidation": "strict" },
          "conditions": [
            {
              "id": "c-demo-url",
              "leftValue": "={{ String($json.demoMode) }}",
              "rightValue": "true",
              "operator": { "type": "string", "operation": "equals" }
            }
          ],
          "combinator": "and"
        }
      }
    },
    {
      "id": "fl-url-demo",
      "name": "URL Apollo (demo sin IA)",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [1040, 260],
      "parameters": {
        "mode": "runOnceForAllItems",
        "language": "javaScript",
        "jsCode": "const row = $input.first().json;\nconst q = encodeURIComponent([row.jobTitles, row.industryKeywords, row.location].filter(Boolean).join(' | '));\nconst apolloSearchUrl = 'https://app.apollo.io/#/people?qKeywords=' + q + '&demo=1';\nreturn [{ json: { ...row, apolloSearchUrl, urlSource: 'demo_template', urlValid: true } }];"
      }
    },
    {
      "id": "fl-prompt-url",
      "name": "Prompt Agente URL Apollo",
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [1040, 560],
      "parameters": {
        "mode": "manual",
        "duplicateItem": false,
        "includeOtherFields": true,
        "assignments": {
          "assignments": [
            {
              "id": "p1",
              "name": "aiPrompt",
              "value": "={{ \"Eres un generador de URLs de búsqueda de personas en Apollo.io. Devuelve SOLO una URL https que empiece por https://app.apollo.io/#/people. No inventes hosts. Usa estos filtros:\\njobTitles: \" + ($json.jobTitles || '') + \"\\nindustryKeywords: \" + ($json.industryKeywords || '') + \"\\nemployeeRanges: \" + ($json.employeeRanges || '') + \"\\nlocation: \" + ($json.location || '') + \"\\nEjemplo de forma: https://app.apollo.io/#/people?qKeywords=CEO%20marketing%20Madrid\" }}",
              "type": "string"
            }
          ]
        }
      }
    },
    {
      "id": "fl-agent-url",
      "name": "Agente IA URL Apollo",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "typeVersion": 1.7,
      "position": [1280, 560],
      "parameters": {
        "promptType": "define",
        "text": "={{ $json.aiPrompt }}",
        "options": {}
      }
    },
    {
      "id": "fl-model-url",
      "name": "Modelo OpenAI (URL)",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "typeVersion": 1.2,
      "position": [1280, 780],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4o-mini"
        },
        "options": {}
      }
    },
    {
      "id": "fl-parse-url",
      "name": "Parse URL Apollo (IA)",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [1520, 560],
      "parameters": {
        "mode": "runOnceForAllItems",
        "language": "javaScript",
        "jsCode": "const prev = $('Prompt Agente URL Apollo').first().json;\nconst out = String($input.first().json.output || $input.first().json.text || '').trim();\nconst m = out.match(/https:\\/\\/[^\\s\"'<>]+/i);\nlet apolloSearchUrl = m ? m[0].replace(/[),.;]+$/, '') : '';\nconst urlValid = /^https:\\/\\/app\\.apollo\\.io\\//i.test(apolloSearchUrl);\nif (!urlValid) apolloSearchUrl = '';\nreturn [{ json: { ...prev, apolloSearchUrl, urlSource: 'openai_agent', urlValid, aiRawUrl: out.slice(0, 500) } }];"
      }
    },
    {
      "id": "fl-merge-url",
      "name": "Merge rama URL",
      "type": "n8n-nodes-base.merge",
      "typeVersion": 3,
      "position": [1760, 420],
      "parameters": {
        "mode": "append"
      }
    },
    {
      "id": "fl-if-url-ok",
      "name": "IF URL Apollo válida",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2,
      "position": [2000, 420],
      "parameters": {
        "conditions": {
          "options": { "caseSensitive": true, "leftValue": "", "typeValidation": "loose" },
          "conditions": [
            {
              "id": "c-url-ok",
              "leftValue": "={{ $json.urlValid }}",
              "rightValue": true,
              "operator": { "type": "boolean", "operation": "true", "singleValue": true }
            }
          ],
          "combinator": "and"
        }
      }
    },
    {
      "id": "fl-slack-url-fail",
      "name": "Slack URL inválida",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [2260, 620],
      "parameters": {
        "method": "POST",
        "url": "={{ $json.slackWebhookUrl }}",
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={\n  \"text\": \"Logixb2b form leads · batch {{ $json.batchLabel }} · URL Apollo inválida. No se llamó a Apify. Revisa el Agente IA / demo. Europe/Madrid\"\n}",
        "options": {}
      }
    },
    {
      "id": "fl-if-demo-apify",
      "name": "IF demoMode (Apify)",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2,
      "position": [2260, 280],
      "parameters": {
        "conditions": {
          "options": { "caseSensitive": true, "leftValue": "", "typeValidation": "strict" },
          "conditions": [
            {
              "id": "c-demo-apify",
              "leftValue": "={{ String($json.demoMode) }}",
              "rightValue": "true",
              "operator": { "type": "string", "operation": "equals" }
            }
          ],
          "combinator": "and"
        }
      }
    },
    {
      "id": "fl-sim-leads",
      "name": "Simular leads demo (3)",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [2520, 160],
      "parameters": {
        "mode": "runOnceForAllItems",
        "language": "javaScript",
        "jsCode": "const row = $input.first().json;\nconst sample = [\n  { firstName: 'Ana', lastName: 'Lopez', email: 'ana.lopez@nortech-example.es', title: 'CEO', organizationName: 'NorTech SL', linkedinUrl: 'https://www.linkedin.com/in/example-ana', website: 'https://nortech-example.es', city: 'Madrid' },\n  { firstName: 'Bruno', lastName: 'Sanz', email: 'bruno.sanz@orbitsoft-example.es', title: 'Founder', organizationName: 'OrbitSoft B2B', linkedinUrl: 'https://www.linkedin.com/in/example-bruno', website: 'https://orbitsoft-example.es', city: 'Madrid' },\n  { firstName: 'Carla', lastName: 'Ruiz', email: 'carla.ruiz@plaindata-example.com', title: 'Co-Founder', organizationName: 'PlainData Inc', linkedinUrl: 'https://www.linkedin.com/in/example-carla', website: 'https://plaindata-example.com', city: 'Barcelona' }\n];\nreturn sample.map((p) => ({ json: {\n  ...p,\n  batchLabel: row.batchLabel,\n  apolloSearchUrl: row.apolloSearchUrl,\n  source: 'apollo_apify_demo',\n  sheetsId: row.sheetsId,\n  slackWebhookUrl: row.slackWebhookUrl,\n  timezone: row.timezone,\n  enableCompanyBrief: row.enableCompanyBrief,\n  enableCrmUpsert: row.enableCrmUpsert,\n  crmProvider: row.crmProvider,\n  crmBaseUrl: row.crmBaseUrl,\n  crmToken: row.crmToken,\n  pipedriveBaseUrl: row.pipedriveBaseUrl,\n  pipedriveApiToken: row.pipedriveApiToken,\n  demoMode: true\n}}));"
      }
    },
    {
      "id": "fl-http-apify",
      "name": "HTTP Apify run-sync-get-dataset-items",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [2520, 400],
      "parameters": {
        "method": "POST",
        "url": "={{ $json.apifyRunUrl }}",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            { "name": "Authorization", "value": "=Bearer {{ $json.apifyToken }}" },
            { "name": "Content-Type", "value": "application/json" }
          ]
        },
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={\n  \"searchUrl\": {{ JSON.stringify($json.apolloSearchUrl) }},\n  \"totalRecords\": {{ Number($json.totalRecords) || 50 }}\n}",
        "options": {
          "timeout": 300000
        }
      }
    },
    {
      "id": "fl-flatten-apify",
      "name": "Aplanar dataset Apify",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [2760, 400],
      "parameters": {
        "mode": "runOnceForAllItems",
        "language": "javaScript",
        "jsCode": "const meta = $('IF demoMode (Apify)').first().json;\nconst raw = $input.all().map((i) => i.json);\nlet rows = raw;\nif (raw.length === 1 && Array.isArray(raw[0])) rows = raw[0];\nif (raw.length === 1 && Array.isArray(raw[0].items)) rows = raw[0].items;\nconst max = Number(meta.totalRecords) || 50;\nreturn rows.slice(0, max).map((p) => ({\n  json: {\n    firstName: p.firstName || p.first_name || '',\n    lastName: p.lastName || p.last_name || '',\n    email: p.email || p.email_address || '',\n    title: p.title || p.headline || '',\n    organizationName: p.organizationName || (p.organization && p.organization.name) || p.company || '',\n    linkedinUrl: p.linkedinUrl || p.linkedin_url || '',\n    website: p.website || (p.organization && p.organization.website_url) || '',\n    city: p.city || p.present_raw_address || '',\n    batchLabel: meta.batchLabel,\n    apolloSearchUrl: meta.apolloSearchUrl,\n    source: 'apollo_apify',\n    sheetsId: meta.sheetsId,\n    slackWebhookUrl: meta.slackWebhookUrl,\n    timezone: meta.timezone,\n    enableCompanyBrief: meta.enableCompanyBrief,\n    enableCrmUpsert: meta.enableCrmUpsert,\n    crmProvider: meta.crmProvider,\n    crmBaseUrl: meta.crmBaseUrl,\n    crmToken: meta.crmToken,\n    pipedriveBaseUrl: meta.pipedriveBaseUrl,\n    pipedriveApiToken: meta.pipedriveApiToken,\n    demoMode: false\n  }\n}));"
      }
    },
    {
      "id": "fl-merge-leads",
      "name": "Merge leads demo/Apify",
      "type": "n8n-nodes-base.merge",
      "typeVersion": 3,
      "position": [3000, 280],
      "parameters": {
        "mode": "append"
      }
    },
    {
      "id": "fl-map",
      "name": "Mapear campos lead",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [3240, 280],
      "parameters": {
        "mode": "runOnceForEachItem",
        "language": "javaScript",
        "jsCode": "const j = $input.item.json;\nconst email = String(j.email || '').trim().toLowerCase();\nreturn [{\n  json: {\n    fecha: new Date().toISOString(),\n    batchLabel: j.batchLabel,\n    email,\n    hasEmail: Boolean(email),\n    firstName: j.firstName || '',\n    lastName: j.lastName || '',\n    title: j.title || '',\n    company: j.organizationName || j.company || '',\n    linkedin: j.linkedinUrl || '',\n    website: j.website || '',\n    city: j.city || '',\n    companyBrief: j.companyBrief || '',\n    source: j.source || 'apollo_apify',\n    apolloSearchUrl: j.apolloSearchUrl || '',\n    sheetsId: j.sheetsId,\n    slackWebhookUrl: j.slackWebhookUrl,\n    timezone: j.timezone || 'Europe/Madrid',\n    enableCompanyBrief: j.enableCompanyBrief,\n    enableCrmUpsert: j.enableCrmUpsert,\n    crmProvider: j.crmProvider,\n    crmBaseUrl: j.crmBaseUrl,\n    crmToken: j.crmToken,\n    pipedriveBaseUrl: j.pipedriveBaseUrl,\n    pipedriveApiToken: j.pipedriveApiToken,\n    complianceFlag: 'rgpd_interes_legitimo_b2b_form_leads_apollo_apify'\n  }\n}];"
      }
    },
    {
      "id": "fl-if-email",
      "name": "IF tiene email",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2,
      "position": [3480, 280],
      "parameters": {
        "conditions": {
          "options": { "caseSensitive": true, "leftValue": "", "typeValidation": "loose" },
          "conditions": [
            {
              "id": "c-email",
              "leftValue": "={{ $json.hasEmail }}",
              "rightValue": true,
              "operator": { "type": "boolean", "operation": "true", "singleValue": true }
            }
          ],
          "combinator": "and"
        }
      }
    },
    {
      "id": "fl-skip-no-email",
      "name": "Skip sin email",
      "type": "n8n-nodes-base.noOp",
      "typeVersion": 1,
      "position": [3720, 480],
      "parameters": {}
    },
    {
      "id": "fl-if-brief",
      "name": "IF enableCompanyBrief",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2,
      "position": [3720, 200],
      "parameters": {
        "conditions": {
          "options": { "caseSensitive": true, "leftValue": "", "typeValidation": "strict" },
          "conditions": [
            {
              "id": "c-brief",
              "leftValue": "={{ String($json.enableCompanyBrief) }}",
              "rightValue": "true",
              "operator": { "type": "string", "operation": "equals" }
            }
          ],
          "combinator": "and"
        }
      }
    },
    {
      "id": "fl-prompt-brief",
      "name": "Prompt Agente brief empresa",
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [3960, 80],
      "parameters": {
        "mode": "manual",
        "duplicateItem": false,
        "includeOtherFields": true,
        "assignments": {
          "assignments": [
            {
              "id": "b1",
              "name": "aiPrompt",
              "value": "={{ \"Escribe en español un companyBrief de 2–3 frases para outbound B2B. No inventes facturación ni headcount. Empresa: \" + ($json.company || '') + \". Web: \" + ($json.website || '') + \". Ciudad: \" + ($json.city || '') + \". Cargo contacto: \" + ($json.title || '') + \". Solo texto plano.\" }}",
              "type": "string"
            }
          ]
        }
      }
    },
    {
      "id": "fl-agent-brief",
      "name": "Agente IA companyBrief",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "typeVersion": 1.7,
      "position": [4200, 80],
      "parameters": {
        "promptType": "define",
        "text": "={{ $json.aiPrompt }}",
        "options": {}
      }
    },
    {
      "id": "fl-model-brief",
      "name": "Modelo OpenAI (brief)",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "typeVersion": 1.2,
      "position": [4200, 300],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4o-mini"
        },
        "options": {}
      }
    },
    {
      "id": "fl-apply-brief",
      "name": "Aplicar companyBrief",
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [4440, 80],
      "parameters": {
        "mode": "manual",
        "duplicateItem": false,
        "includeOtherFields": true,
        "assignments": {
          "assignments": [
            {
              "id": "c1",
              "name": "companyBrief",
              "value": "={{ ($json.output || $json.text || $json.companyBrief || '').toString().slice(0, 600) }}",
              "type": "string"
            }
          ]
        }
      }
    },
    {
      "id": "fl-brief-skip",
      "name": "Sin brief (passthrough)",
      "type": "n8n-nodes-base.noOp",
      "typeVersion": 1,
      "position": [3960, 280],
      "parameters": {}
    },
    {
      "id": "fl-merge-brief",
      "name": "Merge brief",
      "type": "n8n-nodes-base.merge",
      "typeVersion": 3,
      "position": [4680, 200],
      "parameters": {
        "mode": "append"
      }
    },
    {
      "id": "fl-sheets",
      "name": "Append Sheets Leads_Formulario",
      "type": "n8n-nodes-base.googleSheets",
      "typeVersion": 4.5,
      "position": [4920, 200],
      "parameters": {
        "operation": "append",
        "documentId": {
          "__rl": true,
          "value": "={{ $json.sheetsId }}",
          "mode": "id"
        },
        "sheetName": {
          "__rl": true,
          "value": "Leads_Formulario",
          "mode": "name"
        },
        "columns": {
          "mappingMode": "defineBelow",
          "value": {
            "fecha": "={{ $now.setZone('Europe/Madrid').toFormat('yyyy-MM-dd HH:mm') }}",
            "batchLabel": "={{ $json.batchLabel }}",
            "email": "={{ $json.email }}",
            "firstName": "={{ $json.firstName }}",
            "lastName": "={{ $json.lastName }}",
            "title": "={{ $json.title }}",
            "company": "={{ $json.company }}",
            "linkedin": "={{ $json.linkedin }}",
            "website": "={{ $json.website }}",
            "city": "={{ $json.city }}",
            "companyBrief": "={{ $json.companyBrief }}",
            "source": "={{ $json.source }}",
            "complianceFlag": "={{ $json.complianceFlag }}"
          }
        },
        "options": {}
      }
    },
    {
      "id": "fl-if-crm",
      "name": "IF enableCrmUpsert",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2,
      "position": [5160, 200],
      "parameters": {
        "conditions": {
          "options": { "caseSensitive": true, "leftValue": "", "typeValidation": "strict" },
          "conditions": [
            {
              "id": "c-crm",
              "leftValue": "={{ String($('Merge brief').item.json.enableCrmUpsert) }}",
              "rightValue": "true",
              "operator": { "type": "string", "operation": "equals" }
            }
          ],
          "combinator": "and"
        }
      }
    },
    {
      "id": "fl-crm-upsert",
      "name": "Upsert CRM HubSpot/Pipedrive",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [5400, 80],
      "parameters": {
        "method": "POST",
        "url": "={{ $('Merge brief').item.json.crmProvider === 'pipedrive' ? ($('Merge brief').item.json.pipedriveBaseUrl + '/persons') : ($('Merge brief').item.json.crmBaseUrl + '/crm/v3/objects/contacts') }}",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "={{ $('Merge brief').item.json.crmProvider === 'pipedrive' ? '' : ('Bearer ' + $('Merge brief').item.json.crmToken) }}"
            },
            { "name": "Content-Type", "value": "application/json" }
          ]
        },
        "sendQuery": true,
        "queryParameters": {
          "parameters": [
            {
              "name": "api_token",
              "value": "={{ $('Merge brief').item.json.crmProvider === 'pipedrive' ? $('Merge brief').item.json.pipedriveApiToken : '' }}"
            }
          ]
        },
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={{ (() => { const j = $('Merge brief').item.json; return j.crmProvider === 'pipedrive' ? { name: ((j.firstName||'') + ' ' + (j.lastName||'')).trim(), email: [{ value: j.email, primary: true }] } : { properties: { email: j.email, firstname: j.firstName, lastname: j.lastName, jobtitle: j.title, company: j.company, lead_source: 'form_inteligente_apollo_apify' } }; })() }}",
        "options": {}
      }
    },
    {
      "id": "fl-crm-skip",
      "name": "CRM off (passthrough)",
      "type": "n8n-nodes-base.noOp",
      "typeVersion": 1,
      "position": [5400, 320],
      "parameters": {}
    },
    {
      "id": "fl-merge-crm",
      "name": "Merge CRM",
      "type": "n8n-nodes-base.merge",
      "typeVersion": 3,
      "position": [5640, 200],
      "parameters": {
        "mode": "append"
      }
    },
    {
      "id": "fl-slack-ok",
      "name": "Slack resumen lote OK",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [5880, 200],
      "parameters": {
        "method": "POST",
        "url": "={{ $('Merge brief').item.json.slackWebhookUrl }}",
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={\n  \"text\": \"Logixb2b form leads · batch {{ $('Merge brief').item.json.batchLabel }} · lead {{ $('Merge brief').item.json.email }} · {{ $('Merge brief').item.json.company }} · source {{ $('Merge brief').item.json.source }} · Sheets Leads_Formulario · Europe/Madrid\"\n}",
        "options": {}
      }
    }
  ],
  "connections": {
    "Manual Trigger form leads": {
      "main": [[{ "node": "Config Form Leads", "type": "main", "index": 0 }]]
    },
    "Config Form Leads": {
      "main": [[{ "node": "Payload demo ICP", "type": "main", "index": 0 }]]
    },
    "Payload demo ICP": {
      "main": [[{ "node": "IF demoMode (URL)", "type": "main", "index": 0 }]]
    },
    "IF demoMode (URL)": {
      "main": [
        [{ "node": "URL Apollo (demo sin IA)", "type": "main", "index": 0 }],
        [{ "node": "Prompt Agente URL Apollo", "type": "main", "index": 0 }]
      ]
    },
    "URL Apollo (demo sin IA)": {
      "main": [[{ "node": "Merge rama URL", "type": "main", "index": 0 }]]
    },
    "Prompt Agente URL Apollo": {
      "main": [[{ "node": "Agente IA URL Apollo", "type": "main", "index": 0 }]]
    },
    "Modelo OpenAI (URL)": {
      "ai_languageModel": [[{ "node": "Agente IA URL Apollo", "type": "ai_languageModel", "index": 0 }]]
    },
    "Agente IA URL Apollo": {
      "main": [[{ "node": "Parse URL Apollo (IA)", "type": "main", "index": 0 }]]
    },
    "Parse URL Apollo (IA)": {
      "main": [[{ "node": "Merge rama URL", "type": "main", "index": 1 }]]
    },
    "Merge rama URL": {
      "main": [[{ "node": "IF URL Apollo válida", "type": "main", "index": 0 }]]
    },
    "IF URL Apollo válida": {
      "main": [
        [{ "node": "IF demoMode (Apify)", "type": "main", "index": 0 }],
        [{ "node": "Slack URL inválida", "type": "main", "index": 0 }]
      ]
    },
    "IF demoMode (Apify)": {
      "main": [
        [{ "node": "Simular leads demo (3)", "type": "main", "index": 0 }],
        [{ "node": "HTTP Apify run-sync-get-dataset-items", "type": "main", "index": 0 }]
      ]
    },
    "Simular leads demo (3)": {
      "main": [[{ "node": "Merge leads demo/Apify", "type": "main", "index": 0 }]]
    },
    "HTTP Apify run-sync-get-dataset-items": {
      "main": [[{ "node": "Aplanar dataset Apify", "type": "main", "index": 0 }]]
    },
    "Aplanar dataset Apify": {
      "main": [[{ "node": "Merge leads demo/Apify", "type": "main", "index": 1 }]]
    },
    "Merge leads demo/Apify": {
      "main": [[{ "node": "Mapear campos lead", "type": "main", "index": 0 }]]
    },
    "Mapear campos lead": {
      "main": [[{ "node": "IF tiene email", "type": "main", "index": 0 }]]
    },
    "IF tiene email": {
      "main": [
        [{ "node": "IF enableCompanyBrief", "type": "main", "index": 0 }],
        [{ "node": "Skip sin email", "type": "main", "index": 0 }]
      ]
    },
    "IF enableCompanyBrief": {
      "main": [
        [{ "node": "Prompt Agente brief empresa", "type": "main", "index": 0 }],
        [{ "node": "Sin brief (passthrough)", "type": "main", "index": 0 }]
      ]
    },
    "Prompt Agente brief empresa": {
      "main": [[{ "node": "Agente IA companyBrief", "type": "main", "index": 0 }]]
    },
    "Modelo OpenAI (brief)": {
      "ai_languageModel": [[{ "node": "Agente IA companyBrief", "type": "ai_languageModel", "index": 0 }]]
    },
    "Agente IA companyBrief": {
      "main": [[{ "node": "Aplicar companyBrief", "type": "main", "index": 0 }]]
    },
    "Aplicar companyBrief": {
      "main": [[{ "node": "Merge brief", "type": "main", "index": 0 }]]
    },
    "Sin brief (passthrough)": {
      "main": [[{ "node": "Merge brief", "type": "main", "index": 1 }]]
    },
    "Merge brief": {
      "main": [[{ "node": "Append Sheets Leads_Formulario", "type": "main", "index": 0 }]]
    },
    "Append Sheets Leads_Formulario": {
      "main": [[{ "node": "IF enableCrmUpsert", "type": "main", "index": 0 }]]
    },
    "IF enableCrmUpsert": {
      "main": [
        [{ "node": "Upsert CRM HubSpot/Pipedrive", "type": "main", "index": 0 }],
        [{ "node": "CRM off (passthrough)", "type": "main", "index": 0 }]
      ]
    },
    "Upsert CRM HubSpot/Pipedrive": {
      "main": [[{ "node": "Merge CRM", "type": "main", "index": 0 }]]
    },
    "CRM off (passthrough)": {
      "main": [[{ "node": "Merge CRM", "type": "main", "index": 1 }]]
    },
    "Merge CRM": {
      "main": [[{ "node": "Slack resumen lote OK", "type": "main", "index": 0 }]]
    }
  }
}
