Huashu Design
alchaincyf · Skill
Turns a one-line request in your AI agent into a finished design: a launch animation, a clickable app prototype, an editable slide deck, an infographic or a se…
An n8n workflow that turns a Google Maps search into a sheet of local businesses with emails. A form takes a keyword, a place and a number. Apify collects the businesses, gpt-4o-mini reads each website for an email, and Anymail Finder fills the gaps.
Google Maps leads with emails read from each website is an n8n workflow in the Marketing & SEO category, listed by Mindket. It is free. This is version 1, last updated on . Download it on this page or copy its JSON, then import it into an n8n canvas. Nothing runs until you activate it in n8n.
Leads form
It starts when someone sends the Google Maps Leads form with:
A sheet of local businesses, each with a contact email wherever the site or Anymail Finder could supply one
What you need before you start.
Business scraping
Runs Google Maps Scraper by Compass from your keyword and place, and returns each business with its address, website and phone.
NeedsApify API token, and credit for the places
Page reading
Returns each business’s website as plain text through its Reader address, for the model to read.
NeedsNo key in the file. A Jina key raises its rate limit
Language model
Runs gpt-4o-mini to pick the best contact email from a site’s text, or to answer Null.
NeedsOpenAI API key
Email search
Searches a business’s domain for addresses when its site gave none, and returns them for the sheet.
NeedsAnymail Finder API key, and credit for the lookups
Lead sheet
Saves each business with its details and email, matched on its title, and updates the email when Anymail Finder finds one.
NeedsA Google account to sign in with, and a sheet with seven headers
Checked by Mindket on 13 Nov 2026
This n8n workflow turns a Google Maps search into a sheet of local businesses with a contact email for each. A form takes a keyword, a place and how many results you want. An Apify Actor collects the businesses. The workflow then visits each one’s website through Jina and has gpt-4o-mini pick the best contact email on it. When the page has none, Anymail Finder searches the site’s domain instead. Every business is saved to Google Sheets with its address, phone and link. Ten nodes run in one loop.
Freelancers, agencies and small sales teams that sell to local businesses, such as dentists, restaurants or plumbers, and need an address to write to, not only a phone number. Skip it if a phone number is enough for you. The email steps add most of the cost and the time.
| Industry | Who uses it | How they use it | Example |
|---|---|---|---|
| Web design and SEO | Freelancers and small agencies | Search one trade in one city and pitch the businesses with a weak site | A designer searches dentists in one city and writes to the ones whose site looks dated. |
| Home and trade services | Suppliers and software sellers | Build a list of contractors for each trade | A tool seller lists roofers in three towns and writes to the ones that have an address. |
| Local marketing | Account managers | Run one search for each area a client serves | An account manager runs a search for each neighborhood a client covers. |
| Recruiting and staffing | Recruiters | Find employers in a trade and a place | A recruiter lists hotels in a resort town and writes to the address on each hotel’s site. |
You need some n8n and four accounts: Apify, OpenAI, Anymail Finder and Google. Its author puts setup at about 16 minutes, which assumes the accounts already exist.
Any n8n that can reach Apify, OpenAI, Jina, Anymail Finder and Google will run it. The sheet is the one place you read the results.
Get it saves a zip with workflow.json and Mindket’s setup notes in your downloads folder. Make the sheet first, since two nodes point at it.
| Need | Detail |
|---|---|
| n8n | On n8n Cloud or on a server of your own |
| Apify | An account, its API token and credit, for the Google Maps Actor |
| OpenAI | An API key that can use gpt-4o-mini |
| Anymail Finder | An account, its API key and credit, for the sites with no email |
| An account that can edit the sheet, for a Google Sheets OAuth2 credential | |
| A sheet | A tab named Sheet1 with seven headers in row 1: Title, Street, Neighborhood, Website, Phone, Email and URL |
workflow.json./d/ and /edit.Append or update row in sheet1 and Update row in sheet, select it and replace YOUR_SHEET_ID with the ID. Both find the tab by the name Sheet1.Message a model.HTTP Request1, replace <YOUR_APIFY_TOKEN> in the Authorization header with your token. The brackets go too, so the header reads Bearer, a space and the token.Anymail, replace <YOUR_ANYMAILFINDER_KEY> in the Authorization header with your key and nothing else.Anymail Finder’s documentation, read on 2 November 2026, gives the key as the whole header value, with no Bearer before it. The file’s placeholder had one, so it is gone here.
Open the form from On form submission1 and fill in Keyword, Location and Max results. None is marked required. Still, an empty Max results breaks the request. The form answers as soon as it is sent. Nothing shows in the sheet until Apify has finished the search. Then the rows arrive one at a time, and a row’s email may be filled in a moment later by the Anymail Finder step.
| To change | Where |
|---|---|
| Kind of business and place | The form’s Keyword and Location fields. The Actor takes free text for both |
| Number of places | Max results in the form, which sets maxCrawledPlacesPerSearch |
| Language of the results | language in the body of HTTP Request1, en in the file |
| Which email wins | The prompt in Message a model, which asks for the most authoritative address |
| Columns saved | Edit Fields and the mapping in both Google Sheets nodes |
You enter this in the form:
Keyword: dentist Location: Austin, Texas Max results: 20
Apify returns up to that many dentists. For each one, a row is written like this one:
| Column | Value |
|---|---|
| Title | Bright Smile Dental |
| Street | 120 Congress Ave |
| Neighborhood | Downtown |
| Website | https://brightsmile.example |
| Phone | +15125550123 |
| info@brightsmile.example | |
| URL | The business’s Google Maps address |
When the site holds no email, the model answers Null and the row first says so. Once Anymail replies, Email holds the list it returned, such as ["info@brightsmile.example"].
If you are new. n8n draws a workflow as boxes joined by lines, and each box, a node, does one job. Here Loop Over Items hands one business at a time down the chain and takes it back at the end. Run it with 10 places first. Each node then shows what it received and sent, which is where a wrong key or a blocked website turns up.
For experts. The whole run sits in one loop, and each stage is one or two nodes.
| Stage | Nodes | What to know |
|---|---|---|
| Search | HTTP Request1 | A POST to Apify’s run-sync-get-dataset-items for the Actor compass~crawler-google-places. The body holds searchStringsArray, locationQuery, maxCrawledPlacesPerSearch and language |
| Tidy | Edit Fields | Keeps seven fields and takes the domain from the website with extractDomain() |
| Read | Scrape Website, Message a model | Jina returns the page as plain text, and gpt-4o-mini answers with one address or the word Null |
| Save | Append or update row in sheet1, Update row in sheet | Both match rows on Title |
| Fallback | If, Anymail | An answer holding Null sends the domain to Anymail Finder, and its list of addresses is written to Email |
The check for Null is case-sensitive. Scrape Website and Anymail carry on when a call fails, so a dead site does not stop the loop.
Three vendors bill by use, one free service has a cap, and the file calls an older Anymail Finder address.
Title, so two businesses with one name overwrite each otherv5.0/search/company.json and reads results.emails. The current documentation describes v5.1/find-email/company, with the addresses in emails. The older one still answered when we checked. If it stops, change bothAn n8n workflow. A form takes a keyword, a place and a number. An Apify Actor collects the matching businesses from Google
Maps, and the workflow reads each business's website to find a contact email. When the site has none, Anymail Finder
searches the domain. Every business is saved to a Google Sheet.
workflow.json: the workflow as n8n exports it, ten nodes and no sticky notes. It holds no credential.README.md: these notes.Bearer <api key>. They now say Bearer <YOUR_APIFY_TOKEN><YOUR_ANYMAILFINDER_KEY>. Anymail Finder's documentation, read on 2 November 2026, gives the key as the wholeBearer before it, so the second one has none.YOUR_SHEET_ID and find the tab by the nameSheet1.gpt-4o-mini.Jina's Reader needs no key in this file.
workflow.json.Sheet1 and these headers in row 1: Title, Street, Neighborhood, Website,Phone, Email, URL. Copy the sheet's ID: the long part of its address between /d/ and /edit.Append or update row in sheet1 and Update row in sheet, select it andYOUR_SHEET_ID with the ID.Message a model.HTTP Request1, replace <YOUR_APIFY_TOKEN> in the Authorization header with your token. The brackets go too, soAnymail, replace <YOUR_ANYMAILFINDER_KEY> in the Authorization header with your key, and nothing else.Max results, and watch the sheet.Keyword, Location and Max results. None is marked required.HTTP Request1 posts them to Apify's run-sync-get-dataset-items address for the Actor compass~crawler-google-placesen.Edit Fields keeps Title, Street, Neighborhood, Website, Phone (from phoneUnformatted) and URL, and adds aDomain taken from the website.Loop Over Items takes one place at a time. Then Scrape Website fetches its site through Jina's Reader athttps://r.jina.ai/, which returns the page as plain text. Next, Message a model asks gpt-4o-mini for the bestNull when there is none.Append or update row in sheet1 saves the place with that answer in Email, matching rows on Title.If looks for Null in the answer. When it is there, Anymail searches the place's Domain, and Update row in sheetEmail. Otherwise the loop moves to the next place.language in the body of HTTP Request1.Message a model. It asks for the most authoritative address.Edit Fields.Title, so two businesses with the same name overwrite each other.Max results leaves the Apify request body broken. Fill all three form fields.v5.0/search/company.json address and reads results.emails. Its currentv5.1/find-email/company, which returns the addresses in emails. The older address still$json.emails in Update row in sheet.Null is case-sensitive.README.md 5 KB workflow.json 16 KB
alchaincyf · Skill
Turns a one-line request in your AI agent into a finished design: a launch animation, a clickable app prototype, an editable slide deck, an infographic or a se…
op7418 · Skill
Skill that makes single-file HTML slide decks, slide illustrations and platform covers in two visual styles, with a presenter mode for rehearsal. For speakers…
alirezarezvani · Skill
Adds 411 ready-made skills for Claude Code and other coding agents, grouped by role from engineering and product to marketing, finance and compliance. Installs…
nerijs · Kit
A pixel art style add-on for Stable Diffusion XL that turns text prompts into pixel-style images, with an optional LCM LoRA for faster runs. For game makers, d…
LiconStudio · Kit
Keeps characters, clothing, objects and backgrounds consistent in generated video by feeding the model up to five reference images. A LoRA for LTX-2.5 in Comfy…
nhathoangfoto · Kit
A LoRA for FLUX.2 Klein 9B that puts a character into the pose shown by a mannequin reference while keeping the character's face and style. For artists and des…