Hilfe benötigt: Warten auf Abschluss des Apify LinkedIn Scrapers vor Datenzuordnung zu AI und Sheets

Hallo zusammen,

Ich baue einen Lead-Generation- und Outreach-Workflow in n8n mit folgendem Setup:

  1. Datenquelle / Scraper: Auslösen eines Apify-Actors, um Prospect-URLs/Profile zu sammeln.

  2. KI-Node (Google Gemini): Verwendung von Google Gemini (statt OpenAI) zur Generierung von benutzerdefinierten Icebreakern/personalisierten Einleitungsnachrichten basierend auf Prospect-Details.

  3. Anreicherung (Lusha): Verwendung von Lusha (statt nur auf LinkedIn-Scraper-Daten zu verlassen), um verifizierte direkte Business-E-Mails und Kontaktdetails zu extrahieren.

  4. 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”
}
}

Hi @shahramphp Willkommen!
POST zu /runs startet den Actor und gibt das Run-Objekt sofort zurück, daher erhalten die Knoten danach Run-Metadaten, nicht Profile. Richte stattdessen diesen HTTP-Request-Knoten auf den Sync-Endpoint aus, der hält die Verbindung offen, bis der Run abgeschlossen ist, und gibt die Dataset-Elemente zurück:

https://api.apify.com/v2/acts/harvestapi~linkedin-profile-search/run-sync-get-dataset-items

Füge die Timeout-Option auf diesem Knoten hinzu und stelle sie auf 300000 ein, Apify bricht Sync-Runs nach 300 Sekunden ab. Bei Suchen, die länger dauern, verwende /runs und frag GET /v2/actor-runs/{runId} in einer Wait-Schleife ab, bis der Status SUCCEEDED ist, dann rufe das Dataset ab.
Lösche bei der Zuordnung die Verbindung, die von „Genrating appolo Url for apify to scrap

Ihr run-sync-get-dataset-items-Aufruf hat auf dem HTTP-Node keine Request-Timeout-Überschreibung, daher erhalten Sie einen falschen Fehler, wenn Apifys Actor länger dauert als n8ns eigener Standard-HTTP-Timeout, noch bevor Sie Apifys 300s-Limit erreichen. Setzen Sie beide: Apifys Timeout-Parameter in der URL/im Body (?timeout=300) und des Node-eigenen Options → Timeout auf etwas Höheres (z. B. 320000ms), damit n8n nicht zuerst aufgibt.

Hi @shahramphp! Ich wollte mal nachfragen, ob du das Problem lösen konntest? Falls nicht, gib mir Bescheid und ich kümmere mich mit dem Team darum.

Ansonsten: schönes Wochenende!

Jesse

@shahramphp bitte teile deinen Bildschirm, dann können wir dir die Lösung leichter geben