Hallo zusammen,
Ich baue einen Lead-Generation- und Outreach-Workflow in n8n mit folgendem Setup:
-
Datenquelle / Scraper: Auslösen eines Apify-Actors, um Prospect-URLs/Profile zu sammeln.
-
KI-Node (Google Gemini): Verwendung von Google Gemini (statt OpenAI) zur Generierung von benutzerdefinierten Icebreakern/personalisierten Einleitungsnachrichten basierend auf Prospect-Details.
-
Anreicherung (Lusha): Verwendung von Lusha (statt nur auf LinkedIn-Scraper-Daten zu verlassen), um verifizierte direkte Business-E-Mails und Kontaktdetails zu extrahieren.
-
Ziel: Angereichte Datensätze und Gemini-Icebreaker direkt in Google Sheets einfügen.
Wobei ich Hilfe brauche:
-
Sicherstellen, dass n8n den Apify-Run korrekt pausiert/wartet, bis dieser abgeschlossen ist, bevor Daten downstream weitergeleitet werden.
-
Korrekte Zuordnung der Ausgabefelder von Apify $\rightarrow$ Google Gemini $\rightarrow$ Lusha $\rightarrow$ Google Sheets, damit jeder Schritt die richtigen Parameter erhält.
Hier ist mein Workflow-Blueprint:
{
“nodes”: [
{
“parameters”: {
“aggregate”: “aggregateAllItemData”,
“options”: {}
},
“id”: “161feae7-64f3-470a-8747-880024aed008”,
“name”: “Aggregate”,
“type”: “n8n-nodes-base.aggregate”,
“position”: [
1824,
240
],
“typeVersion”: 1
},
{
“parameters”: {
“formTitle”: "Audience ",
“formDescription”: “describe your audinece in plain text”,
“formFields”: {
“values”: [
{
“fieldLabel”: "descritpion of the company ",
“placeholder”: "company location,size,industry etc ",
“requiredField”: true
}
]
},
“options”: {}
},
“id”: “f72f38e9-b5b1-4481-8248-f568c8b20123”,
“name”: “Description of the audience you want to scrap”,
“type”: “n8n-nodes-base.formTrigger”,
“position”: [
368,
240
],
“webhookId”: “6aac0ee2-c7d7-427a-ad13-ff570c7f7209”,
“typeVersion”: 2.2
},
{
“parameters”: {
“modelId”: {
“__rl”: true,
“value”: “gpt-4.1-mini”,
“mode”: “list”,
“cachedResultName”: “GPT-4.1-MINI”
},
“messages”: {
“values”: [
{
“content”: “You are an expert system that translates marketing target descriptions into clean LinkedIn Sales Navigator search URLs.\n\nLook at the user’s description of who they want to scrape.\nReturn ONLY a raw JSON object containing the Sales Navigator search URL. Do not write any conversational text or explanation.\n\nUse this format:\n{\n "SearchUrl": "Sales Navigator}"\n}\n\nRules:\n1. Replace "YOUR_KEYWORDS" with the search keywords based on the user’s input.\n2. URL-encode any spaces (use %20 instead of spaces).\n3. Do not include cacheSig, sessionId, or recentSearchId in the URL. Keep it simple and clean.”
},
{
“content”: “your task is to take as input a prospect audience and turn that into a clean LinkedIn Sales Navigator search URL. Here is an example of the URL:\nSales Navigator URL describes a search for people on Sales Navigator matching the keywords "marketing wedding".\nYou can only make changes to the keywords field.\nReturn your response using this format: \n{"SearchUrl":"SearchUrlgoeshere"}”
},
{
“content”: “={{ $json['descritpion of the company '] }}”
}
]
},
“jsonOutput”: true,
“options”: {}
},
“id”: “bddc1d94-d65d-4d8f-811b-81a6c1d5f88f”,
“name”: “Genrating appolo Url for apify to scrap”,
“type”: “@n8n/n8n-nodes-langchain.openAi”,
“position”: [
608,
240
],
“typeVersion”: 1.8,
“credentials”: {
“openAiApi”: {
“id”: “X9bwAhk2O6t3iMa8”,
“name”: “OpenAI account”
}
}
},
{
“parameters”: {
“method”: “POST”,
“url”: “https://api.apify.com/v2/acts/harvestapi~linkedin-profile-search/runs”,
“authentication”: “genericCredentialType”,
“genericAuthType”: “httpHeaderAuth”,
“sendHeaders”: true,
“headerParameters”: {
“parameters”: [
{
“name”: “Accept”,
“value”: “application/json”
}
]
},
“sendBody”: true,
“specifyBody”: “json”,
“jsonBody”: “={\n "searchUrl": "{{ $json.message.content.SearchUrl }}"\n}”,
“options”: {}
},
“id”: “f85a5a7f-97b8-445d-bb39-40671595b72e”,
“name”: “Run apify actor to scrap the proscpect”,
“type”: “n8n-nodes-base.httpRequest”,
“position”: [
1008,
240
],
“typeVersion”: 4.2,
“credentials”: {
“httpHeaderAuth”: {
“id”: “EvHeJjRyMpemPQB9”,
“name”: “Header Auth account”
}
}
},
{
“parameters”: {
“modelId”: {
“__rl”: true,
“value”: “gpt-4.1-mini”,
“mode”: “list”,
“cachedResultName”: “GPT-4.1-MINI”
},
“messages”: {
“values”: [
{
“content”: "you are a helpful ",
“role”: “system”
},
{
“content”: “your task is to input a bunch of linkedin profile information of a user, and then geenrate a very short,very punchy incebreaker that i can use as a variable in my connection request \nreturn your output in this format \n{"Icebreaker":"Icebreakergoeshere"}\nin order to ensure icebreakers are punchy and high quality, make them follow this template \nHey {{name}}, loved seeing {{thingaboutThem}}, Im also into {{plausibleTieIN}}, thought Id connect.\nFor {{thingaboutThem}}and {{plausibleTiein}}, never use the exact information provided in a linked in field. instead,always parapharse. this makes it seems human written instead of just an automated message, Also, make it super short. Dont say stuff like "passionate about truning vision into reality " or anything like that be extremely Laconic and spartan.”
},
{
“content”: “{"LinkedInFields":"Danielle Morgan, Fort Lauderdale, Founder & CEO at DM Creative Agency, previous experience: Regional Sales Director at Out East Eyewear, Account Director at Radancy"}\n”
},
{
“content”: "map the prospect’s LinkedIn or details from the previous node. "
}
]
},
“options”: {}
},
“id”: “6cb4458f-c921-4e9b-ad10-581b47e42c2e”,
“name”: “Genrate ice breaker by scraping linkedin data”,
“type”: “@n8n/n8n-nodes-langchain.openAi”,
“position”: [
1216,
240
],
“typeVersion”: 1.8,
“credentials”: {
“openAiApi”: {
“id”: “X9bwAhk2O6t3iMa8”,
“name”: “OpenAI account”
}
}
},
{
“parameters”: {
“operation”: “append”,
“documentId”: {
“__rl”: true,
“value”: “1Dy7-fQHGk7dASHu6VfusQCrIMqH2KJWfmSvD-4DjR4c”,
“mode”: “list”,
“cachedResultName”: “Marketinf data1”,
“cachedResultUrl”: “https://docs.google.com/spreadsheets/d/1Dy7-fQHGk7dASHu6VfusQCrIMqH2KJWfmSvD-4DjR4c/edit?usp=drivesdk”
},
“sheetName”: {
“__rl”: true,
“value”: “gid=0”,
“mode”: “list”,
“cachedResultName”: “Sheet1”,
“cachedResultUrl”: “https://docs.google.com/spreadsheets/d/1Dy7-fQHGk7dASHu6VfusQCrIMqH2KJWfmSvD-4DjR4c/edit#gid=0”
},
“columns”: {
“mappingMode”: “autoMapInputData”,
“value”: {},
“matchingColumns”: ,
“schema”: [
{
“id”: “index”,
“displayName”: “index”,
“required”: false,
“defaultMatch”: false,
“display”: true,
“type”: “string”,
“canBeUsedToMatch”: true,
“removed”: false
},
{
“id”: “message”,
“displayName”: “message”,
“required”: false,
“defaultMatch”: false,
“display”: true,
“type”: “string”,
“canBeUsedToMatch”: true,
“removed”: false
},
{
“id”: “logprobs”,
“displayName”: “logprobs”,
“required”: false,
“defaultMatch”: false,
“display”: true,
“type”: “string”,
“canBeUsedToMatch”: true,
“removed”: false
},
{
“id”: “finish_reason”,
“displayName”: “finish_reason”,
“required”: false,
“defaultMatch”: false,
“display”: true,
“type”: “string”,
“canBeUsedToMatch”: true,
“removed”: false
}
],
“attemptToConvertTypes”: false,
“convertFieldsToString”: false
},
“options”: {}
},
“id”: “423b22af-c02f-4abc-a77e-8050dcca9c90”,
“name”: “Adding ice breaker to google sheets”,
“type”: “n8n-nodes-base.googleSheets”,
“position”: [
1600,
240
],
“typeVersion”: 4.6,
“credentials”: {
“googleSheetsOAuth2Api”: {
“id”: “e4oPTe5I3052Fn7l”,
“name”: “Google Sheets account”
}
}
},
{
“parameters”: {
“method”: “POST”,
“url”: “https://api.phantombuster.com/api/v2/(your agent id goes here)/launch”,
“sendHeaders”: true,
“headerParameters”: {
“parameters”: [
{
“name”: “X-Phantombuster-Key”,
“value”: “api key goes here”
}
]
},
“options”: {}
},
“id”: “642dd7d3-a634-4cb5-b930-1021a594413d”,
“name”: “trigger phantom buster to send personlized connection request”,
“type”: “n8n-nodes-base.httpRequest”,
“position”: [
2048,
240
],
“typeVersion”: 4.2
},
{
“parameters”: {
“content”: "Create a google sheet add relevant colums name,linkedin url,company website,description and oter coloums that are genrated by the apify node and map them accordingly ",
“height”: 336
},
“id”: “9f714cd6-82dd-4e85-b076-cf01542d8395”,
“name”: “Sticky Note”,
“type”: “n8n-nodes-base.stickyNote”,
“position”: [
1536,
96
],
“typeVersion”: 1
},
{
“parameters”: {
“content”: “Triggers the phantom buster a platform that sends linkedin connection requests. to your leads, you have to go to the api credentials to get the relevant url but i hvae harcoded one for the connection request and add your api key to the header, and the agent ID of the agent you are running will be available in the url of the agent in phantombuster thats it no body is needed.”,
“height”: 384
},
“id”: “bbd5ef47-3815-4157-9269-c558e0fe7d26”,
“name”: “Sticky Note1”,
“type”: “n8n-nodes-base.stickyNote”,
“position”: [
1968,
-16
],
“typeVersion”: 1
},
{
“parameters”: {
“content”: “Hard-coded the prompt for GPT4o to generate the icebreaker; alter the prompt according to your desired need”,
“height”: 304
},
“id”: “792ddc3b-1c38-4e7b-b84e-36c7009b6689”,
“name”: “Sticky Note2”,
“type”: “n8n-nodes-base.stickyNote”,
“position”: [
1232,
96
],
“typeVersion”: 1
},
{
“parameters”: {
“content”: "Send a request to run the apify actor that scrapes the leads; everything is configuered add your API key ",
“height”: 224
},
“id”: “7b0d00de-8404-4bb5-bd9b-9201bab7ef62”,
“name”: “Sticky Note3”,
“type”: “n8n-nodes-base.stickyNote”,
“position”: [
944,
144
],
“typeVersion”: 1
},
{
“parameters”: {
“content”: "Generates an Apollo URL,using GPT-4o, which will be scraped by apify actor to get the leads data. the url is generated by the information you input in the form. ",
“height”: 352
},
“id”: “de1af1ca-e857-4e37-8786-104300f73cad”,
“name”: “Sticky Note4”,
“type”: “n8n-nodes-base.stickyNote”,
“position”: [
624,
80
],
“typeVersion”: 1
}
],
“connections”: {
“Aggregate”: {
“main”: [
[
{
“node”: “trigger phantom buster to send personlized connection request”,
“type”: “main”,
“index”: 0
}
]
]
},
“Description of the audience you want to scrap”: {
“main”: [
[
{
“node”: “Genrating appolo Url for apify to scrap”,
“type”: “main”,
“index”: 0
}
]
]
},
“Genrating appolo Url for apify to scrap”: {
“main”: [
[
{
“node”: “Run apify actor to scrap the proscpect”,
“type”: “main”,
“index”: 0
},
{
“node”: “Genrate ice breaker by scraping linkedin data”,
“type”: “main”,
“index”: 0
}
]
]
},
“Run apify actor to scrap the proscpect”: {
“main”: [
[
{
“node”: “Genrate ice breaker by scraping linkedin data”,
“type”: “main”,
“index”: 0
}
]
]
},
“Genrate ice breaker by scraping linkedin data”: {
“main”: [
[
{
“node”: “Adding ice breaker to google sheets”,
“type”: “main”,
“index”: 0
}
]
]
},
“Adding ice breaker to google sheets”: {
“main”: [
[
{
“node”: “Aggregate”,
“type”: “main”,
“index”: 0
}
]
]
}
},
“pinData”: {},
“meta”: {
“templateId”: “7182”,
“templateCredsSetupCompleted”: true,
“instanceId”: “1e78b1373da4a45ed93f6951e503328c634cef8780946387f0609e0ba62d734e”
}
}