AutomationFlowsWeb Scraping › Personalized Sales Outreach From Linkedin Job Signals with Apify & Google Gemini

Personalized Sales Outreach From Linkedin Job Signals with Apify & Google Gemini

ByIntuz @intuz on n8n.io

Community nodes are used in this workflow. B2B Sales Teams & SDRs Recruitment Agencies & Tech Recruiters Startup Founders Growth Marketing Teams Scrape Hiring Signals: The workflow starts by using an Apify scraper to find companies actively hiring for specific roles on LinkedIn…

Event trigger★★★★★ complexityAI-powered47 nodesGoogle SheetsGoogle Gemini ChatOutput Parser Structured@Apify/N8N Nodes ApifyHTTP RequestChain Llm
Web Scraping Trigger: Event Nodes: 47 Complexity: ★★★★★ AI nodes: yes Added:

This workflow corresponds to n8n.io template #9219 — we link there as the canonical source.

This workflow follows the Apifyn8N Nodes Apify → Google Sheets recipe pattern — see all workflows that pair these two integrations.

The workflow JSON

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

Download .json
{
  "id": "6ZDejfbyr1msa2zv",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "Automate Sales Outreach with LinkedIn Job Signals, Apify, Apollo.io & Google Gemini",
  "tags": [],
  "nodes": [
    {
      "id": "0fd7b446-8b69-4fb4-b79e-f69fbe4082ab",
      "name": "Update Sheet with Email",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        2560,
        1008
      ],
      "parameters": {
        "columns": {
          "value": {
            "Email": "={{ $('Filter for Batching').item.json.Email }}",
            "Subject": "={{ $json.output.subject }}",
            "Email Body": "={{ $json.output.email_body }}"
          },
          "schema": [
            {
              "id": "First Name",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "First Name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Last Name",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Last Name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Occupation",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Occupation",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Company",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Company",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "LinkedIn Url",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "LinkedIn Url",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Company LinkedIn Url",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Company LinkedIn Url",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Company URL",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Company URL",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Location",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Location",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Domain",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Domain",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Email",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Email",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Company Description",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Company Description",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Employee Count",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Employee Count",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Job Title",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Job Title",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Subject",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Subject",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Email Body",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Email Body",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "row_number",
              "type": "string",
              "display": true,
              "removed": true,
              "readOnly": true,
              "required": false,
              "displayName": "row_number",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "Email"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "update",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/YOUR_AWS_SECRET_KEY_HERE_gdo/edit#gid=0",
          "cachedResultName": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "YOUR_AWS_SECRET_KEY_HERE_gdo",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/YOUR_AWS_SECRET_KEY_HERE_gdo/edit?usp=drivesdk",
          "cachedResultName": "LinkedIn Lead Gen"
        }
      },
      "typeVersion": 4
    },
    {
      "id": "12d544fc-86d7-4cbf-9be7-ed6d4730dbdf",
      "name": "Google Gemini Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
      "position": [
        1936,
        1376
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 1
    },
    {
      "id": "78b63764-9948-40ca-be63-f188ff8faeba",
      "name": "Structured Output Parser",
      "type": "@n8n/n8n-nodes-langchain.outputParserStructured",
      "position": [
        2496,
        1376
      ],
      "parameters": {
        "jsonSchemaExample": "{\n  \"subject\": \"A short, catchy, question-based subject line\",\n  \"email_body\": \"The full email body, 100-120 words, without any salutation or sign-off.\"\n}"
      },
      "typeVersion": 1.3
    },
    {
      "id": "6e685361-565d-4dc6-9149-a6c2b23fe2c3",
      "name": "When clicking \u2018Execute workflow\u2019",
      "type": "n8n-nodes-base.manualTrigger",
      "position": [
        -816,
        160
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "9af7695c-fb5d-4a23-b7e3-8d26a821b4d1",
      "name": "Remove Duplicates",
      "type": "n8n-nodes-base.removeDuplicates",
      "position": [
        -768,
        496
      ],
      "parameters": {
        "compare": "selectedFields",
        "options": {
          "removeOtherFields": false,
          "disableDotNotation": false
        },
        "fieldsToCompare": "companyName"
      },
      "typeVersion": 2
    },
    {
      "id": "c1348833-1b28-4270-ae53-4dbcfc93251e",
      "name": "Run the LinkedIn Job Scraper",
      "type": "@apify/n8n-nodes-apify.apify",
      "position": [
        -432,
        96
      ],
      "parameters": {
        "memory": 4096,
        "actorId": {
          "__rl": true,
          "mode": "list",
          "value": "hKByXkMQaC5Qt9UMN",
          "cachedResultUrl": "https://console.apify.com/actors/hKByXkMQaC5Qt9UMN/input",
          "cachedResultName": "Linkedin Jobs Scraper - PPR (curious_coder/linkedin-jobs-scraper)"
        },
        "timeout": {},
        "customBody": "{\n  \"count\": 100,\n  \"scrapeCompany\": true,\n  \"urls\": [\n    \"https://www.linkedin.com/jobs/search-results/?distance=25&f_TPR=r86400&geoId=103644278&keywords=ML%20Engineer&origin=SEMANTIC_SEARCH_HISTORY\"\n  ]\n}"
      },
      "typeVersion": 1
    },
    {
      "id": "5e36853c-5e15-42ac-9c7e-95c60aadf9da",
      "name": "Get dataset Items",
      "type": "@apify/n8n-nodes-apify.apify",
      "position": [
        96,
        160
      ],
      "parameters": {
        "limit": 110,
        "offset": {},
        "resource": "Datasets",
        "datasetId": "={{ $json.defaultDatasetId }}"
      },
      "typeVersion": 1
    },
    {
      "id": "92470dd9-7f01-4795-b36a-8d1553a12e80",
      "name": "Checks Company Size < 250",
      "type": "n8n-nodes-base.if",
      "position": [
        592,
        208
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "ed72c7e6-2a1f-4c8e-b87c-7ab53ea8f356",
              "operator": {
                "type": "number",
                "operation": "lt"
              },
              "leftValue": "={{ $json.companyEmployeesCount }}",
              "rightValue": 250
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "9469d083-1393-4661-bc1a-2626be76b3af",
      "name": "Removes HR Related Industry",
      "type": "n8n-nodes-base.if",
      "position": [
        -400,
        496
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "or",
          "conditions": [
            {
              "id": "cd695047-a0f4-4058-b83b-339c5fe77a9c",
              "operator": {
                "type": "string",
                "operation": "notContains"
              },
              "leftValue": "={{ $json.industries }}",
              "rightValue": "Human Resources"
            },
            {
              "id": "7b9d94db-da9c-4b94-8961-0827f5175f9c",
              "operator": {
                "type": "string",
                "operation": "notContains"
              },
              "leftValue": "={{ $json.industries }}",
              "rightValue": "Staffing and Recruiting"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "13ccb5b9-221b-4be6-ba7c-02c53205fc63",
      "name": "Prepare Final Company Details",
      "type": "n8n-nodes-base.code",
      "position": [
        112,
        496
      ],
      "parameters": {
        "jsCode": "// n8n Function Node\n// Keep only required fields + extract clean domain from companyWebsite\n// Wrap output in \"company\" wrapper\n\nreturn items.map(item => {\n  const data = item.json;\n\n  let domain = null;\n  if (data.companyWebsite) {\n    let website = data.companyWebsite.trim();\n\n    // If no protocol, prepend http://\n    if (!/^https?:\\/\\//i.test(website)) {\n      website = \"http://\" + website;\n    }\n\n    try {\n      const parsedUrl = new URL(website);\n      domain = parsedUrl.hostname.replace(/^www\\./, \"\"); // remove \"www.\"\n    } catch (err) {\n      // Fallback: strip query/hash manually\n      domain = website\n        .replace(/^(https?:\\/\\/)?(www\\.)?/, \"\")\n        .split(/[/?#]/)[0]; // take only domain part\n    }\n  }\n\n  return {\n    json: {\n      company: { // \ud83d\udc48 wrapper added\n        companyName: data.companyName || null,\n        companyLinkedInUrl: data.companyLinkedInUrl || data.companyLinkedinUrl || null,\n        companyWebsite: data.companyWebsite || null,\n        industries: data.industries || null,\n        location: data.location || null,\n        employeeCount: data.companyEmployeesCount || null,\n        jobTitle: data.jobTitle || data.title || null,\n        companyDescription: data.companyDescription || null,\n        domain: domain\n      }\n    }\n  };\n});\n"
      },
      "typeVersion": 2
    },
    {
      "id": "43d308cf-516a-4acf-8b77-f20a3947f0cb",
      "name": "Checks Domain Existence",
      "type": "n8n-nodes-base.if",
      "position": [
        -800,
        816
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "8f1130d1-8082-48a4-9f97-a05df2e6f725",
              "operator": {
                "type": "string",
                "operation": "exists",
                "singleValue": true
              },
              "leftValue": "={{ $json.company.domain }}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "c25ec326-deb9-490e-97ab-ebe3521e41a0",
      "name": "Apollo Get Targeted Personnel",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -1168,
        1312
      ],
      "parameters": {
        "url": "https://api.apollo.io/api/v1/people/search",
        "method": "POST",
        "options": {},
        "jsonBody": "={\n  \"q_organization_domains_list\": [\"{{ $json.company.domain }}\"],\n  \"person_seniorities\": [\"vp\", \"head\", \"director\", \"founder\", \"c-suite\", \"lead\"],\n  \"person_titles\": [\n    \"engineering\",\n    \"technology\",\n    \"product\",\n    \"operations\",\n    \"infrastructure\",\n    \"devops\",\n    \"data science\",\n    \"machine learning\",\n    \"cloud\"\n  ],\n  \"pagination\": { \"page\": 1, \"per_page\": 2 }\n}\n",
        "sendBody": true,
        "specifyBody": "json",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth"
      },
      "typeVersion": 4.2
    },
    {
      "id": "b42ec2f9-f178-49e3-aaf8-026fb1b3b360",
      "name": "Apollo Email Finder",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -496,
        1648
      ],
      "parameters": {
        "url": "https://api.apollo.io/v1/people/match",
        "method": "POST",
        "options": {},
        "jsonBody": "={\n  \"id\": \"{{ $json.person.personId }}\"\n}",
        "sendBody": true,
        "specifyBody": "json",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth"
      },
      "typeVersion": 4.2
    },
    {
      "id": "dbd59767-6054-4a77-b097-73b537b7404d",
      "name": "Sanitising Email Details",
      "type": "n8n-nodes-base.code",
      "position": [
        16,
        1648
      ],
      "parameters": {
        "jsCode": "// Extract only person.id + email\nreturn items.map(item => {\n  return {\n    json: {\n      email: {   // \ud83d\udc48 wrapped object\n        id: item.json.person?.id || null,\n        email: item.json.person?.email || null\n      }\n    }\n  };\n});\n"
      },
      "typeVersion": 2
    },
    {
      "id": "c2d53522-21bb-4d04-b3f5-f6c935356c9a",
      "name": "Structuring Complete Details of Person",
      "type": "n8n-nodes-base.code",
      "position": [
        816,
        896
      ],
      "parameters": {
        "jsCode": "// N8N JavaScript Code Node - Clean Data Merging (No Debug)\n// Mapping Logic:\n// - person.personId <-> email.id (one-to-one, unique)\n// - person.companyName <-> company.companyName (many-to-one, multiple persons per company)\n\n// Get all input items\nconst allItems = $input.all();\n\n// Step 1: Build email lookup by personId (one-to-one mapping)\nconst emailMap = {};\nallItems.forEach(item => {\n  const jsonData = item.json || {};\n  if (jsonData.email && jsonData.email.id) {\n    emailMap[jsonData.email.id] = jsonData.email.email;\n  }\n});\n\n// Step 2: Build company lookup by companyName (many-to-one mapping)\nconst companyMap = {};\nallItems.forEach(item => {\n  const jsonData = item.json || {};\n  if (jsonData.company && jsonData.company.companyName) {\n    companyMap[jsonData.company.companyName] = jsonData.company;\n  }\n});\n\n// Step 3: Merge person with email + company info\nconst outputItems = [];\n\nallItems.forEach(item => {\n  const jsonData = item.json || {};\n  if (!jsonData.person) return;\n  \n  const person = jsonData.person;\n  const personId = person.personId;\n  const companyName = person.companyName;\n  \n  // Get email from emailMap (unique per person)\n  const email = emailMap[personId] || null;\n  \n  // Get company info from companyMap (same for all persons at this company)\n  const companyInfo = companyMap[companyName] || {};\n  \n  // Create merged record\n  const mergedItem = {\n    json: {\n      ...person, // Spread all person fields\n      email: email,\n      companyDescription: companyInfo.companyDescription || null,\n      jobTitle: companyInfo.jobTitle || null,\n      employeeCount: companyInfo.employeeCount || null\n    }\n  };\n  \n  outputItems.push(mergedItem);\n});\n\n// Return the merged results\nreturn outputItems;"
      },
      "typeVersion": 2
    },
    {
      "id": "326bb4c6-ce73-4e76-9576-685319d00b1e",
      "name": "Adding Leads to Sheets",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        1040,
        560
      ],
      "parameters": {
        "columns": {
          "value": {
            "Email": "={{ $json.email }}",
            "Domain": "={{ $json.primaryDomain }}",
            "Company": "={{ $json.companyName }}",
            "Location": "={{ $json.city }}, {{ $json.country }}",
            "Job Title": "={{ $json.jobTitle }}",
            "Last Name": "={{ $json.lastName }}",
            "First Name": "={{ $json.firstName }}",
            "Occupation": "={{ $json.title }}",
            "Company URL": "={{ $json.companyWebsite }}",
            "LinkedIn Url": "={{ $json.personLinkedInUrl }}",
            "Employee Count": "={{ $json.employeeCount }}",
            "Company Description": "={{ $json.companyDescription }}",
            "Company LinkedIn Url": "={{ $json.companyLinkedInUrl }}"
          },
          "schema": [
            {
              "id": "First Name",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "First Name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Last Name",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Last Name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Occupation",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Occupation",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Company",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Company",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "LinkedIn Url",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "LinkedIn Url",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Company LinkedIn Url",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Company LinkedIn Url",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Company URL",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Company URL",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Location",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Location",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Domain",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Domain",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Email",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Email",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Company Description",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Company Description",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Employee Count",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Employee Count",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Job Title",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Job Title",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Subject",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Subject",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Email Body",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Email Body",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/YOUR_AWS_SECRET_KEY_HERE_gdo/edit#gid=0",
          "cachedResultName": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "YOUR_AWS_SECRET_KEY_HERE_gdo",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/YOUR_AWS_SECRET_KEY_HERE_gdo/edit?usp=drivesdk",
          "cachedResultName": "LinkedIn Lead Gen"
        }
      },
      "typeVersion": 4.6
    },
    {
      "id": "636f4815-dae0-4628-aa65-775781c405b5",
      "name": "Fetching Leads Data",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        1488,
        560
      ],
      "parameters": {
        "options": {},
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/YOUR_AWS_SECRET_KEY_HERE_gdo/edit#gid=0",
          "cachedResultName": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "YOUR_AWS_SECRET_KEY_HERE_gdo",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/YOUR_AWS_SECRET_KEY_HERE_gdo/edit?usp=drivesdk",
          "cachedResultName": "LinkedIn Lead Gen"
        }
      },
      "typeVersion": 4
    },
    {
      "id": "bb071500-09fa-492c-a64c-20fdd384e42a",
      "name": "Validates Email Id and Email Content",
      "type": "n8n-nodes-base.if",
      "position": [
        2160,
        576
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "0640b75d-662e-4625-a038-92c099b79f25",
              "operator": {
                "type": "string",
                "operation": "empty",
                "singleValue": true
              },
              "leftValue": "={{ $json.Subject }}",
              "rightValue": ""
            },
            {
              "id": "6d30f170-03fd-4e89-9a56-ab87e8c7c01a",
              "operator": {
                "type": "string",
                "operation": "empty",
                "singleValue": true
              },
              "leftValue": "={{ $json[\"Email Body\"] }}",
              "rightValue": ""
            },
            {
              "id": "81d61ac3-f195-4516-8259-331f7190a0c3",
              "operator": {
                "type": "string",
                "operation": "contains"
              },
              "leftValue": "={{ $json.Email }}",
              "rightValue": "@"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "012dd6c0-612d-4bbb-b690-43282abc2df0",
      "name": "Lead Email Generator",
      "type": "@n8n/n8n-nodes-langchain.chainLlm",
      "position": [
        2032,
        1008
      ],
      "parameters": {
        "text": "=Act as an expert B2B copywriter specializing in cold outreach for tech recruitment services.\n\n\nYour task is to write a personalized, friendly, and professional cold email. The goal is to get the attention of a busy executive by offering a clear solution to their current hiring needs.\n\n\nBACKGROUND & CONTEXT:\n\nOur Service: We provide pre-vetted, skilled remote tech talent (AI/ML Engineers, DevOps, etc.).\n\nTarget Company: US-based, under 250 employees.\n\nTarget Persona: CEO, CTO, Head of Engineering, VP of Operations.\n\nTrigger Event: The target company is actively hiring for a specific tech role.\n\nKey Value Proposition:\n\nSave significant time in the hiring process.\n\nSave 30-40% on budget compared to a direct, in-house hire.\n\n\nINPUT VARIABLES (You will use these to personalize the email):\n\n{{ $json.Company }}: The name of the company.\n\n{{ $json['Job Title'] }}: The specific job title they are hiring for (e.g., \"AI Engineer\").\n\n{{ $json.Occupation }}: The job title of the person I'm emailing (e.g., \"CTO\").\n\n\nINSTRUCTIONS & CONSTRAINTS:\n\n\n1. Subject Line:\n\nGenerate catchy subject line.\n\nEach subject line must be 7-8 words maximum.\n\nThey should be intriguing and directly related to their hiring needs. Examples: \"Your AI Engineer role,\" \"An idea for your engineering team,\" \"Filling your {{ $json['Job Title'] }} role.\"\n\n\n2. Email Body:\n\nWrite the email body only. Do not include a salutation like \"Hi {{ $json['First Name'] }}\".\n\nThe email must start with the exact phrase: \"Saw that {{ $json.Company }} is hiring for a {{ $json['Job Title'] }}.\"\n\nThe tone must be professional, friendly, and easy to understand.\n\nCrucially, avoid high-level marketing jargon or complex AI-related terminology. Keep the language simple and direct.\n\nFocus the message on the two main benefits: filling the role faster and more affordably. Mention the 30-40% savings.\n\nThe total word count for the body must be under 120 words.\n\nEnd with a soft, low-pressure call-to-action, such as asking if they are open to exploring alternative ways to build their team",
        "batching": {},
        "promptType": "define",
        "hasOutputParser": true
      },
      "typeVersion": 1.7
    },
    {
      "id": "2c3b430d-d1bb-42d6-ab31-88ced73e58f3",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -912,
        -32
      ],
      "parameters": {
        "height": 360,
        "content": "## \u25b6\ufe0f Start Workflow\n\n\n**Manually triggers the entire lead generation process.**"
      },
      "typeVersion": 1
    },
    {
      "id": "0d3f4c5f-c716-40ab-87b3-e5f74f705e65",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -512,
        -176
      ],
      "parameters": {
        "width": 260,
        "height": 440,
        "content": "## Run the LinkedIn Job Scraper from Apify\n\n\nScrape LinkedIn Job Postings:\n\nUses Apify to find companies that are actively hiring based on a specific job search URL."
      },
      "typeVersion": 1
    },
    {
      "id": "3743dc33-a59f-4ee4-95a2-9956c99c3981",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        16,
        -112
      ],
      "parameters": {
        "width": 260,
        "height": 420,
        "content": "## Get dataset Items\n\nCollect Scraped Data:\n\nRetrieves the list of job postings and company details scraped by Apify."
      },
      "typeVersion": 1
    },
    {
      "id": "8bb80fc2-cd66-4664-8b44-16fb8776a61c",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        512,
        -48
      ],
      "parameters": {
        "width": 260,
        "height": 420,
        "content": "## Checks Company Size < 250\n\nFilter by Company Size:\n\nOnly allows companies with fewer than 250 employees to pass through."
      },
      "typeVersion": 1
    },
    {
      "id": "2425cb33-44ce-411b-a01d-aede93c801b5",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1072,
        496
      ],
      "parameters": {
        "color": 5,
        "height": 100,
        "content": "## Rmeove Duplicate Entries\n"
      },
      "typeVersion": 1
    },
    {
      "id": "e5937705-ff40-41c7-bb0a-3864fac0e9dc",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -448,
        368
      ],
      "parameters": {
        "color": 5,
        "height": 120,
        "content": "## Rmeove HR Related Companies"
      },
      "typeVersion": 1
    },
    {
      "id": "17a39567-8afb-4faa-a29f-ca7522cf3408",
      "name": "Sticky Note6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        96,
        368
      ],
      "parameters": {
        "color": 5,
        "height": 120,
        "content": "## Prepare Final Company Details"
      },
      "typeVersion": 1
    },
    {
      "id": "603bc9a8-e1be-49e2-a789-2bc84da68ee2",
      "name": "Sticky Note7",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -816,
        736
      ],
      "parameters": {
        "color": 5,
        "height": 80,
        "content": "## Check domain Existence"
      },
      "typeVersion": 1
    },
    {
      "id": "ee151293-9743-4df6-bf8c-fab51cf5df10",
      "name": "Limit Companies Search",
      "type": "n8n-nodes-base.limit",
      "position": [
        -128,
        848
      ],
      "parameters": {
        "maxItems": 5
      },
      "typeVersion": 1
    },
    {
      "id": "6f6e8313-f32e-4bd1-8ff8-973593afd95d",
      "name": "Sticky Note8",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -176,
        752
      ],
      "parameters": {
        "color": 5,
        "height": 80,
        "content": "## Limit Company Search"
      },
      "typeVersion": 1
    },
    {
      "id": "00d91745-b097-4049-805e-8133294b46fe",
      "name": "Sticky Note9",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1488,
        1248
      ],
      "parameters": {
        "color": 6,
        "height": 260,
        "content": "## Apollo Get Targeted Personnel\n\n\nFind Decision-Makers:\n\nSearches Apollo.io using the company domain to find key contacts (VPs, Directors, etc.)."
      },
      "typeVersion": 1
    },
    {
      "id": "f7572335-877a-4033-82f8-bb7bda1a38ff",
      "name": "Sticky Note10",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -848,
        1088
      ],
      "parameters": {
        "color": 6,
        "height": 260,
        "content": "## Sanitising Person Details\n\nClean Person Data:\n\nStructures the contact details and removes duplicates to create a clean list of people."
      },
      "typeVersion": 1
    },
    {
      "id": "786da361-b3f8-45ee-a4d5-4b1a0a00c9c7",
      "name": "Sanitising Person Details",
      "type": "n8n-nodes-base.code",
      "position": [
        -768,
        1360
      ],
      "parameters": {
        "jsCode": "// Flatten + dedupe by (person.id + companyName)\nlet results = [];\nlet seen = new Set();\n\nitems.forEach(item => {\n  const people = item.json.people || [];\n\n  people.forEach(person => {\n    if (!person.id) return;\n\n    const company = person.organization || {};\n    const uniqueKey = person.id + \"|\" + (company.name || \"\"); \n\n    if (seen.has(uniqueKey)) return;\n    seen.add(uniqueKey);\n\n    let websiteUrl = company.website_url || null;\n    let domain = company.primary_domain || null;\n\n    if (!domain && websiteUrl) {\n      try {\n        const parsedUrl = new URL(websiteUrl);\n        domain = parsedUrl.hostname.replace(/^www\\./, \"\");\n      } catch (err) {\n        domain = websiteUrl.replace(/^(https?:\\/\\/)?(www\\.)?/, \"\").split(/[/?#]/)[0];\n      }\n    }\n\n    results.push({\n      json: {\n        person: {   // \ud83d\udc48 wrapped object\n          uniqueKey: uniqueKey,\n          personId: person.id || null,\n          firstName: person.first_name || null,\n          lastName: person.last_name || null,\n          personLinkedInUrl: person.linkedin_url || null,\n          title: person.title || null,\n          city: person.city || null,\n          country: person.country || null,\n          companyName: company.name || null,\n          companyWebsite: websiteUrl,\n          primaryDomain: domain,\n          companyLinkedInUrl: company.linkedin_url || null\n        }\n      }\n    });\n  });\n});\n\nreturn results;\n"
      },
      "typeVersion": 2
    },
    {
      "id": "f847fb0f-f82b-47c9-a493-9e859bc16a4e",
      "name": "Sticky Note11",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -576,
        1840
      ],
      "parameters": {
        "color": 6,
        "height": 260,
        "content": "## Apollo Email Finder\n\nFind Verified Emails:\n\nFor each contact, this node asks Apollo.io to find their professional email address."
      },
      "typeVersion": 1
    },
    {
      "id": "18a68ac3-c63f-44aa-9169-a080eb1a21ce",
      "name": "Sticky Note12",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -48,
        1840
      ],
      "parameters": {
        "color": 6,
        "height": 220,
        "content": "## Sanitising Email Details\n\nIsolate Email Data:\n\nPrepares the found email addresses for merging"
      },
      "typeVersion": 1
    },
    {
      "id": "2713732b-136d-4f9d-8964-ef5b54adeff6",
      "name": "Sticky Note13",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        400,
        1296
      ],
      "parameters": {
        "color": 4,
        "width": 280,
        "height": 240,
        "content": "## Merge Data\n\nCombine Data Streams:\n\nMerges the company data, the person data, and the email data together."
      },
      "typeVersion": 1
    },
    {
      "id": "20fc29b2-1b85-4f55-847f-51161415391b",
      "name": "Sticky Note14",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        768,
        1056
      ],
      "parameters": {
        "color": 4,
        "width": 280,
        "height": 240,
        "content": "## Structuring Complete Details of Person\n\nCreate Final Lead Profile:\n\nCombines all three data streams into a single, complete lead record for each person."
      },
      "typeVersion": 1
    },
    {
      "id": "6a07323e-c5aa-4cfa-8f8b-19662806e35b",
      "name": "Sticky Note15",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        928,
        352
      ],
      "parameters": {
        "color": 3,
        "width": 280,
        "height": 240,
        "content": "## Save Leads to Google Sheets\n\nAppends each complete lead profile as a new row in the master spreadsheet."
      },
      "typeVersion": 1
    },
    {
      "id": "0b81960f-6d52-498d-9bd7-34689431fb88",
      "name": "Sticky Note16",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1408,
        336
      ],
      "parameters": {
        "color": 3,
        "width": 280,
        "height": 260,
        "content": "## Fetching Leads Data\n\nRead Leads for AI:\n\nReads the newly saved leads from the sheet to begin the email generation phase."
      },
      "typeVersion": 1
    },
    {
      "id": "d19a3c2d-ec40-4263-aa09-799f3ab25e7a",
      "name": "Sticky Note17",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2080,
        352
      ],
      "parameters": {
        "color": 3,
        "width": 280,
        "height": 300,
        "content": "## Validates Email Id and Email Content\n\nCheck Before AI Processing:\n\nFilters for leads that have a valid email but do NOT yet have a generated subject or body."
      },
      "typeVersion": 1
    },
    {
      "id": "0ccfe835-fc19-4ffa-acf8-644bc6149633",
      "name": "Sticky Note18",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1408,
        1152
      ],
      "parameters": {
        "color": 2,
        "width": 280,
        "height": 180,
        "content": "## Apply Final Filter\n\nApplies a final condition before sending data to the AI model (e.g., for batching or testing).\n\n"
      },
      "typeVersion": 1
    },
    {
      "id": "fd60f2ef-f30c-4450-9ce4-273946d0f3ed",
      "name": "Sticky Note19",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1952,
        816
      ],
      "parameters": {
        "color": 2,
        "width": 360,
        "height": 240,
        "content": "## Lead Email Generator\n\nAI Prompt Engine:\n\nTakes the lead data, combines it with the prompt, and sends it to the Gemini model.\n\n"
      },
      "typeVersion": 1
    },
    {
      "id": "14f000f8-c23b-43fb-9dc8-53c056d09345",
      "name": "Sticky Note20",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1792,
        1520
      ],
      "parameters": {
        "color": 2,
        "width": 360,
        "height": 240,
        "content": "## Google Gemini Chat Model\n\nGoogle Gemini Model:\n\nThe AI model that actually writes the email based on the provided data and instructions.\n\n"
      },
      "typeVersion": 1
    },
    {
      "id": "17ef075d-dde3-4999-9868-f78f867fa322",
      "name": "Sticky Note21",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2448,
        816
      ],
      "parameters": {
        "color": 2,
        "width": 360,
        "height": 240,
        "content": "## Update Sheet with Email\n\nUpdate Sheet with AI Email:\n\nSaves the generated subject and email body back into the correct row for the lead in Google Sheets.\n\n"
      },
      "typeVersion": 1
    },
    {
      "id": "d7ec9db4-05eb-4e9c-8916-26b046252611",
      "name": "Sticky Note22",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2416,
        1536
      ],
      "parameters": {
        "color": 2,
        "width": 360,
        "height": 240,
        "content": "## Structured Output Parser\n\nFormat AI Output:\n\nTakes the raw text from Gemini and structures it into clean JSON (subject and email_body).\n\n"
      },
      "typeVersion": 1
    },
    {
      "id": "26ab04ae-8f36-4268-ac75-0628e12e321d",
      "name": "Sticky Note23",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2880,
        1200
      ],
      "parameters": {
        "color": 2,
        "width": 440,
        "height": 240,
        "content": "## Need Help? \n\nWe develop tailored workflow to save youe valuable time. Should you have any questions or wish to explore more custom automation solutions, we would be happy to connect\n\n\n### Email: getstarted@intuz.com\n### Website: https://www.intuz.com/\n\n"
      },
      "typeVersion": 1
    },
    {
      "id": "30bffaa6-f024-4725-a969-06f489de54d1",
      "name": "Merge Data",
      "type": "n8n-nodes-base.merge",
      "position": [
        480,
        1120
      ],
      "parameters": {
        "numberInputs": 3
      },
      "typeVersion": 3.2
    },
    {
      "id": "db0db762-142e-4ea8-8ff3-f868fd7d262c",
      "name": "Filter for Batching",
      "type": "n8n-nodes-base.filter",
      "position": [
        1520,
        1008
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "fed38656-1a21-4b77-babe-3c49a6f36124",
              "operator": {
                "type": "number",
                "operation": "gt"
              },
              "leftValue": "={{ $json.row_number }}",
              "rightValue": 83
            }
          ]
        }
      },
      "typeVersion": 2.2
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "75ee3ba0-b483-48b3-a185-cd0aaec04290",
  "connections": {
    "Merge Data": {
      "main": [
        [
          {
            "node": "Structuring Complete Details of Person",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get dataset Items": {
      "main": [
        [
          {
            "node": "Checks Company Size < 250",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Remove Duplicates": {
      "main": [
        [
          {
            "node": "Removes HR Related Industry",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Apollo Email Finder": {
      "main": [
        [
          {
            "node": "Sanitising Email Details",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetching Leads Data": {
      "main": [
        [
          {
            "node": "Validates Email Id and Email Content",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Filter for Batching": {
      "main": [
        [
          {
            "node": "Lead Email Generator",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Lead Email Generator": {
      "main": [
        [
          {
            "node": "Update Sheet with Email",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Adding Leads to Sheets": {
      "main": [
        [
          {
            "node": "Fetching Leads Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Limit Companies Search": {
      "main": [
        [
          {
            "node": "Merge Data",
            "type": "main",
            "index": 0
          },
          {
            "node": "Apollo Get Targeted Personnel",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Checks Domain Existence": {
      "main": [
        [
          {
            "node": "Limit Companies Search",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Google Gemini Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "Lead Email Generator",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Sanitising Email Details": {
      "main": [
        [
          {
            "node": "Merge Data",
            "type": "main",
            "index": 2
          }
        ]
      ]
    },
    "Structured Output Parser": {
      "ai_outputParser": [
        [
          {
            "node": "Lead Email Generator",
            "type": "ai_outputParser",
            "index": 0
          }
        ]
      ]
    },
    "Checks Company Size < 250": {
      "main": [
        [
          {
            "node": "Remove Duplicates",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Sanitising Person Details": {
      "main": [
        [
          {
            "node": "Apollo Email Finder",
            "type": "main",
            "index": 0
          },
          {
            "node": "Merge Data",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Removes HR Related Industry": {
      "main": [
        [
          {
            "node": "Prepare Final Company Details",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Run the LinkedIn Job Scraper": {
      "main": [
        [
          {
            "node": "Get dataset Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Apollo Get Targeted Personnel": {
      "main": [
        [
          {
            "node": "Sanitising Person Details",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Prepare Final Company Details": {
      "main": [
        [
          {
            "node": "Checks Domain Existence",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Validates Email Id and Email Content": {
      "main": [
        [
          {
            "node": "Filter for Batching",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "When clicking \u2018Execute workflow\u2019": {
      "main": [
        [
          {
            "node": "Run the LinkedIn Job Scraper",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Structuring Complete Details of Person": {
      "main": [
        [
          {
            "node": "Adding Leads to Sheets",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
Pro

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

About this workflow

Community nodes are used in this workflow. B2B Sales Teams & SDRs Recruitment Agencies & Tech Recruiters Startup Founders Growth Marketing Teams Scrape Hiring Signals: The workflow starts by using an Apify scraper to find companies actively hiring for specific roles on LinkedIn…

Source: https://n8n.io/workflows/9219/ — original creator credit. Request a take-down →

More Web Scraping workflows → · Browse all categories →

Related workflows

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

Web Scraping

Visual Regression Testing With Apify And Ai Vision Model. Uses googleDrive, lmChatGoogleGemini, outputParserStructured, stickyNote. Scheduled trigger; 34 nodes.

Google Drive, Google Gemini Chat, Output Parser Structured +4
Web Scraping

This n8n workflow is a proof-of-concept template exploring how we might work with multimodal LLMs and their multi-image analysis capabilities. In this demo, we compare 2 screenshots of a webpage taken

Google Drive, Google Gemini Chat, Output Parser Structured +4
Web Scraping

This n8n workflow automates the process of collecting job and decision-maker data, crafting AI-generated referral messages, and drafting them in Gmail—all using a combination of Apify, Google Sheets,

Google Sheets, Chain Llm, Google Gemini Chat +3
Web Scraping

This powerful workflow automates the evaluation of new digital tools, websites, or platforms with the goal of assessing their potential impact on your business. By leveraging Telegram for user input,

Telegram Trigger, OpenRouter Chat, Telegram +6
Web Scraping

AI Chatbot-Backend. Uses scheduleTrigger, chainLlm, lmChatGoogleGemini, outputParserStructured. Scheduled trigger; 12 nodes.

Chain Llm, Google Gemini Chat, Output Parser Structured +3