n8n Google Maps scraper workflows
By Doug Nielsen, Product Manager · Published
Three free n8n templates that run a Hubertino Google Maps scrape from inside n8n and send the businesses, with emails, phones, websites and social profiles, to Google Sheets or HubSpot. Each is a JSON file you import; you add your API key as an n8n credential. They poll the Hubertino REST API with the core HTTP Request node, so no community node is needed.
The templates
Google Maps leads with emails → Google Sheets
Runs one scrape and writes every business that has an email into a Google Sheet. Rows are upserted on place_id, so running it again updates known businesses instead of duplicating them.
Needs: Google Sheets (OAuth2) and a spreadsheet with a Leads tab.
Google Maps leads with emails → HubSpot contacts
Runs one scrape and creates or updates one HubSpot contact per business email, with company name, phone, website and address.
Needs: A HubSpot private-app token with the crm.objects.contacts read and write scopes.
Weekly new-business monitor → Google Sheets
Every Monday at 08:00 it re-runs the same search, compares the results with the sheet by place_id and appends only businesses it hasn't seen, with a first_seen date.
Needs: Google Sheets (OAuth2) and a spreadsheet with a Places tab.
Set it up
- 1. Import the workflow. In n8n, open Workflows → Create → ⋯ → Import from File and pick the JSON (or paste its contents onto the canvas). The yellow sticky notes repeat these steps.
- 2. Get an API key. Sign up (100 free credits, no card), then copy a key from Dashboard → Settings. It starts with
hub_live_and is shown once. - 3. Add the credential. Create one Bearer Auth credential with the key as the Bearer Token, and select it in the three HTTP Request nodes: Start scrape, Get scrape status and Fetch all rows. Bearer Auth arrived in n8n 1.88; on older versions use a Header Auth credential instead and set each of those nodes to Authentication → Generic → Header Auth:
Name: Authorization Value: Bearer hub_live_your_key_here - 4. Connect the destination. Google Sheets via OAuth2, pointed at a spreadsheet with a
Leadstab (orPlacesfor the weekly monitor; the header row is written on the first run), or HubSpot via a private-app token. - 5. Edit the search and run. Open Start scrape and change the JSON body, then execute the workflow (or activate the weekly monitor).Add
{ "categories": ["dentist"], "locations": ["Austin, TX, United States"], "maxResults": 50, "enrichWebsite": true, "enrichLinks": true }"country": "gb"to pin a Google country edition; otherwise it's read from the locations. Every field is described in the API docs.
Node by node
All three share the same scrape-and-poll block after the trigger:
- 1. Start scrape — HTTP Request,
POST /api/v1/scrapeswith your categories, locations andmaxResults. It doesn't retry, so a timeout can't start the same scrape twice. - 2. Wait 30 seconds — Wait node.
- 3. Get scrape status — HTTP Request,
GET /api/v1/scrapes/{id}. Retries 3 times, 5 seconds apart, on transient errors. - 4. Scrape finished? — IF
statusisdone, go on to fetch the rows; otherwise check for failure. - 5. Scrape failed? — IF
statusiserror, Stop and Error with the API's message (the reserved credits are refunded). Otherwise loop back to Wait 30 seconds. - 6. Fetch all rows — HTTP Request,
GET /api/v1/scrapes/{id}/resultswith n8n's built-in pagination: 1,000 rows a page untilhasMoreis false, up to 100 pages (100,000 rows). - 7. One item per place — Split Out on
rows: one n8n item per business.
Google Maps leads with emails → Google Sheets
Trigger: Manual trigger (“When clicking ‘Execute workflow’”). Then the block above, then:
- 8. Has email? — IF node: keeps rows whose
emailisn't empty. Delete it to keep every business. - 9. Pick lead columns — Edit Fields: 20 columns, including
place_id, name, category, email, phone, website, address parts, rating, reviews, four social links, the Maps link and the scrape id. - 10. Upsert into Google Sheet — Google Sheets, append or update on
place_id, into a tab namedLeads, with RAW cell format so phone numbers and ZIP codes stay text.
Google Maps leads with emails → HubSpot contacts
Trigger: Manual trigger. Then the block above, then:
- 8. Has email? — IF node: HubSpot contacts are keyed on email, so businesses without one are skipped.
- 9. Create or update contact — HubSpot node: email, company name, phone, website, street, city, state, postal code and country.
Weekly new-business monitor → Google Sheets
Trigger: Schedule trigger (“Every Monday 08:00”). Then the block above, then:
- 8. Pick columns — Edit Fields: the same 20 columns plus
first_seen. - 9. Read known places — Google Sheets read of the
Placestab. Runs once and always outputs, so an empty sheet works on the first run. - 10. Compare with known places — Compare Datasets on
place_id. - 11. Append new businesses — Google Sheets append of the “In A only” branch: the newcomers.
What it costs in credits
- • 1 credit per business delivered. Each run reserves categories × locations ×
maxResults(capped at your balance) and refunds what the scrape didn't use. Emails and social profiles cost nothing extra. On Starter that's $0.38 per 1,000 businesses; see pricing. - • Filters don't save credits. Has email? runs after delivery, so businesses without an email are still charged.
- • The weekly monitor spends every week. It re-scrapes the whole search each Monday: 1 category × 1 city at
maxResults200 is at most 200 credits a week (about $0.08 at the Starter rate). KeepmaxResultsmodest.
Limits
- •
maxResultsis 1–500 per category × location pair, and one scrape covers up to 2,000 pairs. - • 12 new scrapes per 5 minutes per account, so don't fan one workflow out into dozens of parallel runs.
- • Fetch all rows stops at 100 pages, 100,000 businesses per run.
- • The Google Sheets node reads columns A–Z, so the templates write 20–21 chosen columns. The full 38-column file is one call away:
GET /api/v1/scrapes/{id}/export?format=csv.
Questions
Do I need a community node?
No. The templates use core n8n nodes only: Manual or Schedule Trigger, HTTP Request, Wait, IF, Split Out, Edit Fields, Compare Datasets, Stop and Error, Google Sheets and HubSpot. There's nothing extra to install, whether you use n8n Cloud or self-host.
Why does it poll instead of waiting for a webhook?
The Hubertino API has no webhooks yet, so polling the scrape's status is the supported pattern. A scrape usually takes a few minutes, so checking every 30 seconds keeps the number of API calls low.
Are these in n8n's template library?
Not yet. For now, download the JSON files here and import them. The files contain no credentials: you add your own key in n8n.
Prefer a spreadsheet without n8n? The Google Sheets script does the scrape-and-dedupe inside Sheets. All integrations: /integrations.
Get a key for the templates
Start free with 100 credits, no card. The API and templates work on every plan.
Start free with 100 credits