{ "id": "cQAILffOajE9n2cf", "meta": { "instanceId": "workflow-76c45099", "versionId": "1.0.0", "createdAt": "2025-09-29T07:07:55.774403", "updatedAt": "2025-09-29T07:07:55.774425", "owner": "n8n-user", "license": "MIT", "category": "automation", "status": "active", "priority": "high", "environment": "production" }, "name": "Generate Leads with Google Maps - AlexK1919", "tags": [ "automation", "n8n", "production-ready", "excellent", "optimized" ], "nodes": [ { "id": "edc9d8f5-e1f4-48e2-b7f7-36e53674d5b3", "name": "When clicking \"Execute Workflow\"", "type": "n8n-nodes-base.manualTrigger", "position": [ -1080, 540 ], "parameters": {}, "typeVersion": 1, "notes": "This manualTrigger node performs automated tasks as part of the workflow." }, { "id": "b761e882-298f-454e-8c21-f77b336ce54e", "name": "Run workflow every hours", "type": "n8n-nodes-base.scheduleTrigger", "disabled": true, "position": [ -1080, 360 ], "parameters": { "rule": { "interval": [ { "field": "minutes", "minutesInterval": 15 } ] } }, "typeVersion": 1.1, "notes": "This scheduleTrigger node performs automated tasks as part of the workflow." }, { "id": "63d30ea8-1e31-47d2-8f3a-6757f438ab8a", "name": "Execute Workflow Trigger", "type": "n8n-nodes-base.executeWorkflowTrigger", "disabled": true, "position": [ -1080, 200 ], "parameters": {}, "typeVersion": 1, "notes": "This executeWorkflowTrigger node performs automated tasks as part of the workflow." }, { "id": "10f40f60-c29f-47db-a4d1-3d0b8e8363d7", "name": "Check Max Retries1", "type": "n8n-nodes-base.if", "position": [ 1680, 740 ], "parameters": { "options": {}, "conditions": { "options": { "version": 2, "leftValue": "", "caseSensitive": true, "typeValidation": "strict" }, "combinator": "and", "conditions": [ { "id": "51e191cb-af20-423b-9303-8523caa4ae0d", "operator": { "type": "number", "operation": "gt" }, "leftValue": "={{ $('Exponential Backoff').item.json[\"retryCount\"] }}", "rightValue": 10 } ] } }, "typeVersion": 2.2, "notes": "This if node performs automated tasks as part of the workflow." }, { "id": "6665de66-8e00-4a45-b26a-93be044e9b8d", "name": "Stop and Error1", "type": "n8n-nodes-base.stopAndError", "position": [ 1880, 740 ], "parameters": { "errorMessage": "Google Sheets API Limit has been triggered and the workflow has stopped" }, "typeVersion": 1, "notes": "This stopAndError node performs automated tasks as part of the workflow." }, { "id": "f0b15937-3734-4cdf-9256-ae36e39a2046", "name": "GMaps API", "type": "n8n-nodes-base.httpRequest", "position": [ 80, 680 ], "parameters": { "url": "{{ $env.API_BASE_URL }}", "method": "POST", "options": { "response": { "response": { "fullResponse": true } } }, "sendBody": true, "sendHeaders": true, "authentication": "{{ $credentials.predefinedCredentialType }}", "bodyParameters": { "parameters": [ { "name": "textQuery", "value": "={{ $('Subcategory').item.json.Subcategory }} {{ $json.zip }}" } ] }, "headerParameters": { "parameters": [ { "name": "X-Goog-FieldMask", "value": "places.id,places.displayName,places.addressComponents,places.formattedAddress,places.primaryType,places.primaryTypeDisplayName,places.types,places.location,places.nationalPhoneNumber,places.rating,places.userRatingCount,places.websiteUri,places.editorialSummary,places.reviews,places.attributions,places.userRatingCount" } ] }, "nodeCredentialType": "YOUR_CREDENTIAL_HERE" }, "credentials": { "googleOAuth2Api": { "id": "mfmC5Vkz0fz2YJ77", "name": "KBB Google OAuth" } }, "typeVersion": 4.2, "notes": "This httpRequest node performs automated tasks as part of the workflow." }, { "id": "539bb125-173a-45b8-a6fc-0b755a013525", "name": "Update Status to Success", "type": "n8n-nodes-base.googleSheets", "onError": "continueErrorOutput", "position": [ 1520, 1160 ], "parameters": { "columns": { "value": { "zip": "={{ $('Set Zip').first().json.zip }}", "status": "scraped", "subcat": "={{ $('Subcategory').first().json.Subcategory }}" }, "schema": [ { "id": "zip", "type": "string", "display": true, "removed": false, "required": false, "displayName": "zip", "defaultMatch": false, "canBeUsedToMatch": true }, { "id": "status", "type": "string", "display": true, "removed": false, "required": false, "displayName": "status", "defaultMatch": false, "canBeUsedToMatch": true }, { "id": "subcat", "type": "string", "display": true, "removed": false, "required": false, "displayName": "subcat", "defaultMatch": false, "canBeUsedToMatch": true }, { "id": "row_number", "type": "string", "display": true, "removed": false, "readOnly": true, "required": false, "displayName": "row_number", "defaultMatch": false, "canBeUsedToMatch": true } ], "mappingMode": "defineBelow", "matchingColumns": [ "zip" ] }, "options": {}, "operation": "update", "sheetName": { "__rl": true, "mode": "name", "value": "={{ $('Settings').first().json.sheet }}" }, "documentId": { "__rl": true, "mode": "url", "value": "={{ $('Settings').first().json.gs_url }}" } }, "credentials": { "googleSheetsOAuth2Api": { "id": "OnIKN60kSWkHVPHx", "name": "Google Sheets - KBB" } }, "executeOnce": true, "typeVersion": 4.2, "alwaysOutputData": true, "notes": "This googleSheets node performs automated tasks as part of the workflow." }, { "id": "848b71e5-7ff5-4fb5-aad3-33b630ee42c8", "name": "Add rows in Google Sheets", "type": "n8n-nodes-base.googleSheets", "onError": "continueErrorOutput", "position": [ 1080, 740 ], "parameters": { "columns": { "value": { "type": "={{ $('Subcategory').item.json.Subcategory }}", "phone": "={{ $json.place.nationalPhoneNumber }}", "title": "={{ $json.place.displayName.text }}", "types": "={{ $json.place.types }}", "rating": "={{ $json.place.rating }}", "address": "={{ $json.place.formattedAddress }}", "reviews": "={{ $json.place.reviews }}", "website": "={{ $json.place.websiteUri }}", "place_id": "={{ $json.place.id }}", "gps_coordinates": "={\"latitude\":{{ $json.place.location.latitude }},\"longitude\":{{ $json.place.location.longitude }}}" }, "schema": [ { "id": "ACTION", "type": "string", "display": true, "required": false, "displayName": "ACTION", "defaultMatch": false, "canBeUsedToMatch": true }, { "id": "STATUS", "type": "string", "display": true, "required": false, "displayName": "STATUS", "defaultMatch": false, "canBeUsedToMatch": true }, { "id": "title", "type": "string", "display": true, "required": false, "displayName": "title", "defaultMatch": false, "canBeUsedToMatch": true }, { "id": "email", "type": "string", "display": true, "required": false, "displayName": "email", "defaultMatch": false, "canBeUsedToMatch": true }, { "id": "name", "type": "string", "display": true, "required": false, "displayName": "name", "defaultMatch": false, "canBeUsedToMatch": true }, { "id": "firstname", "type": "string", "display": true, "required": false, "displayName": "firstname", "defaultMatch": false, "canBeUsedToMatch": true }, { "id": "lastname", "type": "string", "display": true, "required": false, "displayName": "lastname", "defaultMatch": false, "canBeUsedToMatch": true }, { "id": "phone", "type": "string", "display": true, "required": false, "displayName": "phone", "defaultMatch": false, "canBeUsedToMatch": true }, { "id": "clean url", "type": "string", "display": true, "required": false, "displayName": "clean url", "defaultMatch": false, "canBeUsedToMatch": true }, { "id": "website", "type": "string", "display": true, "required": false, "displayName": "website", "defaultMatch": false, "canBeUsedToMatch": true }, { "id": "WP API", "type": "string", "display": true, "required": false, "displayName": "WP API", "defaultMatch": false, "canBeUsedToMatch": true }, { "id": "WP", "type": "string", "display": true, "required": false, "displayName": "WP", "defaultMatch": false, "canBeUsedToMatch": true }, { "id": "facebook", "type": "string", "display": true, "required": false, "displayName": "facebook", "defaultMatch": false, "canBeUsedToMatch": true }, { "id": "instagram", "type": "string", "display": true, "required": false, "displayName": "instagram", "defaultMatch": false, "canBeUsedToMatch": true }, { "id": "youtube", "type": "string", "display": true, "required": false, "displayName": "youtube", "defaultMatch": false, "canBeUsedToMatch": true }, { "id": "tiktok", "type": "string", "display": true, "required": false, "displayName": "tiktok", "defaultMatch": false, "canBeUsedToMatch": true }, { "id": "twitter", "type": "string", "display": true, "required": false, "displayName": "twitter", "defaultMatch": false, "canBeUsedToMatch": true }, { "id": "linkedin", "type": "string", "display": true, "required": false, "displayName": "linkedin", "defaultMatch": false, "canBeUsedToMatch": true }, { "id": "pinterest", "type": "string", "display": true, "required": false, "displayName": "pinterest", "defaultMatch": false, "canBeUsedToMatch": true }, { "id": "reddit", "type": "string", "display": true, "required": false, "displayName": "reddit", "defaultMatch": false, "canBeUsedToMatch": true }, { "id": "rating", "type": "string", "display": true, "required": false, "displayName": "rating", "defaultMatch": false, "canBeUsedToMatch": true }, { "id": "reviews", "type": "string", "display": true, "required": false, "displayName": "reviews", "defaultMatch": false, "canBeUsedToMatch": true }, { "id": "type", "type": "string", "display": true, "required": false, "displayName": "type", "defaultMatch": false, "canBeUsedToMatch": true }, { "id": "address", "type": "string", "display": true, "required": false, "displayName": "address", "defaultMatch": false, "canBeUsedToMatch": true }, { "id": "price", "type": "string", "display": true, "required": false, "displayName": "price", "defaultMatch": false, "canBeUsedToMatch": true }, { "id": "place_id", "type": "string", "display": true, "removed": false, "required": false, "displayName": "place_id", "defaultMatch": false, "canBeUsedToMatch": true }, { "id": "position", "type": "string", "display": true, "required": false, "displayName": "position", "defaultMatch": false, "canBeUsedToMatch": true }, { "id": "data_id", "type": "string", "display": true, "required": false, "displayName": "data_id", "defaultMatch": false, "canBeUsedToMatch": true }, { "id": "data_cid", "type": "string", "display": true, "required": false, "displayName": "data_cid", "defaultMatch": false, "canBeUsedToMatch": true }, { "id": "reviews_link", "type": "string", "display": true, "required": false, "displayName": "reviews_link", "defaultMatch": false, "canBeUsedToMatch": true }, { "id": "photos_link", "type": "string", "display": true, "required": false, "displayName": "photos_link", "defaultMatch": false, "canBeUsedToMatch": true }, { "id": "gps_coordinates", "type": "string", "display": true, "required": false, "displayName": "gps_coordinates", "defaultMatch": false, "canBeUsedToMatch": true }, { "id": "place_id_search", "type": "string", "display": true, "required": false, "displayName": "place_id_search", "defaultMatch": false, "canBeUsedToMatch": true }, { "id": "provider_id", "type": "string", "display": true, "required": false, "displayName": "provider_id", "defaultMatch": false, "canBeUsedToMatch": true }, { "id": "types", "type": "string", "display": true, "required": false, "displayName": "types", "defaultMatch": false, "canBeUsedToMatch": true }, { "id": "open_state", "type": "string", "display": true, "required": false, "displayName": "open_state", "defaultMatch": false, "canBeUsedToMatch": true }, { "id": "hours", "type": "string", "display": true, "required": false, "displayName": "hours", "defaultMatch": false, "canBeUsedToMatch": true }, { "id": "operating_hours", "type": "string", "display": true, "required": false, "displayName": "operating_hours", "defaultMatch": false, "canBeUsedToMatch": true }, { "id": "description", "type": "string", "display": true, "required": false, "displayName": "description", "defaultMatch": false, "canBeUsedToMatch": true }, { "id": "service_options", "type": "string", "display": true, "required": false, "displayName": "service_options", "defaultMatch": false, "canBeUsedToMatch": true }, { "id": "order_online", "type": "string", "display": true, "required": false, "displayName": "order_online", "defaultMatch": false, "canBeUsedToMatch": true }, { "id": "thumbnail", "type": "string", "display": true, "required": false, "displayName": "thumbnail", "defaultMatch": false, "canBeUsedToMatch": true }, { "id": "editorial_reviews", "type": "string", "display": true, "required": false, "displayName": "editorial_reviews", "defaultMatch": false, "canBeUsedToMatch": true }, { "id": "unclaimed_listing", "type": "string", "display": true, "required": false, "displayName": "unclaimed_listing", "defaultMatch": false, "canBeUsedToMatch": true }, { "id": "reserve_a_table", "type": "string", "display": true, "required": false, "displayName": "reserve_a_table", "defaultMatch": false, "canBeUsedToMatch": true }, { "id": "user_review", "type": "string", "display": true, "required": false, "displayName": "user_review", "defaultMatch": false, "canBeUsedToMatch": true }, { "id": "amenities", "type": "string", "display": true, "required": false, "displayName": "amenities", "defaultMatch": false, "canBeUsedToMatch": true }, { "id": "book_online", "type": "string", "display": true, "required": false, "displayName": "book_online", "defaultMatch": false, "canBeUsedToMatch": true } ], "mappingMode": "defineBelow", "matchingColumns": [ "place_id" ] }, "options": {}, "operation": "appendOrUpdate", "sheetName": { "__rl": true, "mode": "name", "value": "=Results" }, "documentId": { "__rl": true, "mode": "url", "value": "={{ $('Settings').item.json.gs_url }}" } }, "credentials": { "googleSheetsOAuth2Api": { "id": "OnIKN60kSWkHVPHx", "name": "Google Sheets - KBB" } }, "typeVersion": 4.2, "alwaysOutputData": true, "notes": "This googleSheets node performs automated tasks as part of the workflow." }, { "id": "4e1e9438-8091-4cf6-8a99-179960a35eae", "name": "Set Row Number", "type": "n8n-nodes-base.set", "position": [ 80, 80 ], "parameters": { "options": {}, "assignments": { "assignments": [ { "id": "4c5ad6be-28aa-455f-8ee2-edce1ab1bdbb", "name": "row_number", "type": "number", "value": "={{ $json.row_number }}" } ] }, "includeOtherFields": true }, "typeVersion": 3.4, "notes": "This set node performs automated tasks as part of the workflow." }, { "id": "a1939e46-7a56-4e41-9f12-86e784acd044", "name": "Set Zip", "type": "n8n-nodes-base.set", "position": [ -120, 680 ], "parameters": { "options": {}, "assignments": { "assignments": [ { "id": "7b1629c5-cbfe-4769-8286-66b46c51cd7e", "name": "zip", "type": "number", "value": "={{ $('Loop Zips').first().json.zip }}" } ] }, "includeOtherFields": true }, "typeVersion": 3.4, "notes": "This set node performs automated tasks as part of the workflow." }, { "id": "062d2c9f-f957-43ee-9fc2-2a8600828b58", "name": "Set Place ID", "type": "n8n-nodes-base.set", "position": [ 680, 740 ], "parameters": { "options": {}, "assignments": { "assignments": [ { "id": "758ff896-7cd8-4f72-bfbb-e64583c5937c", "name": "places.id", "type": "string", "value": "={{ $json.place.id }}" } ] }, "includeOtherFields": true }, "typeVersion": 3.4, "notes": "This set node performs automated tasks as part of the workflow." }, { "id": "0e3f4e19-0067-4233-afa8-1b9dd0a6bf30", "name": "Exponential Backoff", "type": "n8n-nodes-base.code", "position": [ 1280, 740 ], "parameters": { "mode": "runOnceForEachItem", "jsCode": "// Define the retry count (coming from a previous node or set manually)\nconst retryCount = $json[\"retryCount\"] || 0; // If not present, default to 0\nconst maxRetries = 5; // Define the maximum number of retries\nconst initialDelay = 1; // Initial delay in seconds (1 second)\n\n// If the retry count is less than the max retries, calculate the delay\nif (retryCount < maxRetries) {\n const currentDelayInSeconds = initialDelay * Math.pow(2, retryCount); // Exponential backoff delay in seconds\n \n // Log the delay time for debugging\n console.log(`Waiting for ${currentDelayInSeconds} seconds before retry...`);\n \n return {\n json: {\n retryCount: retryCount + 1, // Increment retry count\n waitTimeInSeconds: currentDelayInSeconds, // Pass the delay time in seconds\n status: 'retrying',\n }\n };\n} else {\n // If max retries are exceeded, return a failure response\n return {\n json: {\n error: 'Max retries exceeded',\n retryCount: retryCount,\n status: 'failed'\n }\n };\n}\n" }, "typeVersion": 2, "notes": "This code node performs automated tasks as part of the workflow." }, { "id": "68e13297-e299-4218-a02e-354c4bdd61db", "name": "Remove Duplicates", "type": "n8n-nodes-base.removeDuplicates", "position": [ 880, 740 ], "parameters": { "compare": "selectedFields", "options": {}, "fieldsToCompare": "place.id,places.id" }, "typeVersion": 1.1, "notes": "This removeDuplicates node performs automated tasks as part of the workflow." }, { "id": "ee71fd03-8e15-4c38-b10a-8ff5853da476", "name": "Wait", "type": "n8n-nodes-base.wait", "position": [ 1480, 740 ], "webhookId": "e0cf8da3-e4ab-490e-abcd-0c0c55b90846", "parameters": { "amount": "={{ $json[\"waitTime\"] }}" }, "typeVersion": 1.1, "notes": "This wait node performs automated tasks as part of the workflow." }, { "id": "761d8d0e-c185-41a5-9a75-53e51ab67add", "name": "Check Max Retries", "type": "n8n-nodes-base.if", "position": [ 2120, 1160 ], "parameters": { "options": {}, "conditions": { "options": { "version": 2, "leftValue": "", "caseSensitive": true, "typeValidation": "strict" }, "combinator": "and", "conditions": [ { "id": "51e191cb-af20-423b-9303-8523caa4ae0d", "operator": { "type": "number", "operation": "gt" }, "leftValue": "={{ $('Exponential Backoff1').item.json[\"retryCount\"] }}", "rightValue": 10 } ] } }, "typeVersion": 2.2, "notes": "This if node performs automated tasks as part of the workflow." }, { "id": "d8fa857a-e195-405c-ae15-44fecd3fea3e", "name": "Stop and Error", "type": "n8n-nodes-base.stopAndError", "position": [ 2320, 1160 ], "parameters": { "errorMessage": "Google Sheets API Limit has been triggered and the workflow has stopped" }, "typeVersion": 1, "notes": "This stopAndError node performs automated tasks as part of the workflow." }, { "id": "127dc44e-dd79-4735-b818-b95ec00184f2", "name": "Exponential Backoff1", "type": "n8n-nodes-base.code", "position": [ 1720, 1160 ], "parameters": { "mode": "runOnceForEachItem", "jsCode": "// Define the retry count (coming from a previous node or set manually)\nconst retryCount = $json[\"retryCount\"] || 0; // If not present, default to 0\nconst maxRetries = 5; // Define the maximum number of retries\nconst initialDelay = 1; // Initial delay in seconds (1 second)\n\n// If the retry count is less than the max retries, calculate the delay\nif (retryCount < maxRetries) {\n const currentDelayInSeconds = initialDelay * Math.pow(2, retryCount); // Exponential backoff delay in seconds\n \n // Log the delay time for debugging\n console.log(`Waiting for ${currentDelayInSeconds} seconds before retry...`);\n \n return {\n json: {\n retryCount: retryCount + 1, // Increment retry count\n waitTimeInSeconds: currentDelayInSeconds, // Pass the delay time in seconds\n status: 'retrying',\n }\n };\n} else {\n // If max retries are exceeded, return a failure response\n return {\n json: {\n error: 'Max retries exceeded',\n retryCount: retryCount,\n status: 'failed'\n }\n };\n}\n" }, "typeVersion": 2, "notes": "This code node performs automated tasks as part of the workflow." }, { "id": "fb7e37c4-f0b3-4a19-a4cc-29fd0c158f9d", "name": "Wait1", "type": "n8n-nodes-base.wait", "position": [ 1920, 1160 ], "webhookId": "670750d4-0c4d-4fff-b139-1d60be1eac68", "parameters": { "amount": "={{ $json[\"waitTime\"] }}" }, "typeVersion": 1.1, "notes": "This wait node performs automated tasks as part of the workflow." }, { "id": "520c9d50-bf23-402f-abf2-cb107341da4d", "name": "Settings", "type": "n8n-nodes-base.set", "position": [ -800, 360 ], "parameters": { "options": {}, "assignments": { "assignments": [ { "id": "fa469a25-eb00-4011-a626-87fae7fb8bbd", "name": "gs_url", "type": "string", "value": "{{ $env.WEBHOOK_URL }}" }, { "id": "df0a7a51-0ec6-47d2-9f73-bc8268385305", "name": "catSheet", "type": "string", "value": "Google Maps Categories" }, { "id": "a1ff9a58-9ae6-4000-9fcd-6c11de23bd48", "name": "sheet", "type": "string", "value": "AZ Zips" } ] } }, "typeVersion": 3.4, "notes": "This set node performs automated tasks as part of the workflow." }, { "id": "1e9c68db-5ccd-4db7-a469-47aabb38dca1", "name": "GS - Get Subcategory", "type": "n8n-nodes-base.googleSheets", "position": [ -220, 340 ], "parameters": { "options": {}, "sheetName": { "__rl": true, "mode": "name", "value": "={{ $('Settings').item.json.catSheet }}" }, "documentId": { "__rl": true, "mode": "url", "value": "={{ $('Settings').item.json.gs_url }}" } }, "credentials": { "googleSheetsOAuth2Api": { "id": "OnIKN60kSWkHVPHx", "name": "Google Sheets - KBB" } }, "executeOnce": true, "typeVersion": 4.2, "notes": "This googleSheets node performs automated tasks as part of the workflow." }, { "id": "e822be8c-ac7e-472e-a6e6-8835a1001323", "name": "Subcategory", "type": "n8n-nodes-base.set", "position": [ 180, 340 ], "parameters": { "options": {}, "assignments": { "assignments": [ { "id": "d3470f6f-c66e-4223-bbf5-81e45201d45d", "name": "Subcategory", "type": "string", "value": "={{ $json.Subcategory }}" } ] }, "includeOtherFields": true }, "typeVersion": 3.4, "notes": "This set node performs automated tasks as part of the workflow." }, { "id": "003af494-cb09-441b-87c7-43d7d98682e6", "name": "GS - Get Zip Codes", "type": "n8n-nodes-base.googleSheets", "position": [ -520, 80 ], "parameters": { "options": {}, "sheetName": { "__rl": true, "mode": "name", "value": "={{ $('Settings').item.json.sheet }}" }, "documentId": { "__rl": true, "mode": "url", "value": "={{ $('Settings').item.json.gs_url }}" } }, "credentials": { "googleSheetsOAuth2Api": { "id": "OnIKN60kSWkHVPHx", "name": "Google Sheets - KBB" } }, "executeOnce": true, "typeVersion": 4.2, "notes": "This googleSheets node performs automated tasks as part of the workflow." }, { "id": "cccc740e-55e5-4a64-b7f1-b1ca3fbb236e", "name": "Place Array", "type": "n8n-nodes-base.code", "position": [ 480, 740 ], "parameters": { "jsCode": "// Get the places array from the input data\nconst places = items[0]?.json?.body?.places || [];\n\n// Create an output array to hold each place as a separate item\nlet output = [];\n\nif (places.length > 0) {\n for (let i = 0; i < places.length; i++) {\n // For each place, push a new item into the output array\n output.push({\n json: {\n place: places[i], // The individual place object\n otherData: items[0].json.otherData || null // Include other data or default to null\n }\n });\n }\n} else {\n // Log an error or handle the case where places array is empty or undefined\n console.log('Places array is empty or undefined.');\n}\n\n// Return the output array, so each place becomes its own item\nreturn output;\n" }, "typeVersion": 2, "notes": "This code node performs automated tasks as part of the workflow." }, { "id": "4cd6a14a-084f-4389-90c5-f4d5921fc80d", "name": "Loop Zips", "type": "n8n-nodes-base.splitInBatches", "position": [ -420, 280 ], "parameters": { "options": {} }, "typeVersion": 3, "notes": "This splitInBatches node performs automated tasks as part of the workflow." }, { "id": "33bbb601-86ad-40b2-94fc-ccb7753d690e", "name": "Loop Subcats", "type": "n8n-nodes-base.splitInBatches", "position": [ -320, 620 ], "parameters": { "options": {} }, "typeVersion": 3, "notes": "This splitInBatches node performs automated tasks as part of the workflow." }, { "id": "fc1f56d7-ac1c-4447-a897-5b48ab4be430", "name": "GS - Get Status", "type": "n8n-nodes-base.googleSheets", "onError": "continueErrorOutput", "position": [ 1280, 960 ], "parameters": { "options": {}, "sheetName": { "__rl": true, "mode": "name", "value": "={{ $('Settings').first().json.sheet }}" }, "documentId": { "__rl": true, "mode": "url", "value": "={{ $('Settings').first().json.gs_url }}" } }, "credentials": { "googleSheetsOAuth2Api": { "id": "OnIKN60kSWkHVPHx", "name": "Google Sheets - KBB" } }, "executeOnce": true, "typeVersion": 4.2, "notes": "This googleSheets node performs automated tasks as part of the workflow." }, { "id": "04e698d9-2455-4884-8f95-e2a9dbc16d57", "name": "Check Max Retries2", "type": "n8n-nodes-base.if", "position": [ 1880, 960 ], "parameters": { "options": {}, "conditions": { "options": { "version": 2, "leftValue": "", "caseSensitive": true, "typeValidation": "strict" }, "combinator": "and", "conditions": [ { "id": "51e191cb-af20-423b-9303-8523caa4ae0d", "operator": { "type": "number", "operation": "gt" }, "leftValue": "={{ $('Exponential Backoff2').item.json[\"retryCount\"] }}", "rightValue": 10 } ] } }, "typeVersion": 2.2, "notes": "This if node performs automated tasks as part of the workflow." }, { "id": "be784eb9-1d18-4ddc-a91a-1a78355eabed", "name": "Stop and Error2", "type": "n8n-nodes-base.stopAndError", "position": [ 2080, 960 ], "parameters": { "errorMessage": "Google Sheets API Limit has been triggered and the workflow has stopped" }, "typeVersion": 1, "notes": "This stopAndError node performs automated tasks as part of the workflow." }, { "id": "3226891f-2e03-442e-9be3-7bc41d067d23", "name": "Exponential Backoff2", "type": "n8n-nodes-base.code", "position": [ 1480, 960 ], "parameters": { "mode": "runOnceForEachItem", "jsCode": "// Define the retry count (coming from a previous node or set manually)\nconst retryCount = $json[\"retryCount\"] || 0; // If not present, default to 0\nconst maxRetries = 5; // Define the maximum number of retries\nconst initialDelay = 1; // Initial delay in seconds (1 second)\n\n// If the retry count is less than the max retries, calculate the delay\nif (retryCount < maxRetries) {\n const currentDelayInSeconds = initialDelay * Math.pow(2, retryCount); // Exponential backoff delay in seconds\n \n // Log the delay time for debugging\n console.log(`Waiting for ${currentDelayInSeconds} seconds before retry...`);\n \n return {\n json: {\n retryCount: retryCount + 1, // Increment retry count\n waitTimeInSeconds: currentDelayInSeconds, // Pass the delay time in seconds\n status: 'retrying',\n }\n };\n} else {\n // If max retries are exceeded, return a failure response\n return {\n json: {\n error: 'Max retries exceeded',\n retryCount: retryCount,\n status: 'failed'\n }\n };\n}\n" }, "typeVersion": 2, "notes": "This code node performs automated tasks as part of the workflow." }, { "id": "04435aaa-0ba7-45f9-80a7-248fbd47ff0e", "name": "Wait2", "type": "n8n-nodes-base.wait", "position": [ 1680, 960 ], "webhookId": "d9b32a26-861f-46d5-a8d7-0ede2ea37fe6", "parameters": { "amount": "={{ $json[\"waitTime\"] }}" }, "typeVersion": 1.1, "notes": "This wait node performs automated tasks as part of the workflow." }, { "id": "4c246eb7-5ec2-4c89-b0c0-c851cb318c34", "name": "Limit", "type": "n8n-nodes-base.limit", "position": [ 500, 80 ], "parameters": { "maxItems": 3 }, "typeVersion": 1, "notes": "This limit node performs automated tasks as part of the workflow." }, { "id": "b141c344-c011-41b2-b87d-b5a067e37c0f", "name": "Sticky Note20", "type": "n8n-nodes-base.stickyNote", "position": [ -1420, 0 ], "parameters": { "color": 6, "width": 250, "height": 1390, "content": "# AlexK1919 \n![Alex Kim]({{ $env.WEBHOOK_URL }}\n\n#### I’m Alex Kim, an AI-Native Workflow Automation Architect Building Solutions to Optimize your Personal and Professional Life.\n\n\n### About Me\n{{ $env.WEBHOOK_URL }}\n\n\n### Products Used \n[Google Maps API via Google Cloud Account]({{ $env.WEBHOOK_URL }}\n" }, "typeVersion": 1, "notes": "This stickyNote node performs automated tasks as part of the workflow." }, { "id": "3fd43827-bc14-4337-89d3-2e48fc010e9f", "name": "Sticky Note8", "type": "n8n-nodes-base.stickyNote", "position": [ -860, 0 ], "parameters": { "color": 3, "width": 247, "height": 1391, "content": "# Settings" }, "typeVersion": 1, "notes": "This stickyNote node performs automated tasks as part of the workflow." }, { "id": "c4ddef39-75e4-4a04-808c-2057ed59eddf", "name": "Sticky Note15", "type": "n8n-nodes-base.stickyNote", "position": [ -860, 80 ], "parameters": { "color": 7, "width": 219, "height": 220, "content": "In the Google Sheets document, set the subcategories you'd like to search for\n\nSet the URL of your Google Sheets document\n\nSet the Zip Code sheet name" }, "typeVersion": 1, "notes": "This stickyNote node performs automated tasks as part of the workflow." }, { "id": "b02c6a3a-3939-469a-bb50-0417cf2bc3c5", "name": "Sticky Note", "type": "n8n-nodes-base.stickyNote", "position": [ -1140, 0 ], "parameters": { "color": 7, "width": 247, "height": 1391, "content": "# Triggers" }, "typeVersion": 1, "notes": "This stickyNote node performs automated tasks as part of the workflow." }, { "id": "0aeeaed1-e0dd-4837-ba69-31e0205ea824", "name": "Zips", "type": "n8n-nodes-base.set", "position": [ -320, 80 ], "parameters": { "options": {}, "assignments": { "assignments": [ { "id": "3d16d922-0ed3-4a0f-9707-43797438970d", "name": "zip", "type": "number", "value": "={{ $json.zip }}" } ] }, "includeOtherFields": true }, "typeVersion": 3.4, "notes": "This set node performs automated tasks as part of the workflow." }, { "id": "e186129c-202b-409a-8028-e7434ab70093", "name": "Sticky Note1", "type": "n8n-nodes-base.stickyNote", "position": [ -580, 520 ], "parameters": { "color": 5, "width": 3060, "height": 880, "content": "# Google Maps API" }, "typeVersion": 1, "notes": "This stickyNote node performs automated tasks as part of the workflow." }, { "id": "6e142b17-55e7-4a2f-ae2a-829edd330aad", "name": "Filter Zips", "type": "n8n-nodes-base.filter", "position": [ -120, 80 ], "parameters": { "options": {}, "conditions": { "options": { "version": 2, "leftValue": "", "caseSensitive": true, "typeValidation": "strict" }, "combinator": "and", "conditions": [ { "id": "9f5a5e37-faae-45db-8a22-ad7d5786ecfe", "operator": { "type": "string", "operation": "empty", "singleValue": true }, "leftValue": "={{ $json.status }}", "rightValue": "" } ] } }, "typeVersion": 2.2, "notes": "This filter node performs automated tasks as part of the workflow." }, { "id": "077dc67e-eab4-413a-8f17-a17b298bf3f4", "name": "Filter Subcategories", "type": "n8n-nodes-base.filter", "position": [ -20, 340 ], "parameters": { "options": {}, "conditions": { "options": { "version": 2, "leftValue": "", "caseSensitive": true, "typeValidation": "strict" }, "combinator": "and", "conditions": [ { "id": "b64333b6-67ce-47c4-a2cc-07303278d178", "operator": { "type": "string", "operation": "notEquals" }, "leftValue": "={{ $json.STATUS }}", "rightValue": "Ignore" } ] } }, "typeVersion": 2.2, "notes": "This filter node performs automated tasks as part of the workflow." }, { "id": "2d5f5e14-4958-4b60-9ae3-b66a7ad095e9", "name": "If Empty", "type": "n8n-nodes-base.if", "position": [ 280, 680 ], "parameters": { "options": {}, "conditions": { "options": { "version": 2, "leftValue": "", "caseSensitive": true, "typeValidation": "strict" }, "combinator": "and", "conditions": [ { "id": "7424452f-e208-4e7e-8144-d0c6278bc0f0", "operator": { "type": "object", "operation": "empty", "singleValue": true }, "leftValue": "={{ $json.body }}", "rightValue": "" } ] } }, "typeVersion": 2.2, "notes": "This if node performs automated tasks as part of the workflow." }, { "id": "594eee9f-35d2-4b7f-8926-47010891298b", "name": "Split Out", "type": "n8n-nodes-base.splitOut", "position": [ 300, 80 ], "parameters": { "include": "allOtherFields", "options": {}, "fieldToSplitOut": "row_number" }, "typeVersion": 1, "notes": "This splitOut node performs automated tasks as part of the workflow." }, { "id": "2402643d-605e-40d8-b4ed-1678a144960b", "name": "Sticky Note2", "type": "n8n-nodes-base.stickyNote", "position": [ -580, 0 ], "parameters": { "color": 4, "width": 3060, "height": 500, "content": "# Data Prep" }, "typeVersion": 1, "notes": "This stickyNote node performs automated tasks as part of the workflow." } ], "active": false, "pinData": {}, "settings": { "executionOrder": "v1", "saveManualExecutions": true, "callerPolicy": "workflowsFromSameOwner", "errorWorkflow": null, "timezone": "UTC", "executionTimeout": 3600, "maxExecutions": 1000, "retryOnFail": true, "retryCount": 3, "retryDelay": 1000 }, "versionId": "5b91dfd7-b915-46b5-a195-c6cfa0d90dc6", "connections": { "f0b15937-3734-4cdf-9256-ae36e39a2046": { "main": [ [ { "node": "error-handler-f0b15937-3734-4cdf-9256-ae36e39a2046-4da3be27", "type": "main", "index": 0 } ], [ { "node": "error-handler-f0b15937-3734-4cdf-9256-ae36e39a2046-e4b97923", "type": "main", "index": 0 } ], [ { "node": "error-handler-f0b15937-3734-4cdf-9256-ae36e39a2046-060ef151", "type": "main", "index": 0 } ], [ { "node": "error-handler-f0b15937-3734-4cdf-9256-ae36e39a2046-4c676c2a", "type": "main", "index": 0 } ], [ { "node": "error-handler-f0b15937-3734-4cdf-9256-ae36e39a2046-c1938c4d", "type": "main", "index": 0 } ], [ { "node": "error-handler-f0b15937-3734-4cdf-9256-ae36e39a2046-c2ad9f61", "type": "main", "index": 0 } ], [ { "node": "error-handler-f0b15937-3734-4cdf-9256-ae36e39a2046-fa478057", "type": "main", "index": 0 } ], [ { "node": "error-handler-f0b15937-3734-4cdf-9256-ae36e39a2046-cfc7f7cc", "type": "main", "index": 0 } ] ] }, "539bb125-173a-45b8-a6fc-0b755a013525": { "main": [ [ { "node": "error-handler-539bb125-173a-45b8-a6fc-0b755a013525-62c1cdc4", "type": "main", "index": 0 } ] ] }, "848b71e5-7ff5-4fb5-aad3-33b630ee42c8": { "main": [ [ { "node": "error-handler-848b71e5-7ff5-4fb5-aad3-33b630ee42c8-0273a4af", "type": "main", "index": 0 } ] ] }, "1e9c68db-5ccd-4db7-a469-47aabb38dca1": { "main": [ [ { "node": "error-handler-1e9c68db-5ccd-4db7-a469-47aabb38dca1-8c1c00d9", "type": "main", "index": 0 } ] ] }, "003af494-cb09-441b-87c7-43d7d98682e6": { "main": [ [ { "node": "error-handler-003af494-cb09-441b-87c7-43d7d98682e6-91b09a97", "type": "main", "index": 0 } ] ] }, "fc1f56d7-ac1c-4447-a897-5b48ab4be430": { "main": [ [ { "node": "error-handler-fc1f56d7-ac1c-4447-a897-5b48ab4be430-570c1ae4", "type": "main", "index": 0 } ] ] } }, "description": "Automated workflow: Generate Leads with Google Maps - AlexK1919. This workflow integrates 16 different services: stickyNote, httpRequest, filter, wait, splitInBatches. It contains 48 nodes and follows best practices for error handling and security.", "notes": "Excellent quality workflow: Generate Leads with Google Maps - AlexK1919. This workflow has been optimized for production use with comprehensive error handling, security, and documentation." }