This workflow corresponds to n8n.io template #8012 — 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 →
{
"id": "xkdknceWGy7eT6B0",
"name": "Live-Automate LinkedIn Profile Research & AI Outreach with Apify, Gemini & Sheets",
"tags": [],
"nodes": [
{
"id": "ecbfc577-7f4d-448c-8c70-4c6a80ba7629",
"name": "Get row(s) in sheet",
"type": "n8n-nodes-base.googleSheets",
"position": [
-1792,
336
],
"parameters": {
"options": {},
"sheetName": {
"__rl": true,
"mode": "list",
"value": 1023079571,
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1nIGlVREvoz7iyCsOmCgqRXgKFFQZIVckV6a1KnDGpjM/edit#gid=1023079571",
"cachedResultName": "Sheet10"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1nIGlVREvoz7iyCsOmCgqRXgKFFQZIVckV6a1KnDGpjM",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1nIGlVREvoz7iyCsOmCgqRXgKFFQZIVckV6a1KnDGpjM/edit?usp=drivesdk",
"cachedResultName": "MLOps CXOs Bay Area"
}
},
"typeVersion": 4.7
},
{
"id": "efe97c07-f2d4-4f90-9f21-a503ebbd4103",
"name": "Limit",
"type": "n8n-nodes-base.limit",
"position": [
-1360,
320
],
"parameters": {},
"typeVersion": 1
},
{
"id": "4f2e62e8-7e5e-434b-80f7-c2197ad1950c",
"name": "Get dataset items",
"type": "@apify/n8n-nodes-apify.apify",
"position": [
-944,
320
],
"parameters": {
"offset": {},
"resource": "Datasets",
"datasetId": "={{ $json.defaultDatasetId }}"
},
"typeVersion": 1
},
{
"id": "b8bdd09a-1e75-4a13-9fee-75ffc305fa67",
"name": "Append or update row in sheet",
"type": "n8n-nodes-base.googleSheets",
"position": [
-672,
320
],
"parameters": {
"columns": {
"value": {
"LinkedIn": "={{ $('Limit').item.json.LinkedIn }}",
"Profile Data": "=About : {{ $json.basic_info.about }}\n\n{{ $json.experience.map((exp, i) => \n \"Experience \" + (i+1) + \"\\n\" +\n \"Title: \" + exp.title + \"\\n\" +\n \"Company: \" + exp.company + \"\\n\" +\n \"Location: \" + exp.location + \"\\n\" +\n \"Description: \" + exp.description\n).join(\"\\n\\n\") }}\n\n"
},
"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": "Job Title",
"type": "string",
"display": true,
"required": false,
"displayName": "Job Title",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Location",
"type": "string",
"display": true,
"required": false,
"displayName": "Location",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "LinkedIn",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "LinkedIn",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Company Name",
"type": "string",
"display": true,
"required": false,
"displayName": "Company Name",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Profile Data",
"type": "string",
"display": true,
"required": false,
"displayName": "Profile Data",
"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
}
],
"mappingMode": "defineBelow",
"matchingColumns": [
"LinkedIn"
],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {},
"operation": "appendOrUpdate",
"sheetName": {
"__rl": true,
"mode": "list",
"value": 1023079571,
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1nIGlVREvoz7iyCsOmCgqRXgKFFQZIVckV6a1KnDGpjM/edit#gid=1023079571",
"cachedResultName": "Sheet10"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1nIGlVREvoz7iyCsOmCgqRXgKFFQZIVckV6a1KnDGpjM",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1nIGlVREvoz7iyCsOmCgqRXgKFFQZIVckV6a1KnDGpjM/edit?usp=drivesdk",
"cachedResultName": "MLOps CXOs Bay Area"
}
},
"typeVersion": 4.7
},
{
"id": "0d58b6ca-bd4d-442b-958a-6e54c8fcb9b0",
"name": "Get row(s) in sheet1",
"type": "n8n-nodes-base.googleSheets",
"position": [
-400,
320
],
"parameters": {
"options": {},
"sheetName": {
"__rl": true,
"mode": "list",
"value": 1023079571,
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1nIGlVREvoz7iyCsOmCgqRXgKFFQZIVckV6a1KnDGpjM/edit#gid=1023079571",
"cachedResultName": "Sheet10"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1nIGlVREvoz7iyCsOmCgqRXgKFFQZIVckV6a1KnDGpjM",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1nIGlVREvoz7iyCsOmCgqRXgKFFQZIVckV6a1KnDGpjM/edit?usp=drivesdk",
"cachedResultName": "MLOps CXOs Bay Area"
}
},
"typeVersion": 4.7
},
{
"id": "0ca835dc-bc3f-49bf-85d8-08a8d41d3502",
"name": "Structured Output Parser",
"type": "@n8n/n8n-nodes-langchain.outputParserStructured",
"position": [
240,
512
],
"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": "d1412a37-4f94-4efa-aac8-ba7f129b2bb7",
"name": "Google Gemini Chat Model",
"type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
"position": [
64,
512
],
"parameters": {
"options": {}
},
"typeVersion": 1
},
{
"id": "6e9c4aac-17fc-4b21-a832-038b6571a52e",
"name": "Schedule Trigger",
"type": "n8n-nodes-base.scheduleTrigger",
"position": [
-2000,
336
],
"parameters": {
"rule": {
"interval": [
{
"field": "minutes",
"minutesInterval": 2
}
]
}
},
"typeVersion": 1.2
},
{
"id": "27f7cb9e-f89a-4496-b2ff-0cd8fb0cf6af",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
-2048,
80
],
"parameters": {
"color": 2,
"width": 384,
"height": 416,
"content": "## \u23f0 Schedule Trigger & \ud83d\udcc4 Google Sheets (Input)\nThis part of the workflow runs every 2 minutes. \nIt fetches new rows (LinkedIn URLs and lead data) from the CRM sheet. \nOnly leads without Profile Data or Email drafts move forward.\n"
},
"typeVersion": 1
},
{
"id": "20b443fd-25df-4397-b167-cfa1ae1616fc",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1616,
80
],
"parameters": {
"color": 6,
"width": 384,
"height": 416,
"content": "## \ud83d\udd0d If Check & \u2696\ufe0f Limit\n1. The **If node** ensures only leads missing Profile Data and Subject are processed. \n\n2. The **Limit node** controls batch size to prevent Apify overload or LinkedIn blocks. \n\nKeeps the workflow safe & efficient.\n"
},
"typeVersion": 1
},
{
"id": "fd519317-971a-4cbf-a891-dcb61965c30f",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1200,
80
],
"parameters": {
"color": 4,
"width": 384,
"height": 416,
"content": "## \ud83e\udd16 Apify Actor & \ud83d\udcc2 Dataset\n1. Runs the **LinkedIn Profile Scraper** actor on Apify for each LinkedIn URL. \n\n2. The Dataset node fetches structured results (About, Experience, Roles, Companies). \n\nThis enriches leads with detailed career data.\n"
},
"typeVersion": 1
},
{
"id": "5b2af68b-9acb-4021-9211-ea9f947cffbf",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
-768,
64
],
"parameters": {
"color": 5,
"width": 288,
"height": 432,
"content": "## \ud83d\udcbe Google Sheets (Profile Data)\nAppends enriched profile details into the \"Profile Data\" column in Google Sheets. \nNow each lead row includes About + Experience insights, ready for email personalisation.\n\n"
},
"typeVersion": 1
},
{
"id": "5fbf3fc9-7a32-46b3-92a1-95758b9a1337",
"name": "Sticky Note4",
"type": "n8n-nodes-base.stickyNote",
"position": [
-432,
80
],
"parameters": {
"color": 3,
"width": 368,
"height": 384,
"content": "## \ud83d\udcc4 Get Rows Again & \ud83d\udd0d If Check (Email)\n1. Pulls updated rows after scraping. \n\n2. Checks if Profile Data exists but \nSubject + Email Body are still empty. \n\nEnsures only complete profiles go into email generation.\n"
},
"typeVersion": 1
},
{
"id": "6b63c91d-a436-4c1d-8d1c-3e5b3f84194e",
"name": "Sticky Note5",
"type": "n8n-nodes-base.stickyNote",
"position": [
0,
0
],
"parameters": {
"width": 368,
"height": 464,
"content": "## \ud83e\udde0 LLM Chain (Gemini via LangChain)\n1. Gemini is instructed to act as an expert B2B cold email copywriter. \n\n2. It generates personalised subject lines & email bodies using career insights, achievements, and context. \n\n3. Parser ensures Gemini\u2019s response is valid JSON with \"subject\" + \"email_body\".\n\nResult: high-relevance outreach emails.\n \n"
},
"typeVersion": 1
},
{
"id": "36ffcba7-23b8-45fc-b7dd-612f8537c293",
"name": "Sticky Note6",
"type": "n8n-nodes-base.stickyNote",
"position": [
416,
80
],
"parameters": {
"color": 5,
"width": 320,
"height": 384,
"content": "## \ud83d\udcbe Google Sheets (Final Email)\nFinal email drafts are stored in Google Sheets alongside LinkedIn URL & Profile Data. \nEach lead row is now fully ready for outreach \ud83d\ude80.\n"
},
"typeVersion": 1
},
{
"id": "6bcd2902-cf7c-4235-ad92-d8ea28392af4",
"name": "Check Profiles with no Data",
"type": "n8n-nodes-base.if",
"position": [
-1568,
336
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "b8ddddfc-54ae-4815-aea8-edc05959cc11",
"operator": {
"type": "string",
"operation": "empty",
"singleValue": true
},
"leftValue": "={{ $json[\"Profile Data\"] }}",
"rightValue": ""
},
{
"id": "5b0584d8-cfe8-4758-b097-cb0ecd87f5e4",
"operator": {
"type": "string",
"operation": "empty",
"singleValue": true
},
"leftValue": "={{ $json.Subject }}",
"rightValue": ""
}
]
}
},
"typeVersion": 2.2
},
{
"id": "77f3dbf8-9218-44cf-a03f-feacfa4a1906",
"name": "Runs Profile Extraction Actor",
"type": "@apify/n8n-nodes-apify.apify",
"position": [
-1152,
320
],
"parameters": {
"actorId": {
"__rl": true,
"mode": "list",
"value": "VhxlqQXRwhW8H5hNV",
"cachedResultUrl": "https://console.apify.com/actors/VhxlqQXRwhW8H5hNV/input",
"cachedResultName": "Linkedin Profile Details Scraper + EMAIL (No Cookies Required) (apimaestro/linkedin-profile-detail)"
},
"timeout": {},
"customBody": "={\n \"includeEmail\": false,\n \"username\": \"{{ $json.LinkedIn }}\"\n}"
},
"typeVersion": 1
},
{
"id": "02725c27-8264-4b8d-a725-18947a0c8b6b",
"name": "Check Profiles with No Email Drafts",
"type": "n8n-nodes-base.if",
"position": [
-208,
320
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "dcf02764-abdc-4eca-8022-b0c585301927",
"operator": {
"type": "string",
"operation": "notEmpty",
"singleValue": true
},
"leftValue": "={{ $json[\"Profile Data\"] }}",
"rightValue": ""
},
{
"id": "87fc4d1b-97e7-4fcd-af85-f1414d476b67",
"operator": {
"type": "string",
"operation": "empty",
"singleValue": true
},
"leftValue": "={{ $json.Subject }}",
"rightValue": ""
},
{
"id": "4a7ddabd-14bd-429f-97e3-513abf6c62f8",
"operator": {
"type": "string",
"operation": "empty",
"singleValue": true
},
"leftValue": "={{ $json[\"Email Body\"] }}",
"rightValue": ""
}
]
}
},
"typeVersion": 2.2
},
{
"id": "f81e7880-4ae7-4f32-864a-05bb176a9e58",
"name": "Hyper Personalised Email Generator",
"type": "@n8n/n8n-nodes-langchain.chainLlm",
"position": [
80,
304
],
"parameters": {
"text": "=**Act as an expert B2B cold email copywriter.** Your specialty is writing highly personalized, concise, and compelling emails that get replies from busy executives. Your style is peer-to-peer, respectful, and avoids generic sales jargon.\n\n\n\n**Your Goal:** Generate 1 distinct email draft to a prospect based on their professional profile. Each email must feel like I have personally researched them and understood their career journey.\n\n\n\n**My Context:**\n\n\n* **My Company/Service:** We offer MLOps solutions that help companies significantly reduce their cloud costs for AI and machine learning workloads without sacrificing performance.\n\n\n* **My Core Value Proposition:** We help tech leaders ship AI features faster and more profitably by optimizing their infrastructure.\n\n\n* **My Call to Action (CTA):** An offer for a complimentary, no-obligation audit of their current ML infrastructure to identify immediate cost-saving opportunities.\n\n\n\n**Prospect's Profile:**\n\n\nFULL PROFILE DETAILS HERE \nFirst Name: {{ $json['First Name'] }}\nLast Name: {{ $json['Last Name'] }}\nJob Title: {{ $json['Job Title'] }}\nCompany Name: {{ $json['Company Name'] }}\nProfile Data: {{ $json['Profile Data'] }}\n\n**Instructions for Crafting the Emails:**\n\n\n\n1. **Scrutinize the Profile:** Read the entire profile provided. Do not just look at the current job title. Instead, identify the most unique and compelling \"nuggets\" of information. Look for:\n\n\n * **Unusual Career Paths:** (e.g., from SysAdmin to VP of Product, or Trader to COO).\n\n\n * **Long Tenure / Promotions:** (e.g., spending 9+ years at one company and rising through the ranks).\n\n\n * **Specific, Quantifiable Achievements:** (e.g., \"scaled to 4M members\").\n\n\n * **\"Boomerang\" Employment:** (e.g., leaving a company and returning later in a more senior role).\n\n\n * **Consistent Themes:** (e.g., a career-long focus on \"health and wealth outcomes\").\n\n\n * **Past Roles at well-known companies** that are relevant to their current role.\n\n\n\n2. **Create a \"Hook\" from a Nugget:** Start each email with a genuine, specific observation based on one of these nuggets. This is the most critical step.\n\n\n * **Good Example:** \"Your 9-year journey at Wanderu, from Director to leading both Product & Technology, is incredibly impressive.\"\n\n\n * **Bad Example:** \"I saw on your LinkedIn profile that you are the VP at Wanderu.\"\n\n\n\n3. **Build a \"Bridge\":** Immediately connect your observation (the Hook) to a relevant business problem that the prospect likely faces in their *current* role. The problem should be tailored to their title:\n\n\n * **For a CTO/VP Engineering:** Frame the problem around infrastructure complexity, scalability, and technical debt.\n\n\n * **For a COO/GM:** Frame the problem around operational efficiency, P&L, gross margins, and profitability (COGS).\n\n\n * **For a VP Product:** Frame the problem around speed-to-market, feature ROI, and the budget for new initiatives.\n\n\n\n4. **Introduce the Solution:** Seamlessly introduce my service (MLOps for cost reduction) as the direct solution to the problem you just framed. Use my Core Value Proposition here.\n\n\n\n5. **Deliver the Call to Action:** End with the specific, low-friction CTA I provided.\n\n\n\n**Final Output Requirements:**\n\n\n* Provide 1 distinct drafts, each using a different \"nugget\" or angle for the hook.\n\n\n* Keep each email under 150 words.\n\n\n* Use a confident, peer-level tone. Avoid overly formal or submissive language.\n\n\n* Create a compelling, short subject line for each draft.\n\nCritical Information:\n- The output should be divided into \nsubject: \"Subject line\"\nBody: \"Content for email\"\n- Each mail should be different to other one.",
"batching": {},
"promptType": "define",
"hasOutputParser": true
},
"typeVersion": 1.7
},
{
"id": "556499f4-f086-45bf-aad7-90e78c4dfc5b",
"name": "Final Output",
"type": "n8n-nodes-base.googleSheets",
"position": [
512,
304
],
"parameters": {
"columns": {
"value": {
"Subject": "={{ $json.output.subject }}",
"LinkedIn": "={{ $('Check Profiles with No Email Drafts').item.json.LinkedIn }}",
"Email Body": "={{ $json.output.email_body }}"
},
"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": "Job Title",
"type": "string",
"display": true,
"required": false,
"displayName": "Job Title",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Location",
"type": "string",
"display": true,
"required": false,
"displayName": "Location",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "LinkedIn",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "LinkedIn",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Company Name",
"type": "string",
"display": true,
"required": false,
"displayName": "Company Name",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Profile Data",
"type": "string",
"display": true,
"required": false,
"displayName": "Profile Data",
"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
}
],
"mappingMode": "defineBelow",
"matchingColumns": [
"LinkedIn"
],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {},
"operation": "appendOrUpdate",
"sheetName": {
"__rl": true,
"mode": "list",
"value": 1023079571,
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1nIGlVREvoz7iyCsOmCgqRXgKFFQZIVckV6a1KnDGpjM/edit#gid=1023079571",
"cachedResultName": "Sheet10"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1nIGlVREvoz7iyCsOmCgqRXgKFFQZIVckV6a1KnDGpjM",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1nIGlVREvoz7iyCsOmCgqRXgKFFQZIVckV6a1KnDGpjM/edit?usp=drivesdk",
"cachedResultName": "MLOps CXOs Bay Area"
}
},
"typeVersion": 4.7
}
],
"active": false,
"settings": {
"executionOrder": "v1"
},
"versionId": "2d96068c-2cd4-48c7-adb3-f5139666adc1",
"connections": {
"Limit": {
"main": [
[
{
"node": "Runs Profile Extraction Actor",
"type": "main",
"index": 0
}
]
]
},
"Schedule Trigger": {
"main": [
[
{
"node": "Get row(s) in sheet",
"type": "main",
"index": 0
}
]
]
},
"Get dataset items": {
"main": [
[
{
"node": "Append or update row in sheet",
"type": "main",
"index": 0
}
]
]
},
"Get row(s) in sheet": {
"main": [
[
{
"node": "Check Profiles with no Data",
"type": "main",
"index": 0
}
]
]
},
"Get row(s) in sheet1": {
"main": [
[
{
"node": "Check Profiles with No Email Drafts",
"type": "main",
"index": 0
}
]
]
},
"Google Gemini Chat Model": {
"ai_languageModel": [
[
{
"node": "Hyper Personalised Email Generator",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Structured Output Parser": {
"ai_outputParser": [
[
{
"node": "Hyper Personalised Email Generator",
"type": "ai_outputParser",
"index": 0
}
]
]
},
"Check Profiles with no Data": {
"main": [
[
{
"node": "Limit",
"type": "main",
"index": 0
}
]
]
},
"Append or update row in sheet": {
"main": [
[
{
"node": "Get row(s) in sheet1",
"type": "main",
"index": 0
}
]
]
},
"Runs Profile Extraction Actor": {
"main": [
[
{
"node": "Get dataset items",
"type": "main",
"index": 0
}
]
]
},
"Hyper Personalised Email Generator": {
"main": [
[
{
"node": "Final Output",
"type": "main",
"index": 0
}
]
]
},
"Check Profiles with No Email Drafts": {
"main": [
[
{
"node": "Hyper Personalised Email Generator",
"type": "main",
"index": 0
}
]
]
}
}
}
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
It transforms a basic list of LinkedIn profiles into a campaign-ready database by first enriching contacts with detailed career data and then using AI to craft unique, context-aware emails based on each individual's professional journey. Sales Development Representatives (SDRs)…
Source: https://n8n.io/workflows/8012/ — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
Effortlessly generate, review, and publish SEO-optimized blog posts to WordPress using AI and automation.
This n8n workflow automatically monitors YouTube channels, transcribes new videos, and generates AI-powered summaries with relevance scoring. It pulls channel URLs from a Google Sheet, fetches recent
This workflow automatically creates short-form AI videos using Sora 2 Cameos, powered by n8n and AI agents.
Transform your festival marketing with this comprehensive automation workflow that creates and posts culturally authentic social media content across multiple platforms daily.
Automatically generate viral short-form health videos using AI and publish them to social platforms with n8n and Veo 3. This workflow collects viral ideas, analyzes engagement patterns, generates AI v