AI-Powered Google Maps Business Scraper with Enrichment Export to Google Sheets

    Shared 10/1/2025

    342 views

    Visual Workflow

    JSON Code

    {
      "meta": {},
      "nodes": [
        {
          "id": "79df5316-c210-478d-a4de-35b5d31924ee",
          "name": "Remove Duplicate URLs",
          "type": "n8n-nodes-base.removeDuplicates",
          "position": [
            2000,
            980
          ],
          "parameters": {},
          "typeVersion": 1.1
        },
        {
          "id": "985ac7e3-b501-4079-a043-780677c94b52",
          "name": "Loop over queries",
          "type": "n8n-nodes-base.splitInBatches",
          "position": [
            1500,
            580
          ],
          "parameters": {
            "options": {}
          },
          "typeVersion": 3
        },
        {
          "id": "3a478935-781b-4fb1-bdc7-fcf8be1334bc",
          "name": "Search Google Maps with query",
          "type": "n8n-nodes-base.httpRequest",
          "position": [
            1280,
            980
          ],
          "parameters": {
            "url": "=https://www.google.com/maps/search/{{ $json.query }}",
            "options": {
              "allowUnauthorizedCerts": false
            }
          },
          "executeOnce": false,
          "typeVersion": 4.2,
          "alwaysOutputData": false
        },
        {
          "id": "477e7d55-b7d6-4b20-ac44-dd1f443e270a",
          "name": "Scrape URLs from results",
          "type": "n8n-nodes-base.code",
          "position": [
            1480,
            980
          ],
          "parameters": {
            "jsCode": "const data = $input.first().json.data\n\nconst regex = /https?:\\/\\/[^\\/]+/g\n\nconst urls = data.match(regex)\n\nreturn urls.map(url => ({json: {url: url}}))"
          },
          "typeVersion": 2
        },
        {
          "id": "a5b67e45-a3f6-41d2-aa58-c26a441c41b2",
          "name": "Filter irrelevant URLs",
          "type": "n8n-nodes-base.filter",
          "position": [
            1680,
            980
          ],
          "parameters": {
            "options": {},
            "conditions": {
              "options": {
                "version": 2,
                "leftValue": "",
                "caseSensitive": true,
                "typeValidation": "strict"
              },
              "combinator": "and",
              "conditions": [
                {
                  "id": "041797f2-2fe2-41dc-902a-d34050b9b304",
                  "operator": {
                    "type": "string",
                    "operation": "notRegex"
                  },
                  "leftValue": "={{ $json.url }}",
                  "rightValue": "=(google|gstatic|ggpht|schema\\.org|example\\.com|sentry-next\\.wixpress\\.com|imli\\.com|sentry\\.wixpress\\.com|ingest\\.sentry\\.io)"
                },
                {
                  "id": "eb499a7e-17bc-453c-be08-a47286f726dd",
                  "operator": {
                    "name": "filter.operator.equals",
                    "type": "string",
                    "operation": "equals"
                  },
                  "leftValue": "",
                  "rightValue": ""
                }
              ]
            }
          },
          "typeVersion": 2.2
        },
        {
          "id": "12f662a8-c55f-409a-b381-f37ab6dd3794",
          "name": "Loop over URLs",
          "type": "n8n-nodes-base.splitInBatches",
          "onError": "continueErrorOutput",
          "position": [
            2640,
            980
          ],
          "parameters": {
            "options": {
              "reset": false
            }
          },
          "typeVersion": 3
        },
        {
          "id": "93437e8b-4f8d-40a1-9585-cab1b556164a",
          "name": "Starts scraper workflow",
          "type": "n8n-nodes-base.executeWorkflowTrigger",
          "position": [
            800,
            980
          ],
          "parameters": {},
          "typeVersion": 1
        },
        {
          "id": "dffaf04e-d1d2-4002-9a69-f0904b61fc2d",
          "name": "Wait between executions",
          "type": "n8n-nodes-base.wait",
          "position": [
            2300,
            600
          ],
          "webhookId": "40eb11a9-0f7d-4932-993e-0052b69dbf9b",
          "parameters": {
            "unit": "minutes",
            "amount": 20
          },
          "typeVersion": 1.1
        },
        {
          "id": "18787007-1d11-41b9-89c3-d5f69756eda7",
          "name": "Execute scraper for query",
          "type": "n8n-nodes-base.executeWorkflow",
          "position": [
            1800,
            600
          ],
          "parameters": {
            "mode": "each",
            "options": {
              "waitForSubWorkflow": false
            },
            "workflowId": {
              "__rl": true,
              "mode": "id",
              "value": "={{ $workflow.id }}"
            }
          },
          "typeVersion": 1.1
        },
        {
          "id": "9fa06f2a-0e7a-43e1-b997-4b4288a990cd",
          "name": "AI Agent",
          "type": "@n8n/n8n-nodes-langchain.agent",
          "position": [
            4260,
            1360
          ],
          "parameters": {
            "text": "={{ $json.prompt }}",
            "options": {
              "systemMessage": "You are an expert business analyst.\n\nGiven a business website data, generate a JSON object with key business information and a detailed, insightful description that could be used to prepare for outreach or partnership discussions.\n\nFocus the description on:\n\n- What the business does (products/services)\n- Their strengths or market position\n- Technologies or platforms used (if identifiable)\n- Unique value proposition\n- Target customers\n- Any possible gaps, pain points, or areas for improvement\n- Why this business could benefit from external collaboration (e.g., automation, digital transformation, SEO, AI tools)\n\nFormat the output as a single JSON object with these fields:\n\n- business_name\n- website_url\n- email\n- phone_number\n- address\n- city\n- postal_code\n- country\n- latitude\n- longitude\n- category\n- subcategory\n- opening_hours\n- social_media_links (array)\n- about_us\n- services (array)\n- contact_page_url\n- privacy_policy_url\n- terms_conditions_url\n- logo_url\n- languages (array)\n- keywords (array)\n- google_maps_url\n- ai_description_detailed (a detailed paragraph or two with everything above)\n\nOnly output valid JSON.\nif prompt is empty just return empty json data "
            },
            "promptType": "define"
          },
          "typeVersion": 2
        },
        {
          "id": "c191a15f-2457-49c1-976b-90b0caaf3835",
          "name": "OpenRouter Chat Model",
          "type": "@n8n/n8n-nodes-langchain.lmChatOpenRouter",
          "position": [
            4260,
            1620
          ],
          "parameters": {
            "model": "google/gemini-2.5-flash-lite-preview-06-17",
            "options": {}
          },
          "credentials": {
            "openRouterApi": {
              "id": "tC9q2VizRVbSvlww",
              "name": "OpenRouter account"
            }
          },
          "typeVersion": 1
        },
        {
          "id": "20c5612b-8fbf-4eb4-8f95-ca17acc5f0e2",
          "name": "Code",
          "type": "n8n-nodes-base.code",
          "position": [
            4680,
            960
          ],
          "parameters": {
            "jsCode": "const allPromptResults = $input.first().json.data.map(item => item.promptResult).join('\\n');\n\n\nreturn {\n  \"prompt\":allPromptResults\n};"
          },
          "typeVersion": 2
        },
        {
          "id": "53d2251a-f7bb-43b1-8035-c7ac74e0aa62",
          "name": "Aggregate",
          "type": "n8n-nodes-base.aggregate",
          "position": [
            4420,
            960
          ],
          "parameters": {
            "options": {},
            "aggregate": "aggregateAllItemData"
          },
          "typeVersion": 1
        },
        {
          "id": "67dfef97-0fc2-4fa8-a7a8-08c491f8785f",
          "name": "Schedule Trigger",
          "type": "n8n-nodes-base.scheduleTrigger",
          "position": [
            1060,
            580
          ],
          "parameters": {
            "rule": {
              "interval": [
                {
                  "field": "hours"
                }
              ]
            }
          },
          "typeVersion": 1.2
        },
        {
          "id": "cb651c6d-eac0-44bc-8d80-c07c5a65ce6a",
          "name": "Get row(s) in sheet",
          "type": "n8n-nodes-base.googleSheets",
          "position": [
            1280,
            580
          ],
          "parameters": {
            "options": {},
            "filtersUI": {
              "values": [
                {
                  "lookupColumn": "processed"
                }
              ]
            },
            "sheetName": {
              "__rl": true,
              "mode": "list",
              "value": 1652190371,
              "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1si2IQusnIF-Br8JdXSVd_Z9QvnXrKcieXOkxI0Xz9ks/edit#gid=1652190371",
              "cachedResultName": "keywords"
            },
            "documentId": {
              "__rl": true,
              "mode": "list",
              "value": "1si2IQusnIF-Br8JdXSVd_Z9QvnXrKcieXOkxI0Xz9ks",
              "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1si2IQusnIF-Br8JdXSVd_Z9QvnXrKcieXOkxI0Xz9ks/edit?usp=drivesdk",
              "cachedResultName": "google maps  bussiness informations"
            }
          },
          "credentials": {
            "googleSheetsOAuth2Api": {
              "id": "c7TYv7ZcF6y7LGEQ",
              "name": "Google Sheets account"
            }
          },
          "typeVersion": 4.6
        },
        {
          "id": "423dce21-e06d-4bd2-833b-976b3ce9e231",
          "name": "Update row in sheet",
          "type": "n8n-nodes-base.googleSheets",
          "position": [
            2040,
            600
          ],
          "parameters": {
            "columns": {
              "value": {
                "query": "={{ $json.query }}",
                "processed": "TRUE"
              },
              "schema": [
                {
                  "id": "query",
                  "type": "string",
                  "display": true,
                  "removed": false,
                  "required": false,
                  "displayName": "query",
                  "defaultMatch": false,
                  "canBeUsedToMatch": true
                },
                {
                  "id": "processed",
                  "type": "string",
                  "display": true,
                  "required": false,
                  "displayName": "processed",
                  "defaultMatch": false,
                  "canBeUsedToMatch": true
                },
                {
                  "id": "row_number",
                  "type": "number",
                  "display": true,
                  "removed": true,
                  "readOnly": true,
                  "required": false,
                  "displayName": "row_number",
                  "defaultMatch": false,
                  "canBeUsedToMatch": true
                }
              ],
              "mappingMode": "defineBelow",
              "matchingColumns": [
                "query"
              ],
              "attemptToConvertTypes": false,
              "convertFieldsToString": false
            },
            "options": {},
            "operation": "update",
            "sheetName": {
              "__rl": true,
              "mode": "list",
              "value": 1652190371,
              "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1si2IQusnIF-Br8JdXSVd_Z9QvnXrKcieXOkxI0Xz9ks/edit#gid=1652190371",
              "cachedResultName": "keywords"
            },
            "documentId": {
              "__rl": true,
              "mode": "list",
              "value": "1si2IQusnIF-Br8JdXSVd_Z9QvnXrKcieXOkxI0Xz9ks",
              "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1si2IQusnIF-Br8JdXSVd_Z9QvnXrKcieXOkxI0Xz9ks/edit?usp=drivesdk",
              "cachedResultName": "google maps  bussiness informations"
            }
          },
          "credentials": {
            "googleSheetsOAuth2Api": {
              "id": "c7TYv7ZcF6y7LGEQ",
              "name": "Google Sheets account"
            }
          },
          "typeVersion": 4.6
        },
        {
          "id": "a996171f-c358-471d-91ba-b6c9950e7edf",
          "name": "If",
          "type": "n8n-nodes-base.if",
          "position": [
            3940,
            980
          ],
          "parameters": {
            "options": {},
            "conditions": {
              "options": {
                "version": 2,
                "leftValue": "",
                "caseSensitive": true,
                "typeValidation": "strict"
              },
              "combinator": "and",
              "conditions": [
                {
                  "id": "7eec5545-99ac-410a-87ec-4e5f79e30202",
                  "operator": {
                    "type": "boolean",
                    "operation": "true",
                    "singleValue": true
                  },
                  "leftValue": "={{ $json.dontExist }}",
                  "rightValue": ""
                },
                {
                  "id": "96fe4cf5-4689-4140-8a75-8bdbc893b363",
                  "operator": {
                    "name": "filter.operator.equals",
                    "type": "string",
                    "operation": "equals"
                  },
                  "leftValue": "",
                  "rightValue": ""
                }
              ]
            }
          },
          "typeVersion": 2.2
        },
        {
          "id": "4575083d-5d45-497e-a5d1-5c369f2d7b91",
          "name": "Merge",
          "type": "n8n-nodes-base.merge",
          "position": [
            3660,
            980
          ],
          "parameters": {
            "mode": "combineBySql",
            "query": "SELECT * FROM input1 LEFT JOIN input2 ON 1=1",
            "options": {}
          },
          "typeVersion": 3.2
        },
        {
          "id": "73814b4e-ab19-4a06-b180-a2997e43bdbd",
          "name": "convert string to json object",
          "type": "n8n-nodes-base.code",
          "onError": "continueRegularOutput",
          "position": [
            4640,
            1360
          ],
          "parameters": {
            "mode": "runOnceForEachItem",
            "jsCode": "\n\nlet raw = $json.output;\n\n// Remove ```json or ``` wrapping if it exists\nraw = raw.replace(/^```json\\s*|\\s*```$/g, '').trim();\n\nlet outputJson;\n\ntry {\n  outputJson = JSON.parse(raw);\n} catch (err) {\n  outputJson = { error: 'Invalid JSON format in promptResult' };\n}\n\nreturn {\n  json: outputJson\n};"
          },
          "typeVersion": 2
        },
        {
          "id": "54d94ef2-84cf-4568-a9d5-28ec9a818ffd",
          "name": "Save DATA to Google Sheet1",
          "type": "n8n-nodes-base.googleSheets",
          "position": [
            5060,
            1360
          ],
          "parameters": {
            "columns": {
              "value": {},
              "schema": [
                {
                  "id": "Business Name",
                  "type": "string",
                  "display": true,
                  "removed": false,
                  "required": false,
                  "displayName": "Business Name",
                  "defaultMatch": false,
                  "canBeUsedToMatch": true
                },
                {
                  "id": "Website URL",
                  "type": "string",
                  "display": true,
                  "removed": false,
                  "required": false,
                  "displayName": "Website URL",
                  "defaultMatch": false,
                  "canBeUsedToMatch": true
                },
                {
                  "id": "Email",
                  "type": "string",
                  "display": true,
                  "removed": false,
                  "required": false,
                  "displayName": "Email",
                  "defaultMatch": false,
                  "canBeUsedToMatch": true
                },
                {
                  "id": "Phone Number",
                  "type": "string",
                  "display": true,
                  "removed": false,
                  "required": false,
                  "displayName": "Phone Number",
                  "defaultMatch": false,
                  "canBeUsedToMatch": true
                },
                {
                  "id": "Address",
                  "type": "string",
                  "display": true,
                  "removed": false,
                  "required": false,
                  "displayName": "Address",
                  "defaultMatch": false,
                  "canBeUsedToMatch": true
                },
                {
                  "id": "City",
                  "type": "string",
                  "display": true,
                  "removed": false,
                  "required": false,
                  "displayName": "City",
                  "defaultMatch": false,
                  "canBeUsedToMatch": true
                },
                {
                  "id": "Postal Code",
                  "type": "string",
                  "display": true,
                  "removed": false,
                  "required": false,
                  "displayName": "Postal Code",
                  "defaultMatch": false,
                  "canBeUsedToMatch": true
                },
                {
                  "id": "Country",
                  "type": "string",
                  "display": true,
                  "removed": false,
                  "required": false,
                  "displayName": "Country",
                  "defaultMatch": false,
                  "canBeUsedToMatch": true
                },
                {
                  "id": "Latitude",
                  "type": "string",
                  "display": true,
                  "removed": false,
                  "required": false,
                  "displayName": "Latitude",
                  "defaultMatch": false,
                  "canBeUsedToMatch": true
                },
                {
                  "id": "Longitude",
                  "type": "string",
                  "display": true,
                  "removed": false,
                  "required": false,
                  "displayName": "Longitude",
                  "defaultMatch": false,
                  "canBeUsedToMatch": true
                },
                {
                  "id": "Category",
                  "type": "string",
                  "display": true,
                  "removed": false,
                  "required": false,
                  "displayName": "Category",
                  "defaultMatch": false,
                  "canBeUsedToMatch": true
                },
                {
                  "id": "Subcategory",
                  "type": "string",
                  "display": true,
                  "removed": false,
                  "required": false,
                  "displayName": "Subcategory",
                  "defaultMatch": false,
                  "canBeUsedToMatch": true
                },
                {
                  "id": "Opening Hours",
                  "type": "string",
                  "display": true,
                  "removed": false,
                  "required": false,
                  "displayName": "Opening Hours",
                  "defaultMatch": false,
                  "canBeUsedToMatch": true
                },
                {
                  "id": "Social Media Links",
                  "type": "string",
                  "display": true,
                  "removed": false,
                  "required": false,
                  "displayName": "Social Media Links",
                  "defaultMatch": false,
                  "canBeUsedToMatch": true
                },
                {
                  "id": "About Us",
                  "type": "string",
                  "display": true,
                  "removed": false,
                  "required": false,
                  "displayName": "About Us",
                  "defaultMatch": false,
                  "canBeUsedToMatch": true
                },
                {
                  "id": "Services",
                  "type": "string",
                  "display": true,
                  "removed": false,
                  "required": false,
                  "displayName": "Services",
                  "defaultMatch": false,
                  "canBeUsedToMatch": true
                },
                {
                  "id": "Contact Page URL",
                  "type": "string",
                  "display": true,
                  "removed": false,
                  "required": false,
                  "displayName": "Contact Page URL",
                  "defaultMatch": false,
                  "canBeUsedToMatch": true
                },
                {
                  "id": "Privacy Policy URL",
                  "type": "string",
                  "display": true,
                  "removed": false,
                  "required": false,
                  "displayName": "Privacy Policy URL",
                  "defaultMatch": false,
                  "canBeUsedToMatch": true
                },
                {
                  "id": "Terms & Conditions URL",
                  "type": "string",
                  "display": true,
                  "removed": false,
                  "required": false,
                  "displayName": "Terms & Conditions URL",
                  "defaultMatch": false,
                  "canBeUsedToMatch": true
                },
                {
                  "id": "Logo URL",
                  "type": "string",
                  "display": true,
                  "removed": false,
                  "required": false,
                  "displayName": "Logo URL",
                  "defaultMatch": false,
                  "canBeUsedToMatch": true
                },
                {
                  "id": "Languages",
                  "type": "string",
                  "display": true,
                  "removed": false,
                  "required": false,
                  "displayName": "Languages",
                  "defaultMatch": false,
                  "canBeUsedToMatch": true
                },
                {
                  "id": "Keywords",
                  "type": "string",
                  "display": true,
                  "removed": false,
                  "required": false,
                  "displayName": "Keywords",
                  "defaultMatch": false,
                  "canBeUsedToMatch": true
                },
                {
                  "id": "Google Maps URL",
                  "type": "string",
                  "display": true,
                  "removed": false,
                  "required": false,
                  "displayName": "Google Maps URL",
                  "defaultMatch": false,
                  "canBeUsedToMatch": true
                },
                {
                  "id": "AI Description",
                  "type": "string",
                  "display": true,
                  "removed": false,
                  "required": false,
                  "displayName": "AI Description",
                  "defaultMatch": false,
                  "canBeUsedToMatch": true
                }
              ],
              "mappingMode": "autoMapInputData",
              "matchingColumns": [],
              "attemptToConvertTypes": false,
              "convertFieldsToString": false
            },
            "options": {},
            "operation": "append",
            "sheetName": {
              "__rl": true,
              "mode": "list",
              "value": "gid=0",
              "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1si2IQusnIF-Br8JdXSVd_Z9QvnXrKcieXOkxI0Xz9ks/edit#gid=0",
              "cachedResultName": "Sheet1"
            },
            "documentId": {
              "__rl": true,
              "mode": "list",
              "value": "1si2IQusnIF-Br8JdXSVd_Z9QvnXrKcieXOkxI0Xz9ks",
              "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1si2IQusnIF-Br8JdXSVd_Z9QvnXrKcieXOkxI0Xz9ks/edit?usp=drivesdk",
              "cachedResultName": "google maps  bussiness informations"
            }
          },
          "credentials": {
            "googleSheetsOAuth2Api": {
              "id": "c7TYv7ZcF6y7LGEQ",
              "name": "Google Sheets account"
            }
          },
          "typeVersion": 4.5
        },
        {
          "id": "40ec6d1f-1c98-4c9f-8499-c5893c3df7b9",
          "name": "use APIFY",
          "type": "n8n-nodes-base.httpRequest",
          "onError": "continueRegularOutput",
          "position": [
            4200,
            960
          ],
          "parameters": {
            "url": "=https://api.apify.com/v2/acts/mohamedgb00714~firescraper-ai-prompt-website-content-markdown-scraper/run-sync-get-dataset-items?token=apify_api_DUMMY_TOKEN",
            "method": "POST",
            "options": {},
            "jsonBody": "={\n  \"enqueue\": true,\n  \"getHtml\": false,\n  \"getText\": false,\n  \"prompt\": \"You are an expert business analyst.\\n\\nGiven a business website URL, generate a JSON object with key business information and a detailed, insightful description that could be used to prepare for outreach or partnership discussions.\\n\\nFocus the description on:\\n\\n- What the business does (products/services)\\n- Their strengths or market position\\n- Technologies or platforms used (if identifiable)\\n- Unique value proposition\\n- Target customers\\n- Any possible gaps, pain points, or areas for improvement\\n- Why this business could benefit from external collaboration (e.g., automation, digital transformation, SEO, AI tools)\\n\\nFormat the output as a single JSON object with these fields:\\n\\n- business_name\\n- website_url\\n- email\\n- phone_number\\n- address\\n- city\\n- postal_code\\n- country\\n- latitude\\n- longitude\\n- category\\n- subcategory\\n- opening_hours\\n- social_media_links (array)\\n- about_us\\n- services (array)\\n- contact_page_url\\n- privacy_policy_url\\n- terms_conditions_url\\n- logo_url\\n- languages (array)\\n- keywords (array)\\n- google_maps_url\\n- ai_description_detailed (a detailed paragraph or two with everything above)\\n\\nOnly output valid JSON.\",\n  \"screenshot\": false,\n  \"startUrls\": [\n    {\n      \"url\": \"{{$json.url}}\",\n      \"method\": \"GET\"\n    }\n  ]\n}\n",
            "sendBody": true,
            "specifyBody": "json"
          },
          "typeVersion": 4.2,
          "alwaysOutputData": false
        },
        {
          "id": "e4997964-dc80-4778-9f79-ae4dc9e41284",
          "name": "get records if exist",
          "type": "n8n-nodes-base.googleSheets",
          "onError": "continueErrorOutput",
          "position": [
            2900,
            1300
          ],
          "parameters": {
            "options": {},
            "sheetName": {
              "__rl": true,
              "mode": "list",
              "value": "gid=0",
              "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1si2IQusnIF-Br8JdXSVd_Z9QvnXrKcieXOkxI0Xz9ks/edit#gid=0",
              "cachedResultName": "Sheet1"
            },
            "documentId": {
              "__rl": true,
              "mode": "list",
              "value": "1si2IQusnIF-Br8JdXSVd_Z9QvnXrKcieXOkxI0Xz9ks",
              "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1si2IQusnIF-Br8JdXSVd_Z9QvnXrKcieXOkxI0Xz9ks/edit?usp=drivesdk",
              "cachedResultName": "google maps  bussiness informations"
            }
          },
          "credentials": {
            "googleSheetsOAuth2Api": {
              "id": "c7TYv7ZcF6y7LGEQ",
              "name": "Google Sheets account"
            }
          },
          "typeVersion": 4.6,
          "alwaysOutputData": true
        },
        {
          "id": "d2380d4e-20a5-48bb-9d87-3f2c638f2fc7",
          "name": "Code1",
          "type": "n8n-nodes-base.code",
          "position": [
            3400,
            1280
          ],
          "parameters": {
            "jsCode": "let dontExist = true;\n\n// Get reference domain from 'Loop over URLs' node\nconst referenceUrl = $('Loop over URLs').first().json.url;\nconst referenceDomain = referenceUrl.match(/^https?:\\/\\/([^\\/?#]+)(?:[\\/?#]|$)/i)?.[1]?.toLowerCase();\n\nif (!referenceDomain) {\n  throw new Error('Invalid reference URL');\n}\n\n// Loop over input items\nfor (const item of $input.all()) {\n  const urls = item.json.website_url;\n\n  for (const url of urls) {\n    const domain = url.match(/^https?:\\/\\/([^\\/?#]+)(?:[\\/?#]|$)/i)?.[1]?.toLowerCase();\n    if (!domain) continue;\n\n    if (domain === referenceDomain) {\n      dontExist = false;\n      break;\n    }\n  }\n\n  if (!dontExist) break;\n}\n\n// Return result\nreturn {\n  json: {\n    dontExist\n  }\n};\n"
          },
          "typeVersion": 2
        },
        {
          "id": "0273b1f4-5912-41fd-9899-3ec0a5a24f6c",
          "name": "Aggregate1",
          "type": "n8n-nodes-base.aggregate",
          "position": [
            3160,
            1280
          ],
          "parameters": {
            "options": {},
            "fieldsToAggregate": {
              "fieldToAggregate": [
                {
                  "fieldToAggregate": "website_url"
                }
              ]
            }
          },
          "typeVersion": 1
        },
        {
          "id": "2adf371b-2b7b-4ce9-9666-95a4b892a963",
          "name": "Sticky Note",
          "type": "n8n-nodes-base.stickyNote",
          "position": [
            20,
            240
          ],
          "parameters": {
            "width": 680,
            "height": 2220,
            "content": "\n### Overview\n\nThis workflow automates the discovery, extraction, enrichment, and storage of business information from **Google Maps** search queries using AI tools, scrapers, and Google Sheets.\n\nIt is ideal for:\n\n* Lead generation agencies\n* Local business researchers\n* Digital marketing firms\n* Automation & outreach specialists\n\n---\n\n### 🔧 Tools & APIs Used\n\n* **Google Maps Search (via HTTP)**\n* **Custom JavaScript Parsing**\n* **URL Filtering & De-duplication**\n* **Google Sheets (Read/Write)**\n* **APIFY Actor** for business scraping\n* **LangChain AI Agent** (OpenRouter - Gemini 2.5)\n* **n8n Built-in Logic** (Loops, Conditions, Aggregators)\n\n---\n\n### 🧠 Workflow Summary\n\n1. **Trigger**\n   The automation starts via schedule (every hour).\n\n2. **Read Queries from Google Sheet**\n   Loads unprocessed keywords from a Google Sheet tab named `keywords`.\n\n3. **Loop Through Keywords**\n   Each keyword is used to search Google Maps for relevant businesses.\n\n4. **Extract URLs**\n   JavaScript parses HTML to find all external website URLs from the search results.\n\n5. **Clean URLs**\n   Filters out irrelevant domains (e.g., Google-owned, example.com, etc.), and removes duplicates.\n\n6. **Loop Through URLs**\n   For each URL:\n\n   * Checks if it already exists in the Google Sheet (to prevent duplication).\n   * Calls the **APIFY Actor** to extract full business data.\n   * Optionally uses **AI Agent (Gemini)** to provide detailed insight on the business, including:\n\n     * Services, About, Market Position, Weaknesses, AI suggestions, etc.\n   * Converts the AI result (text) to a structured JSON object.\n\n7. **Save to Google Sheet**\n   Adds all extracted and AI-enriched business information to a separate tab (`Sheet1`).\n\n8. **Mark Queries as Processed**\n   Updates the original row in `keywords` to avoid reprocessing.\n\n---\n\n### 🗃️ Output Fields Saved\n\nThe following information is saved per business:\n\n* Business Name, Website, Email, Phone\n* Address, City, Postal Code, Country, Coordinates\n* Category, Subcategory, Services\n* About Us, Opening Hours, Social Media Links\n* Legal Links (Privacy, Terms)\n* Logo, Languages, Keywords\n* **AI-Generated Description**\n* Google Maps URL\n\n---\n\n### 📈 Use Cases\n\n* Build a **prospect database** for B2B cold outreach.\n* Extract **local SEO insights** per business.\n* Feed CRMs or analytics systems with **enriched business profiles**.\n* Automate market research for **regional opportunity detection**.\n\n---\n\n### 📩 Want a Similar Workflow?\n\nIf you’d like a custom AI-powered automation like this for your business or agency, feel free to contact me:\n\n**📧 [msaidwolfltd@gmail.com](mailto:msaidwolfltd@gmail.com)**\n\n\n\n"
          },
          "typeVersion": 1
        }
      ],
      "pinData": {
        "Starts scraper workflow": [
          {
            "query": "restaurant+paris"
          }
        ]
      },
      "connections": {
        "If": {
          "main": [
            [
              {
                "node": "use APIFY",
                "type": "main",
                "index": 0
              }
            ],
            [
              {
                "node": "Loop over URLs",
                "type": "main",
                "index": 0
              }
            ]
          ]
        },
        "Code": {
          "main": [
            [
              {
                "node": "AI Agent",
                "type": "main",
                "index": 0
              }
            ]
          ]
        },
        "Code1": {
          "main": [
            [
              {
                "node": "Merge",
                "type": "main",
                "index": 1
              }
            ]
          ]
        },
        "Merge": {
          "main": [
            [
              {
                "node": "If",
                "type": "main",
                "index": 0
              }
            ]
          ]
        },
        "AI Agent": {
          "main": [
            [
              {
                "node": "convert string to json object",
                "type": "main",
                "index": 0
              }
            ]
          ]
        },
        "Aggregate": {
          "main": [
            [
              {
                "node": "Code",
                "type": "main",
                "index": 0
              }
            ]
          ]
        },
        "use APIFY": {
          "main": [
            [
              {
                "node": "Aggregate",
                "type": "main",
                "index": 0
              }
            ]
          ]
        },
        "Aggregate1": {
          "main": [
            [
              {
                "node": "Code1",
                "type": "main",
                "index": 0
              }
            ]
          ]
        },
        "Loop over URLs": {
          "main": [
            [],
            [
              {
                "node": "Merge",
                "type": "main",
                "index": 0
              },
              {
                "node": "get records if exist",
                "type": "main",
                "index": 0
              }
            ]
          ]
        },
        "Schedule Trigger": {
          "main": [
            [
              {
                "node": "Get row(s) in sheet",
                "type": "main",
                "index": 0
              }
            ]
          ]
        },
        "Loop over queries": {
          "main": [
            [],
            [
              {
                "node": "Execute scraper for query",
                "type": "main",
                "index": 0
              }
            ]
          ]
        },
        "Get row(s) in sheet": {
          "main": [
            [
              {
                "node": "Loop over queries",
                "type": "main",
                "index": 0
              }
            ]
          ]
        },
        "Update row in sheet": {
          "main": [
            [
              {
                "node": "Wait between executions",
                "type": "main",
                "index": 0
              }
            ]
          ]
        },
        "get records if exist": {
          "main": [
            [
              {
                "node": "Aggregate1",
                "type": "main",
                "index": 0
              }
            ]
          ]
        },
        "OpenRouter Chat Model": {
          "ai_languageModel": [
            [
              {
                "node": "AI Agent",
                "type": "ai_languageModel",
                "index": 0
              }
            ]
          ]
        },
        "Remove Duplicate URLs": {
          "main": [
            [
              {
                "node": "Loop over URLs",
                "type": "main",
                "index": 0
              }
            ]
          ]
        },
        "Filter irrelevant URLs": {
          "main": [
            [
              {
                "node": "Remove Duplicate URLs",
                "type": "main",
                "index": 0
              }
            ]
          ]
        },
        "Starts scraper workflow": {
          "main": [
            [
              {
                "node": "Search Google Maps with query",
                "type": "main",
                "index": 0
              }
            ]
          ]
        },
        "Wait between executions": {
          "main": [
            [
              {
                "node": "Loop over queries",
                "type": "main",
                "index": 0
              }
            ]
          ]
        },
        "Scrape URLs from results": {
          "main": [
            [
              {
                "node": "Filter irrelevant URLs",
                "type": "main",
                "index": 0
              }
            ]
          ]
        },
        "Execute scraper for query": {
          "main": [
            [
              {
                "node": "Update row in sheet",
                "type": "main",
                "index": 0
              }
            ]
          ]
        },
        "Save DATA to Google Sheet1": {
          "main": [
            [
              {
                "node": "Loop over URLs",
                "type": "main",
                "index": 0
              }
            ]
          ]
        },
        "Search Google Maps with query": {
          "main": [
            [
              {
                "node": "Scrape URLs from results",
                "type": "main",
                "index": 0
              }
            ]
          ]
        },
        "convert string to json object": {
          "main": [
            [
              {
                "node": "Save DATA to Google Sheet1",
                "type": "main",
                "index": 0
              }
            ]
          ]
        }
      }
    }