{
  "nodes": [
    {
      "id": "e4c5e020-4e1f-4c77-84ad-50c18097f14c",
      "name": "ICP Lead Extractor Form",
      "type": "n8n-nodes-base.formTrigger",
      "position": [
        1168,
        768
      ],
      "parameters": {
        "options": {
          "buttonLabel": "Leads extrahieren"
        },
        "formTitle": "LinkedIn ICP Lead Extraktor",
        "formFields": {
          "values": [
            {
              "fieldName": "LinkedIn Post URL",
              "fieldLabel": "LinkedIn Post URL",
              "placeholder": "https://www.linkedin.com/posts/... ",
              "requiredField": true
            },
            {
              "fieldName": "Target Job Titles",
              "fieldType": "checkbox",
              "fieldLabel": "Ziel Job Titel",
              "fieldOptions": {
                "values": [
                  {
                    "option": "CEO"
                  },
                  {
                    "option": "Founder"
                  },
                  {
                    "option": "Co-Founder"
                  },
                  {
                    "option": "CMO"
                  },
                  {
                    "option": "COO"
                  },
                  {
                    "option": "CTO"
                  },
                  {
                    "option": "CFO"
                  },
                  {
                    "option": "CRO"
                  },
                  {
                    "option": "CPO"
                  },
                  {
                    "option": "VP Marketing"
                  },
                  {
                    "option": "VP Sales"
                  },
                  {
                    "option": "VP Engineering"
                  },
                  {
                    "option": "Head of Marketing"
                  },
                  {
                    "option": "Head of Sales"
                  },
                  {
                    "option": "Head of Growth"
                  }
                ]
              },
              "requiredField": true
            },
            {
              "fieldName": "Target Countries",
              "fieldType": "checkbox",
              "fieldLabel": "Ziel Länder",
              "fieldOptions": {
                "values": [
                  {
                    "option": "Vereinigte Staaten"
                  },
                  {
                    "option": "Vereinigtes Königreich"
                  },
                  {
                    "option": "Deutschland"
                  },
                  {
                    "option": "Frankreich"
                  },
                  {
                    "option": "Spanien"
                  },
                  {
                    "option": "Niederlande"
                  },
                  {
                    "option": "Kanada"
                  },
                  {
                    "option": "Australien"
                  },
                  {
                    "option": "Irland"
                  },
                  {
                    "option": "Singapur"
                  }
                ]
              },
              "requiredField": true
            }
          ]
        },
        "responseMode": "lastNode",
        "formDescription": "Extrahieren Sie LinkedIn-Profile, die Ihrem Ziel-ICP aus den Kommentaren eines Beitrags entsprechen."
      },
      "typeVersion": 2.4
    },
    {
      "id": "7cb7d4ea-a278-447c-987d-51c8ebd8655b",
      "name": "Remove Duplicate Commenters",
      "type": "n8n-nodes-base.code",
      "position": [
        1904,
        112
      ],
      "parameters": {
        "jsCode": "// Deduplicate commenters by profile URL\nconst seen = new Set();\nconst uniqueCommenters = [];\n\nfor (const item of items) {\n  const profileUrl = item.json?.author?.profile_url;\n  \n  if (profileUrl && !seen.has(profileUrl)) {\n    seen.add(profileUrl);\n    uniqueCommenters.push({\n      json: {\n        name: item.json.author.name,\n        profile_url: profileUrl\n      }\n    });\n  }\n}\n\nreturn uniqueCommenters;"
      },
      "typeVersion": 2
    },
    {
      "id": "4c7e03a5-6658-434f-aca4-fe97ad8fc0bd",
      "name": "Scrape LinkedIn Comments",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1904,
        784
      ],
      "parameters": {
        "url": "https://api.apify.com/v2/acts/apimaestro~linkedin-post-comments-replies-engagements-scraper-no-cookies/run-sync-get-dataset-items",
        "method": "POST",
        "options": {
          "timeout": 600000
        },
        "jsonBody": "={\n    \"postIds\": [\"{ { $json.postUrl } }\"],\n    \"page_number\": { { $json.pageNumber } },\n    \"sortOrder\": \"most recent\",\n    \"limit\": 100\n}",
        "sendBody": true,
        "specifyBody": "json",
        "authentication": "predefinedCredentialType",
        "nodeCredentialType": "apifyApi"
      },
      "typeVersion": 4.3
    },
    {
      "id": "feb1028d-c4f1-4ca0-b881-49dc28ca5ba0",
      "name": "Preserve ICP Kriterien",
      "type": "n8n-nodes-base.code",
      "position": [
        2816,
        208
      ],
      "parameters": {
        "mode": "runOnceForEachItem",
        "jsCode": "// Preserve the _formData from the input through the enrichment\nconst enrichedProfile = $json;\nconst originalData = $('Loop Through Profiles').item.json;\n\n// Combine enriched profile with preserved form data\nreturn {\n  json: {\n    ...enrichedProfile,\n    _formData: originalData._formData\n  }\n};"
      },
      "typeVersion": 2
    },
    {
      "id": "4c7e03a5-6658-434f-aca4-fe97ad8fc0bd",
      "name": "Enrich LinkedIn Profile",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        2576,
        208
      ],
      "parameters": {
        "url": "https://api.apify.com/v2/acts/apimaestro~linkedin-profile-detail/run-sync-get-dataset-items",
        "method": "POST",
        "options": {
          "timeout": 600000
        },
        "jsonBody": "={\n    \"username\": \"{ { $json.profile_url } }\",\n    \"includeEmail\": false\n}",
        "sendBody": true,
        "specifyBody": "json",
        "authentication": "predefinedCredentialType",
        "nodeCredentialType": "apifyApi"
      },
      "typeVersion": 4.3
    },
    {
      "id": "fc10825e-4a95-4e4d-aaf8-632e9fc8abb4",
      "name": "Filter by ICP Kriterien",
      "type": "n8n-nodes-base.code",
      "position": [
        3104,
        96
      ],
      "parameters": {
        "jsCode": "// This node runs when the loop is complete\n// It receives ALL enriched profiles from the loop\n\n// Get the stored form data from the first item\nconst firstItem = items[0]?.json;\nif (!firstItem || !firstItem._formData) {\n  throw new Error('Form data not found in items');\n}\n\nconst selectedTitles = firstItem._formData.selectedTitles || [];\nconst selectedCountries = firstItem._formData.selectedCountries || [];\n\n// Job title mapping with comprehensive synonyms\nconst titleMapping = {\n  'CEO': ['CEO', 'Chief Executive Officer', 'Chief Exec'],\n  'Founder': ['Founder', 'Co-Founder', 'Cofounder', 'Co Founder'],\n  'Co-Founder': ['Co-Founder', 'Cofounder', 'Founder', 'Co Founder'],\n  'CMO': ['CMO', 'Chief Marketing Officer'],\n  'COO': ['COO', 'Chief Operating Officer', 'Chief Operations Officer'],\n  'CTO': ['CTO', 'Chief Technology Officer', 'Chief Technical Officer'],\n  'CFO': ['CFO', 'Chief Financial Officer'],\n  'CRO': ['CRO', 'Chief Revenue Officer'],\n  'CPO': ['CPO', 'Chief Product Officer'],\n  'VP Marketing': ['VP Marketing', 'Vice President Marketing', 'VP of Marketing', 'Vice President of Marketing'],\n  'VP Sales': ['VP Sales', 'Vice President Sales', 'VP of Sales', 'Vice President of Sales'],\n  'VP Engineering': ['VP Engineering', 'Vice President Engineering', 'VP of Engineering', 'Vice President of Engineering'],\n  'Head of Marketing': ['Head of Marketing', 'Marketing Head'],\n  'Head of Sales': ['Head of Sales', 'Sales Head'],\n  'Head of Growth': ['Head of Growth', 'Growth Head']\n};\n\n// Country mapping with localized names\nconst countryMapping = {\n  'United States': ['United States', 'USA', 'US', 'America'],\n  'United Kingdom': ['United Kingdom', 'UK', 'Britain', 'Great Britain', 'England'],\n  'Germany': ['Germany', 'Deutschland'],\n  'France': ['France', 'République française'],\n  'Spain': ['Spain', 'España'],\n  'Netherlands': ['Netherlands', 'Nederland', 'Holland'],\n  'Canada': ['Canada'],\n  'Australia': ['Australia'],\n  'Ireland': ['Ireland', 'Éire'],\n  'Singapore': ['Singapore']\n};\n\n// Build expanded title list\nconst expandedTitles = [];\nfor (const title of selectedTitles) {\n  if (titleMapping[title]) {\n    expandedTitles.push(...titleMapping[title]);\n  }\n}\n\n// Build expanded country list\nconst expandedCountries = [];\nfor (const country of selectedCountries) {\n  if (countryMapping[country]) {\n    expandedCountries.push(...countryMapping[country]);\n  }\n}\n\n// Process all enriched profiles\nconst matchedProfiles = [];\n\nfor (const item of items) {\n  const profile = item.json;\n  const basicInfo = profile.basic_info || {};\n  const experience = profile.experience || [];\n  \n  // Extract job titles from current roles (up to 3)\n  const jobTitles = [];\n  for (let i = 0; i < Math.min(3, experience.length); i++) {\n    const exp = experience[i];\n    if (exp && exp.title) {\n      jobTitles.push(exp.title);\n    }\n  }\n  \n  // Also check headline\n  if (basicInfo.headline) {\n    jobTitles.push(basicInfo.headline);\n  }\n  \n  // Extract location/country - combine all sources\n  const locationParts = [];\n  \n  // From basic_info.location\n  if (basicInfo.location) {\n    if (basicInfo.location.country) locationParts.push(basicInfo.location.country);\n    if (basicInfo.location.full) locationParts.push(basicInfo.location.full);\n    if (basicInfo.location.city) locationParts.push(basicInfo.location.city);\n  }\n  \n  // From experience locations\n  for (let i = 0; i < Math.min(3, experience.length); i++) {\n    const exp = experience[i];\n    if (exp && exp.location) {\n      locationParts.push(exp.location);\n    }\n  }\n  \n  const location = locationParts.join(' ');\n  \n  // Normalize for case-insensitive matching\n  const jobTitlesLower = jobTitles.map(t => String(t).toLowerCase());\n  const locationLower = String(location).toLowerCase();\n  \n  // Check job title match\n  let titleMatch = false;\n  let matchedTitle = '';\n  for (const title of expandedTitles) {\n    const titleLower = title.toLowerCase();\n    for (const jobTitle of jobTitlesLower) {\n      if (jobTitle.includes(titleLower)) {\n        titleMatch = true;\n        matchedTitle = title;\n        break;\n      }\n    }\n    if (titleMatch) break;\n  }\n  \n  // Check country match\n  let countryMatch = false;\n  let matchedCountry = '';\n  for (const country of expandedCountries) {\n    if (locationLower.includes(country.toLowerCase())) {\n      countryMatch = true;\n      matchedCountry = country;\n      break;\n    }\n  }\n  \n  // Add to matched profiles if both match\n  if (titleMatch && countryMatch) {\n    matchedProfiles.push({\n      json: {\n        fullName: basicInfo.fullname || ((basicInfo.first_name || '') + ' ' + (basicInfo.last_name || '')).trim() || '',\n        profileUrl: basicInfo.profile_url || '',\n        jobTitle: jobTitles[0] || '',\n        jobTitles: jobTitles,\n        location: basicInfo.location?.full || basicInfo.location?.country || '',\n        matchedJobTitle: matchedTitle,\n        matchedCountry: matchedCountry,\n        headline: basicInfo.headline || '',\n        currentCompany: basicInfo.current_company || '',\n        email: basicInfo.email || null\n      }\n    });\n  }\n}\n\nreturn matchedProfiles;"
      },
      "typeVersion": 2
    },
    {
      "id": "2315ee1a-66d7-4bb2-89db-418c4e3957df",
      "name": "Aggregate Matched Leads",
      "type": "n8n-nodes-base.aggregate",
      "position": [
        3328,
        96
      ],
      "parameters": {
        "options": {},
        "aggregate": "aggregateAllItemData",
        "destinationFieldName": "leads"
      },
      "typeVersion": 1
    },
    {
      "id": "31d46ff2-8fc1-4fee-b64b-5b038b9add84",
      "name": "Format Leads for CSV",
      "type": "n8n-nodes-base.code",
      "position": [
        3552,
        96
      ],
      "parameters": {
        "jsCode": "// Flatten the aggregated leads for CSV export\nconst leads = $json.leads || [];\n\nif (leads.length === 0) {\n  return [{\n    json: {\n      message: 'Keine passenden Profile gefunden'\n    }\n  }];\n}\n\n// Flatten each lead into CSV-ready format\nconst flattenedLeads = leads.map(lead => ({\n  json: {\n    'Vollständiger Name': lead.fullName || '',\n    'LinkedIn Profil URL': lead.profileUrl || '',\n    'Job Titel': lead.jobTitle || '',\n    'Alle Job Titel': Array.isArray(lead.jobTitles) ? lead.jobTitles.join(', ') : (lead.jobTitles || ''),\n    'Standort': lead.location || '',\n    'Übereinstimmender Job Titel': lead.matchedJobTitle || '',\n    'Übereinstimmendes Land': lead.matchedCountry || '',\n    'Überschrift': lead.headline || '',\n    'Aktuelles Unternehmen': lead.currentCompany || '',\n    'E-Mail': lead.email || ''\n  }\n}));\n\nreturn flattenedLeads;"
      },
      "typeVersion": 2
    },
    {
      "id": "3b52e1e3-d4e0-44f6-96ce-cc6c7b2258da",
      "name": "Export to CSV",
      "type": "n8n-nodes-base.convertToFile",
      "position": [
        3776,
        96
      ],
      "parameters": {
        "options": {
          "fileName": "=linkedin_icp_leads_{ { $now.toFormat('yyyy-MM-dd_HHmm') } }.csv"
        }
      },
      "typeVersion": 1.1
    }
  ],
  "connections": {
    "Loop Through Pages": {
      "main": [
        [
          {
            "node": "Remove Duplicate Commenters",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Scrape LinkedIn Comments",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Filter by ICP Kriterien": {
      "main": [
        [
          {
            "node": "Aggregate Matched Leads",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Aggregate Matched Leads": {
      "main": [
        [
          {
            "node": "Format Leads for CSV",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Preserve ICP Kriterien": {
      "main": [
        [
          {
            "node": "Loop Through Profiles",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Loop Through Profiles": {
      "main": [
        [
          {
            "node": "Filter by ICP Kriterien",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Enrich LinkedIn Profile",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Enrich LinkedIn Profile": {
      "main": [
        [
          {
            "node": "Preserve ICP Kriterien",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}