AutomationFlowsAI & RAG › Scrape & Summarize Google Maps Businesses with Apify + Gpt-4o to Sheets

Scrape & Summarize Google Maps Businesses with Apify + Gpt-4o to Sheets

ByJaures NYA @jauresnya on n8n.io

All results are then saved automatically into Google Sheets, ready for lead generation, enrichment, or outreach.

Event trigger★★★★☆ complexityAI-powered16 nodes@Apify/N8N Nodes ApifyOpenAIGoogle Sheets
AI & RAG Trigger: Event Nodes: 16 Complexity: ★★★★☆ AI nodes: yes Added:

This workflow corresponds to n8n.io template #10120 — we link there as the canonical source.

This workflow follows the Apifyn8N Nodes Apify → Google Sheets recipe pattern — see all workflows that pair these two integrations.

The workflow JSON

Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →

Download .json
{
  "id": "IyvxP8Yujze5aEKB",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "Scrape and Summarize Google Maps Businesses with APIFY and ChatGPT",
  "tags": [],
  "nodes": [
    {
      "id": "330c09af-1f34-4b17-9baf-1018f088a77f",
      "name": "When clicking \u2018Execute workflow\u2019",
      "type": "n8n-nodes-base.manualTrigger",
      "position": [
        0,
        0
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "dc21d5a5-2fa0-44db-b95e-5d3de2eeae74",
      "name": "Get dataset items",
      "type": "@apify/n8n-nodes-apify.apify",
      "position": [
        416,
        0
      ],
      "parameters": {
        "limit": {},
        "offset": {},
        "resource": "Datasets",
        "datasetId": "={{ $json.defaultDatasetId }}"
      },
      "credentials": {
        "apifyApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "aa25d18c-4d21-4742-a511-58cd4083b845",
      "name": "Remove Duplicates",
      "type": "n8n-nodes-base.removeDuplicates",
      "position": [
        624,
        0
      ],
      "parameters": {
        "compare": "selectedFields",
        "options": {},
        "fieldsToCompare": "title"
      },
      "typeVersion": 2
    },
    {
      "id": "dc4e16bc-6c4c-4cd0-8ab2-20503ab85d32",
      "name": "Run Google Maps Scraper",
      "type": "@apify/n8n-nodes-apify.apify",
      "position": [
        208,
        0
      ],
      "parameters": {
        "actorId": {
          "__rl": true,
          "mode": "list",
          "value": "nwua9Gu5YrADL7ZDj",
          "cachedResultUrl": "https://console.apify.com/actors/nwua9Gu5YrADL7ZDj/input",
          "cachedResultName": "Google Maps Scraper (compass/crawler-google-places)"
        },
        "timeout": {},
        "customBody": "{\n    \"countryCode\": \"fr\",\n    \"includeWebResults\": false,\n    \"language\": \"fr\",\n    \"locationQuery\": \"France\",\n    \"maxCrawledPlacesPerSearch\": 5,\n    \"maxImages\": 0,\n    \"maximumLeadsEnrichmentRecords\": 0,\n    \"scrapeContacts\": true,\n    \"scrapeDirectories\": false,\n    \"scrapeImageAuthors\": false,\n    \"scrapePlaceDetailPage\": false,\n    \"scrapeReviewsPersonalData\": true,\n    \"scrapeTableReservationProvider\": false,\n    \"searchStringsArray\": [\n        \"restaurant\"\n    ],\n    \"skipClosedPlaces\": true,\n    \"website\": \"allPlaces\"\n}"
      },
      "credentials": {
        "apifyApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "872850ef-da9f-48b5-a5b1-4ec15482fcc8",
      "name": "company summary Info",
      "type": "@n8n/n8n-nodes-langchain.openAi",
      "position": [
        1056,
        16
      ],
      "parameters": {
        "modelId": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4o",
          "cachedResultName": "GPT-4O"
        },
        "options": {},
        "messages": {
          "values": [
            {
              "role": "system",
              "content": "You are a helpful assistant that generates professional and concise company summaries from raw data scraped from Google Maps. Your goal is to return a natural, readable paragraph containing the company name, business category, address, city, phone number, and a link to the company's location on Google Maps.\n"
            },
            {
              "content": "=Please generate a short and clear summary of the following company, including:\n- Company name\n- Business category\n- Address (with city and country)\n- Phone number\n- A link to the company\u2019s page on Google Maps\n\nHere is the raw data:\nCompany Name: {{ $json.title }}\nCategory: {{ $json.categoryName }}\nAddress: {{ $json.address }}\nCity: {{ $json.city }}\nCountry: {{ $json.countryCode }}\nPhone: {{ $json.phone }}\nGoogle Maps URL:{{ $json.url }}\n\nOnly output a paragraph like this:\n\"The company name is [Name]. It is a [category] located at [address] in [city, country]. You can contact them at [phone]. For more info, visit their Google Maps page: [URL]\"\n"
            },
            {
              "content": "Output the result in the JSON format companySummary"
            }
          ]
        },
        "jsonOutput": true
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.8
    },
    {
      "id": "1283f68e-099e-4511-9706-5b342c4d9480",
      "name": "Loop Over Items",
      "type": "n8n-nodes-base.splitInBatches",
      "position": [
        832,
        0
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 3
    },
    {
      "id": "269e4e42-1186-452a-8258-23080f5071c4",
      "name": "Google maps database",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        1424,
        16
      ],
      "parameters": {
        "columns": {
          "value": {
            "url": "={{ $('Loop Over Items').item.json.url }}",
            "city": "={{ $('Loop Over Items').item.json.city }}",
            "rank": "={{ $('Loop Over Items').item.json.rank }}",
            "phone": "={{ $('Loop Over Items').item.json.phone }}",
            "title": "={{ $('Loop Over Items').item.json.title }}",
            "street": "={{ $('Loop Over Items').item.json.street }}",
            "address": "={{ $('Loop Over Items').item.json.address }}",
            "imageUrl": "={{ $('Loop Over Items').item.json.imageUrl }}",
            "scapedAt": "={{ $('Loop Over Items').item.json.scrapedAt }}",
            "categories": "={{ $('Loop Over Items').item.json.categories }}",
            "postalcode": "={{ $('Loop Over Items').item.json.postalCode }}",
            "totalScore": "={{ $('Loop Over Items').item.json.totalScore }}",
            "countryCode": "={{ $('Loop Over Items').item.json.countryCode }}",
            "categoryName": "={{ $('Loop Over Items').item.json.categoryName }}",
            "isAdvertissement": "={{ $('Loop Over Items').item.json.isAdvertisement }}",
            "phoneUnformattted": "={{ $('Loop Over Items').item.json.phoneUnformatted }}",
            "companySummaryInfo": "={{ $json.message.content.companySummary }}"
          },
          "schema": [
            {
              "id": "title",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "title",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "categoryName",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "categoryName",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "address",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "address",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "street",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "street",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "city",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "city",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "postalcode",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "postalcode",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "countryCode",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "countryCode",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "phone",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "phone",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "phoneUnformattted",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "phoneUnformattted",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "totalScore",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "totalScore",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "categories",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "categories",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "scapedAt",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "scapedAt",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "url",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "url",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "rank",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "rank",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "isAdvertissement",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "isAdvertissement",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "imageUrl",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "imageUrl",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "companySummaryInfo",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "companySummaryInfo",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/17VVXU_eUckRwJ7RaGN5v5hPmhQbNn1Q4pjwOkylNl10/edit#gid=0",
          "cachedResultName": "Feuille 1"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "17VVXU_eUckRwJ7RaGN5v5hPmhQbNn1Q4pjwOkylNl10",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/17VVXU_eUckRwJ7RaGN5v5hPmhQbNn1Q4pjwOkylNl10/edit?usp=drivesdk",
          "cachedResultName": "Google map Template scrape"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "c817b53d-db25-4b16-9f27-51ad629bda5c",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        160,
        -80
      ],
      "parameters": {
        "color": 6,
        "width": 592,
        "height": 256,
        "content": "## Run Google Maps Scraper & remove duplicates"
      },
      "typeVersion": 1
    },
    {
      "id": "fc1d5d48-c0a8-4767-ae96-fa9604b01ae1",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        992,
        -80
      ],
      "parameters": {
        "color": 6,
        "width": 352,
        "height": 256,
        "content": "## Company summary info generator"
      },
      "typeVersion": 1
    },
    {
      "id": "df97187b-4de8-4a24-902d-b8cdc54416ac",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1376,
        -80
      ],
      "parameters": {
        "color": 6,
        "width": 192,
        "height": 256,
        "content": "## Data Base"
      },
      "typeVersion": 1
    },
    {
      "id": "b5933527-6eb7-4152-8635-95d17b96409e",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -128,
        -272
      ],
      "parameters": {
        "color": 7,
        "width": 1968,
        "height": 512,
        "content": "## This automation scrapes businesses from Google Maps, summarizes their information into a human-readable paragraph using ChatGPT, and stores the results in a Google Sheet.\nThis workflow automates the entire process of lead generation from Google Maps \u2014 from scraping business info, cleaning duplicates, summarizing key details, and storing it in a Google Sheet \u2014 so you can save hours of manual research and focus on outreach and closing deals."
      },
      "typeVersion": 1
    },
    {
      "id": "04638e55-2599-4cf7-b079-e522dff29569",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -912,
        -272
      ],
      "parameters": {
        "width": 752,
        "height": 2496,
        "content": "## This workflow automates the process of scraping local business listings from Google Maps and generating clean, AI-powered summaries for each one \u2014 using Apify (community node) and OpenAI\u2019s GPT-4o.\n\nAll results are then saved automatically into Google Sheets, ready for lead generation, enrichment, or outreach.\n\n## What it does\nThis workflow saves hours of manual research by automatically:\n\n- Scraping structured business data from Google Maps (name, category, address, phone, website, etc.)\n\n- Creating natural-language summaries for each business using GPT-4o\n\n- Storing everything into Google Sheets \u2014 perfectly formatted for outreach or CRM import\n\n## Who\u2019s it for\n\nThis automation is ideal for:\n\n- Lead generators and sales teams building B2B lists from local businesses\n\n- Freelancers and agencies prospecting new clients in specific cities or industries\n\n- Recruiters or marketers looking to enrich business data for campaigns\n\n- Automation enthusiasts who want to summarize and structure raw scraped data \u2014 without writing a single line of code\n\n## How it works\n\n- Trigger: The workflow starts manually via the Execute Workflow trigger (ideal for testing or batch runs).\n\n- Scrape: It uses an Apify actor to scrape Google Maps search results and collect structured business info (name, category, address, phone, website, Google Maps URL...).\n\n- Fetch Data: The dataset is retrieved from Apify using the actor's dataset ID, and each business is loaded for processing.\n\n- Deduplicate: Removes duplicate business listings to keep your database clean.\n\n- Loop Over: Iterates over each business to generate a clean summary, one at a time.\n\n- Generate Summary: Sends the business data to OpenAI to generate a human-readable paragraph (including name, category, address, city, phone, and Google Maps link).\n\n- Store: Appends the summarized info into a Google Sheet \u2014 your final lead database.\n\n- Pause for rate limit: Adds a short delay (optional) to control flow or avoid rate limits.\n\n## Customization Tips\n\n- Change the Apify search query to target different cities, industries, or keywords.\n\n- Adjust the OpenAI prompt to include tone, length, or focus areas (e.g., add business highlights).\n\n- Add filters (e.g., add-on: reviews, add-on: images, etc.).\n\n## Setup Guide\n### Apify Setup\n\n- Use a Google Maps scraping actor in Apify.\n\n- Copy your Actor ID and Token \u2014 add them to your Apify node in n8n.\n\n- Note your Dataset ID (where results are stored).\n\n### OpenAI Setup\n\n- Add your OpenAI API key to the Generate Summary node.\n\n- The model gpt-4o is recommended for best quality/cost balance.\n\n### Google Sheets Setup\n\n- Connect your Google account.\n\n## How to use\n\n- Set up your Apify actor for Google Maps scraping (or use a prebuilt one).\n\n- Connect your OpenAI API key to the Message node (company summary).\n\n- Connect your Google Sheets account and select the target sheet.\n\n- Run the workflow \u2192 it will:\n\n1 Scrape business data\n\n2 Clean and summarize each one\n\n3 Save everything to your spreadsheet.\n\n## Requirements\n\n- \u2705 A working Apify actor that scrapes Google Maps listings\n\n- \u2705 An OpenAI account (GPT-4) with API access\n\n- \u2705 A Google Sheet for storing the summarized results\n\n## \u2753 Need help\n\n**Contact me for consulting and support:** [LinkedIn](https://www.linkedin.com/in/jaures-nya-83a033270/) / [YouTube](https://www.youtube.com/@jauresnya) / [Skool](https://www.skool.com/gaia-4903/about?ref=e0430e4c35b645ac8976b952768e9d55)  \n"
      },
      "typeVersion": 1
    },
    {
      "id": "b1391516-f1b9-48e7-a1d4-92388a3468c1",
      "name": "Sticky Note7",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        80,
        -1328
      ],
      "parameters": {
        "width": 736,
        "height": 384,
        "content": "## Apify manual config\n![](https://res.cloudinary.com/dya4plw3w/image/upload/v1761304716/Capture_d_e%CC%81cran_2025-10-24_a%CC%80_13.03.03_pozkdi.png)"
      },
      "typeVersion": 1
    },
    {
      "id": "62322350-6b03-4f5b-911d-efaefa9d2001",
      "name": "Sticky Note8",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        80,
        -928
      ],
      "parameters": {
        "width": 736,
        "height": 624,
        "content": "## Apify JSON config\n![](https://res.cloudinary.com/dya4plw3w/image/upload/v1761304716/Capture_d_e%CC%81cran_2025-10-24_a%CC%80_13.03.16_m8wewv.png)"
      },
      "typeVersion": 1
    },
    {
      "id": "5ef85869-6e7f-4282-bb74-241c6c8272b1",
      "name": "Sticky Note9",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        880,
        -448
      ],
      "parameters": {
        "width": 1056,
        "height": 144,
        "content": "## Google sheet column setups\n![](https://res.cloudinary.com/dya4plw3w/image/upload/v1761305547/Capture_d_e%CC%81cran_2025-10-24_a%CC%80_13.31.49_hn4ibf.png)"
      },
      "typeVersion": 1
    },
    {
      "id": "ce3039af-de00-4066-9f7e-3407d7c8b044",
      "name": "Pause for rate limit",
      "type": "n8n-nodes-base.wait",
      "position": [
        1632,
        16
      ],
      "parameters": {
        "amount": 2
      },
      "typeVersion": 1.1
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "dbae08af-841b-4565-a96f-e23d61c792e8",
  "connections": {
    "Loop Over Items": {
      "main": [
        [],
        [
          {
            "node": "company summary Info",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get dataset items": {
      "main": [
        [
          {
            "node": "Remove Duplicates",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Remove Duplicates": {
      "main": [
        [
          {
            "node": "Loop Over Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Google maps database": {
      "main": [
        [
          {
            "node": "Pause for rate limit",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Pause for rate limit": {
      "main": [
        [
          {
            "node": "Loop Over Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "company summary Info": {
      "main": [
        [
          {
            "node": "Google maps database",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Run Google Maps Scraper": {
      "main": [
        [
          {
            "node": "Get dataset items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "When clicking \u2018Execute workflow\u2019": {
      "main": [
        [
          {
            "node": "Run Google Maps Scraper",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}

Credentials you'll need

Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.

Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

All results are then saved automatically into Google Sheets, ready for lead generation, enrichment, or outreach.

Source: https://n8n.io/workflows/10120/ — original creator credit. Request a take-down →

More AI & RAG workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

AI & RAG

Clone_Viral_TikToks_with_AI_Avatars___Auto_Post_to_9_Platforms_using_Perplexity___Blotato. Uses httpRequest, telegramTrigger, openAi, googleSheets. Event-driven trigger; 42 nodes.

HTTP Request, Telegram Trigger, OpenAI +2
AI & RAG

1-Clone_Viral_TikToks_with_AI_Avatars___Auto_Post_to_9_Platforms_using_Perplexity___Blotato. Uses httpRequest, telegramTrigger, openAi, googleSheets. Event-driven trigger; 42 nodes.

HTTP Request, Telegram Trigger, OpenAI +2
AI & RAG

1-Clone_Viral_TikToks_with_AI_Avatars___Auto_Post_to_9_Platforms_using_Perplexity___Blotato. Uses httpRequest, telegramTrigger, openAi, googleSheets. Event-driven trigger; 42 nodes.

HTTP Request, Telegram Trigger, OpenAI +2
AI & RAG

💥Clone a viral TikTok and auto-post it to 9 platforms using Perplexity & Blotato vide. Uses httpRequest, telegramTrigger, openAi, googleSheets. Event-driven trigger; 41 nodes.

HTTP Request, Telegram Trigger, OpenAI +2
AI & RAG

💥Clone a viral TikTok and auto-post it to 9 platforms using Perplexity & Blotato vide. Uses httpRequest, telegramTrigger, openAi, googleSheets. Event-driven trigger; 41 nodes.

HTTP Request, Telegram Trigger, OpenAI +2