Génération de prospects Instagram qualifiés à partir de tags avec Apify et Google Sheets
Ceci est unLead Generation, Multimodal AIworkflow d'automatisation du domainecontenant 16 nœuds.Utilise principalement des nœuds comme If, Code, Aggregate, HttpRequest, GoogleSheets. Utiliser Apify et Google Sheets pour générer des prospects Instagram qualifiés à partir des hashtags
- •Peut nécessiter les informations d'identification d'authentification de l'API cible
- •Informations d'identification Google Sheets API
Catégorie
{
"meta": {
"instanceId": "3f9200fd36bb1bacb074812d319dd4fba325b9cd32ee87ee82b76f45271f5dfd"
},
"nodes": [
{
"id": "77e9fdfd-ee83-4394-a938-ceb6be4a58a8",
"name": "Lors du clic sur 'Exécuter le workflow'",
"type": "n8n-nodes-base.manualTrigger",
"position": [
-1840,
-32
],
"parameters": {},
"typeVersion": 1
},
{
"id": "04569eb9-91d9-4eda-a3b7-f1044b3aacf2",
"name": "make liens de hashtag",
"type": "n8n-nodes-base.code",
"position": [
-1216,
-32
],
"parameters": {
"jsCode": "// Mode: Run once for all items\nconst tags = $input.first().json.Hashtag || []; // [\"vegan\", \"travel\", …]\n\nconst startUrls = tags.map(\n t => `\"https://www.instagram.com/explore/tags/${encodeURIComponent(t)}/\"`\n);\n\n// Build the final body Apify expects\nreturn [{ // or delete if you don’t need the date filter\n startUrls // ← trailing slash now added\n // customMapFunction left out — see note below\n}];\n"
},
"typeVersion": 2
},
{
"id": "45305b08-fd9f-4872-b4e3-e37d38b866d0",
"name": "Scraper les posts du hashtag instagram",
"type": "n8n-nodes-base.httpRequest",
"position": [
-976,
-32
],
"parameters": {
"url": "https://api.apify.com/v2/acts/culc72xb7MP3EbaeX/run-sync-get-dataset-items",
"method": "POST",
"options": {
"redirect": {
"redirect": {}
}
},
"jsonBody": "={\n \"maxItems\": 300,\n \"startUrls\": [\n{{ $json.startUrls }}\n ],\n \"until\": \"2025-06-20\"\n}",
"sendBody": true,
"sendHeaders": true,
"specifyBody": "json",
"headerParameters": {
"parameters": [
{
"name": "Accept",
"value": "application/json"
},
{
"name": "Authorization",
"value": "Bearer APIFY_API_KEY"
}
]
}
},
"typeVersion": 4.2
},
{
"id": "067ed683-3a63-4d59-8c23-2bb87d8d3287",
"name": "SI — Hashtags uniquement",
"type": "n8n-nodes-base.if",
"position": [
-560,
-32
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 1,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "cond-only-hashtags",
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
},
"leftValue": "={{ $json.hasHashtags && ($json.textNoTags || '').trim() === '' }}"
}
]
}
},
"typeVersion": 2
},
{
"id": "43e985f4-579d-49ed-839c-7b5809d8ddd8",
"name": "SI — Anglais uniquement",
"type": "n8n-nodes-base.if",
"position": [
-352,
64
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 1,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "cond-english-only",
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
},
"leftValue": "={{ $json.enHits > 0 && $json.frHits === 0 && $json.esHits === 0 }}"
}
]
}
},
"typeVersion": 2
},
{
"id": "2b17b052-1474-40a3-8c86-6eb450969b2b",
"name": "Agréger les hashtags",
"type": "n8n-nodes-base.aggregate",
"position": [
-1424,
-32
],
"parameters": {
"options": {},
"fieldsToAggregate": {
"fieldToAggregate": [
{
"fieldToAggregate": "Hashtag"
}
]
}
},
"typeVersion": 1
},
{
"id": "9640b845-8f56-4dea-bcdc-f315e30b1224",
"name": "Formater les légendes, noms d'utilisateur et données",
"type": "n8n-nodes-base.code",
"position": [
-768,
-32
],
"parameters": {
"jsCode": "return items.map(item => {\n const json = item.json;\n // 1) Original caption or title\n const caption = json.caption || json.title || '';\n json.caption = caption;\n // 2) Count hashtags & strip them + strip URLs\n const hashtags = caption.match(/#\\S+/g) || [];\n json.hashtagCount = hashtags.length;\n json.hasHashtags = json.hashtagCount > 0;\n const noUrls = caption.replace(/https?:\\/\\/\\S+/gi, '');\n const textNoTags = noUrls.replace(/#[^\\s#]+/g, '').replace(/\\.{2,}/g, ' ').replace(/\\s+/g, ' ').trim();\n json.textNoTags = textNoTags;\n json.hasOnlyHashtags = json.hasHashtags && textNoTags === '';\n // 3) Word array (no numbers-only, min length 2)\n let words = textNoTags.toLowerCase().split(/\\W+/).filter(w => w.length > 1 && !/^\\d+$/.test(w));\n const totalWords = words.length;\n json.totalWords = totalWords;\n // 4) Keyword hit lists\n const enKw = ['the','and','to','of','in','for','on','with','is','are','this','that','it','be','at','by','from','as','was','were','have','has','you','we','i'];\n const frKw = ['le','la','les','des','un','une','du','de','et','en','dans','pour','avec','est','sur','au','aux','ce','cet','cette','ça','pas','plus','que','qui','où','je','tu','il','elle','nous','vous','ils','elles'];\n const esKw = ['el','la','los','las','de','del','y','en','por','para','con','es','un','una','que','como','muy','pero','si','porque'];\n json.enHits = words.filter(w => enKw.includes(w)).length;\n json.frHits = words.filter(w => frKw.includes(w)).length;\n json.esHits = words.filter(w => esKw.includes(w)).length;\n // 5) Ratios\n json.enRatio = totalWords ? json.enHits / totalWords : 0;\n json.frRatio = totalWords ? json.frHits / totalWords : 0;\n json.esRatio = totalWords ? json.esHits / totalWords : 0;\n // 6) ASCII vs non-ASCII\n const asciiCount = textNoTags.replace(/[^\\x00-\\x7F]/g, '').length;\n json.asciiRatio = textNoTags.length ? asciiCount / textNoTags.length : 0;\n // 7) Accent & script flags\n json.hasFrenchAccent = /[éèêëàâîïôöùûçœæ]/i.test(textNoTags);\n json.hasSpanishAccentStrict = /[ñ¡¿]/.test(textNoTags);\n json.hasArabicOrCJK = /[\\u0600-\\u06FF\\u0750-\\u077F\\u4E00-\\u9FFF\\u3040-\\u30FF\\uAC00-\\uD7AF]/u.test(textNoTags);\n return { json };\n});"
},
"typeVersion": 2
},
{
"id": "6626209f-fc93-4688-a41c-51606d03c887",
"name": "Combiner tous les noms d'utilisateur",
"type": "n8n-nodes-base.aggregate",
"position": [
112,
-64
],
"parameters": {
"options": {},
"fieldsToAggregate": {
"fieldToAggregate": [
{
"fieldToAggregate": "owner.username"
}
]
}
},
"typeVersion": 1
},
{
"id": "1d876779-5409-4214-b6b0-48276e44ab41",
"name": "Supprimer les noms d'utilisateur en double",
"type": "n8n-nodes-base.removeDuplicates",
"position": [
-112,
-64
],
"parameters": {
"compare": "selectedFields",
"options": {},
"fieldsToCompare": "owner.username"
},
"typeVersion": 2
},
{
"id": "12f7a1bd-4ce4-47c0-ae1d-2444ecd7ac6d",
"name": "Scraper les profils instagram",
"type": "n8n-nodes-base.httpRequest",
"position": [
384,
-64
],
"parameters": {
"url": "https://api.apify.com/v2/acts/dSCLg0C3YEZ83HzYX/run-sync-get-dataset-items",
"method": "POST",
"options": {
"redirect": {
"redirect": {}
}
},
"jsonBody": "={\n \"usernames\": [\n \t{{ $json.username.map(u => `\"${u}\"`).join(\", \") }}\n ]\n}",
"sendBody": true,
"sendHeaders": true,
"specifyBody": "json",
"headerParameters": {
"parameters": [
{
"name": "Accept",
"value": "application/json"
},
{
"name": "Authorization",
"value": "Bearer APIFY_API_KEY"
}
]
}
},
"typeVersion": 4.2
},
{
"id": "3288d091-4f14-4c7b-8813-7a4a2b64db66",
"name": "Si les abonnés sont dans une certaine plage, continuer",
"type": "n8n-nodes-base.if",
"position": [
592,
-64
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "7b585f6a-c548-4b62-a6e8-0bcf6c7ba771",
"operator": {
"type": "number",
"operation": "gte"
},
"leftValue": "={{ $json.followersCount }}",
"rightValue": 10000
},
{
"id": "4753a598-fe31-4670-99f2-a0d5ad164074",
"operator": {
"type": "number",
"operation": "lte"
},
"leftValue": "={{ $json.followersCount }}",
"rightValue": 100000
}
]
}
},
"typeVersion": 2.2
},
{
"id": "79d0609c-f68b-41fa-96ec-cc0676fdd706",
"name": "Obtenir la liste des hashtags",
"type": "n8n-nodes-base.googleSheets",
"position": [
-1632,
-32
],
"parameters": {
"options": {},
"sheetName": {
"__rl": true,
"mode": "id",
"value": "SHEET_ID"
},
"documentId": {
"__rl": true,
"mode": "id",
"value": "SPREADSHEET_ID"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"id": "MBFwnmyEV4r4PVbR",
"name": "Google Sheets account 2"
}
},
"typeVersion": 4.6
},
{
"id": "08bc2863-b41f-4e1d-99db-30e03b1b1c01",
"name": "Note adhésive",
"type": "n8n-nodes-base.stickyNote",
"position": [
-704,
-736
],
"parameters": {
"color": 5,
"width": 512,
"height": 240,
"content": "# Workflow Overview\n- Start: Get a list of hashtags from Google Sheets\n- Scrape Instagram posts for each hashtag (via Apify)\n- Analyze captions: extract keywords, check for language & hashtags\n- Gather/post-process usernames, scrape their profiles\n- Filter users based on followers count\n- Result: List of users meeting your criteria"
},
"typeVersion": 1
},
{
"id": "1066082c-43db-4e5b-b9be-4beb44d9061a",
"name": "Note adhésive1",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1680,
-272
],
"parameters": {
"color": 4,
"width": 528,
"height": 144,
"content": "## Read Hashtags & Prepare Instagram Links\n- Retrieve all hashtags from a Google Sheet\n- Build direct Instagram tag-explore URLs for each hashtag\n- Output is a list of start URLs for scraping Instagram hashtag feeds"
},
"typeVersion": 1
},
{
"id": "f5527a08-5916-4234-9225-835262206952",
"name": "Note adhésive2",
"type": "n8n-nodes-base.stickyNote",
"position": [
-752,
-288
],
"parameters": {
"color": 2,
"width": 560,
"height": 176,
"content": "## Analyze Post Captions\n- Extract and process each Instagram caption\n- Count & strip hashtags, links, and analyze language (English/French/Spanish) using keyword lists\n- Mark posts as 'hashtags only', and apply logic to filter for language or other text patterns"
},
"typeVersion": 1
},
{
"id": "4e0a1454-b1c2-4af2-b3f0-d3328d3956c4",
"name": "Note adhésive3",
"type": "n8n-nodes-base.stickyNote",
"position": [
112,
-288
],
"parameters": {
"color": 3,
"width": 592,
"content": "# Gather & Filter User Profiles\n- Combine all usernames from found posts, remove duplicates\n- Scrape profile details (like follower count) for each username\n- Only allow users whose follower counts are within a target range for your use case"
},
"typeVersion": 1
}
],
"pinData": {},
"connections": {
"2b17b052-1474-40a3-8c86-6eb450969b2b": {
"main": [
[
{
"node": "04569eb9-91d9-4eda-a3b7-f1044b3aacf2",
"type": "main",
"index": 0
}
]
]
},
"04569eb9-91d9-4eda-a3b7-f1044b3aacf2": {
"main": [
[
{
"node": "45305b08-fd9f-4872-b4e3-e37d38b866d0",
"type": "main",
"index": 0
}
]
]
},
"43e985f4-579d-49ed-839c-7b5809d8ddd8": {
"main": [
[
{
"node": "1d876779-5409-4214-b6b0-48276e44ab41",
"type": "main",
"index": 0
}
]
]
},
"79d0609c-f68b-41fa-96ec-cc0676fdd706": {
"main": [
[
{
"node": "2b17b052-1474-40a3-8c86-6eb450969b2b",
"type": "main",
"index": 0
}
]
]
},
"067ed683-3a63-4d59-8c23-2bb87d8d3287": {
"main": [
[
{
"node": "1d876779-5409-4214-b6b0-48276e44ab41",
"type": "main",
"index": 0
}
],
[
{
"node": "43e985f4-579d-49ed-839c-7b5809d8ddd8",
"type": "main",
"index": 0
}
]
]
},
"6626209f-fc93-4688-a41c-51606d03c887": {
"main": [
[
{
"node": "12f7a1bd-4ce4-47c0-ae1d-2444ecd7ac6d",
"type": "main",
"index": 0
}
]
]
},
"12f7a1bd-4ce4-47c0-ae1d-2444ecd7ac6d": {
"main": [
[
{
"node": "3288d091-4f14-4c7b-8813-7a4a2b64db66",
"type": "main",
"index": 0
}
]
]
},
"1d876779-5409-4214-b6b0-48276e44ab41": {
"main": [
[
{
"node": "6626209f-fc93-4688-a41c-51606d03c887",
"type": "main",
"index": 0
}
]
]
},
"45305b08-fd9f-4872-b4e3-e37d38b866d0": {
"main": [
[
{
"node": "9640b845-8f56-4dea-bcdc-f315e30b1224",
"type": "main",
"index": 0
}
]
]
},
"9640b845-8f56-4dea-bcdc-f315e30b1224": {
"main": [
[
{
"node": "067ed683-3a63-4d59-8c23-2bb87d8d3287",
"type": "main",
"index": 0
}
]
]
},
"77e9fdfd-ee83-4394-a938-ceb6be4a58a8": {
"main": [
[
{
"node": "79d0609c-f68b-41fa-96ec-cc0676fdd706",
"type": "main",
"index": 0
}
]
]
}
}
}Comment utiliser ce workflow ?
Copiez le code de configuration JSON ci-dessus, créez un nouveau workflow dans votre instance n8n et sélectionnez "Importer depuis le JSON", collez la configuration et modifiez les paramètres d'authentification selon vos besoins.
Dans quelles scénarios ce workflow est-il adapté ?
Avancé - Génération de leads, IA Multimodale
Est-ce payant ?
Ce workflow est entièrement gratuit et peut être utilisé directement. Veuillez noter que les services tiers utilisés dans le workflow (comme l'API OpenAI) peuvent nécessiter un paiement de votre part.
Workflows recommandés
Matthew
@matthew-synteriaPartager ce workflow