Att bygga outreach-listor från Google Maps låter enkelt tills du faktiskt gör det. Du kopierar namn, klistrar in adresser, missar telefonnummer och hamnar ändå med dubbletter som får ditt ark att se “klart” ut medan resultaten visar något helt annat.
Det här drabbar marknadsförare som kör lokala kampanjer först, men byråägare och sales ops-folk känner av det också. Med automation för Google Maps leads gör du en stökig manuell uppgift till ett repeterbart system som håller din lista strukturerad och redo att kontakta.
Det här arbetsflödet hämtar Google Maps-listningar via SerpAPI, formaterar datan, tar bort dubbletter och lägger till allt i Google Sheets. Du får se hur det fungerar, vad du behöver och vad du ska se upp med för att det ska rulla stabilt.
Så fungerar den här automationen
Hela n8n-arbetsflödet, från trigger till slutlig output:
n8n Workflow Template: Google Maps till Google Sheets: rensade leadlistor
flowchart LR
subgraph sg0["When clicking "Execute Workflow" Flow"]
direction LR
n0@{ icon: "mdi:play-circle", form: "rounded", label: "When clicking 'Execute Workf..", pos: "b", h: 48 }
n1["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/code.svg' width='40' height='40' /></div><br/>Extract next start value"]
n2["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/code.svg' width='40' height='40' /></div><br/>Merge all values from SERPAPI"]
n3["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/code.svg' width='40' height='40' /></div><br/>Transform data in the right .."]
n4@{ icon: "mdi:database", form: "rounded", label: "Add rows in Google Sheets", pos: "b", h: 48 }
n5["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/httprequest.dark.svg' width='40' height='40' /></div><br/>SERPAPI - Scrape Google Maps.."]
n6["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/itemLists.svg' width='40' height='40' /></div><br/>Remove duplicate items"]
n7["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/itemLists.svg' width='40' height='40' /></div><br/>Split out items"]
n8@{ icon: "mdi:swap-horizontal", form: "rounded", label: "Remove empty values", pos: "b", h: 48 }
n9@{ icon: "mdi:database", form: "rounded", label: "Google Sheets - Get searches..", pos: "b", h: 48 }
n10@{ icon: "mdi:swap-vertical", form: "rounded", label: "Extract keyword and location..", pos: "b", h: 48 }
n11@{ icon: "mdi:play-circle", form: "rounded", label: "Run workflow every hours", pos: "b", h: 48 }
n12@{ icon: "mdi:database", form: "rounded", label: "Update Status to Success", pos: "b", h: 48 }
n13@{ icon: "mdi:database", form: "rounded", label: "Update Status to Error", pos: "b", h: 48 }
n14@{ icon: "mdi:swap-horizontal", form: "rounded", label: "Continue IF Loop is complete", pos: "b", h: 48 }
n7 --> n8
n8 --> n3
n6 --> n4
n1 --> n14
n11 --> n9
n4 --> n12
n14 --> n5
n14 --> n2
n2 --> n7
n5 --> n1
n5 --> n13
n0 --> n9
n3 --> n6
n10 --> n5
n9 --> n10
end
%% Styling
classDef trigger fill:#e8f5e9,stroke:#388e3c,stroke-width:2px
classDef ai fill:#e3f2fd,stroke:#1976d2,stroke-width:2px
classDef aiModel fill:#e8eaf6,stroke:#3f51b5,stroke-width:2px
classDef decision fill:#fff8e1,stroke:#f9a825,stroke-width:2px
classDef database fill:#fce4ec,stroke:#c2185b,stroke-width:2px
classDef api fill:#fff3e0,stroke:#e65100,stroke-width:2px
classDef code fill:#f3e5f5,stroke:#7b1fa2,stroke-width:2px
classDef disabled stroke-dasharray: 5 5,opacity: 0.5
class n0,n11 trigger
class n8,n14 decision
class n4,n9,n12,n13 database
class n5 api
class n1,n2,n3 code
classDef customIcon fill:none,stroke:none
class n1,n2,n3,n5,n6,n7 customIcon
Problemet: Google Maps leads blir röriga när de samlas in manuellt
Manuell scraping från Google Maps är en långsam ström av frustration. Du börjar med en sökning, öppnar listning efter listning och försöker sedan standardisera det du hittar: telefonnummer i olika format, webbplatser som saknas i vissa profiler och adresser som inte klistras in snyggt i separata kolumner. Sedan kommer den verkliga smärtan senare. Du kontaktar samma företag två gånger eftersom dubbletter smög sig in, eller så inser du att din “leadlista” saknar det enda fältet som din outreach bygger på. Det är inte svårt arbete. Det är konstant arbete där misstag lätt uppstår.
Friktionen bygger på. Här är var det faller isär i verkligheten.
- Du lägger cirka 2 timmar på att sätta ihop en lista, och sedan ytterligare en timme på att städa den.
- Dubbletter smyger sig in när du kör samma sökning nästa vecka och inte minns vad du redan har fångat.
- Datan blir inkonsekvent, så sortering och filtrering blir ett jobb istället för ett snabbt beslut.
- En saknad detalj (som webbplats eller telefonnummer) gör outreach till extra research för varenda post.
Lösningen: hämta Google Maps via SerpAPI till ett strukturerat Google Sheet
Det här n8n-arbetsflödet gör en Google Maps-sökning till en strukturerad leadlista i Google Sheets, utan copy-paste-loopen. Det börjar med att läsa dina inputs från ett ark (inklusive din Google Maps-sök-URL), och omvandlar sedan det till de query-detaljer som SerpAPI behöver. Därefter hämtar det Google Maps-resultat via SerpAPI, fortsätter att paginera via nästa “start”-index och slår ihop allt till en enhetlig mängd. Sedan filtrerar det bort tomma poster, formaterar varje plats till konsekventa fält, tar bort dubbletter och lägger till endast strukturerade rader i ditt målark. Om anropet misslyckas markerar arbetsflödet den inputen som misslyckad så att du slipper gissa vad som hände.
Arbetsflödet startar enligt ett schema varje timme (eller manuellt när du vill). Det hämtar listningar från Google Maps via SerpAPI, städar och deduplicerar datasetet. Till sist skriver det nya rader till Google Sheets och markerar körningen som lyckad så att du kan följa upp.
Vad du får: automation vs. resultat
| Vad det här arbetsflödet automatiserar | Resultat du får |
|---|---|
|
|
Exempel: så här ser det ut
Säg att du behöver 200 lokala leads varje måndag inför en ny outreach-satsning. Manuellt, även om du bara lägger 1 minut per listning för att öppna, kopiera och klistra in kärnuppgifter, blir det runt 3 timmar — och det brukar bli längre när städningen börjar. Med det här arbetsflödet lägger du din Google Maps-sök-URL i input-arket, låter den schemalagda körningen plocka upp den och väntar på att SerpAPI-hämtningen och formateringen blir klar (ofta runt 15 minuter). Ditt output-ark uppdateras med deduplicerade rader, redo för outreach samma morgon.
Det här behöver du
- n8n-instans (prova n8n Cloud gratis)
- Alternativ för self-hosting om du föredrar det (Hostinger fungerar bra)
- Google Sheets för att lagra inputs och output-leads.
- SerpAPI för att hämta Google Maps-listningar till en rimlig kostnad.
- SerpAPI API-nyckel (hämta den i din SerpAPI-dashboard).
Svårighetsgrad: Medel. Du kopplar konton, klistrar in en API-nyckel och är bekväm med att mappa kalkylarkskolumner mot arbetsflödets förväntade inputs.
Vill du inte sätta upp detta själv? Prata med en automationsexpert (gratis 15-minuters konsultation).
Så fungerar det
Schemalagd eller manuell trigger. Arbetsflödet körs varje timme som standard, och du kan även starta det manuellt när du lägger till en ny sökning och vill ha resultat direkt.
Hämtning och parsning av input. n8n läser din Google Maps-sök-URL från Google Sheets och extraherar sedan query- och geo-parametrar som behövs för att köra en konsekvent hämtning.
SerpAPI-hämtning med paginering. Arbetsflödet anropar SerpAPI för Google Maps-resultat, tar fram nästa “start”-index och loopar tills det inte finns något mer att hämta (eller tills din konfigurerade gräns är nådd).
Städning, deduplicering och åter-skrivning. Resultaten slås ihop, delas upp till enskilda plats-poster, filtreras för tomma poster och formateras till konsekventa fält. Dubbletter tas bort, därefter läggs nya rader till i ditt Google Sheet och input-raden markeras som lyckad (eller misslyckad om hämtningen inte fungerade).
Du kan enkelt ändra vilka kolumner du fångar så att det matchar ditt outreach-flöde, så att arket innehåller exakt det som teamet använder. Se hela implementationsguiden nedan för anpassningsalternativ.
Steg-för-steg-guide för implementering
Steg 1: konfigurera schematriggern
Ställ in de timvisa och manuella triggrarna så att arbetsflödet kan köras automatiskt eller vid behov.
- Öppna Hourly Schedule Trigger och ställ in intervallregeln så att den körs varje timme (fältet hours).
- Låt Manual Run Trigger vara kvar för testning och engångskörningar.
- Verifiera att båda triggrarna är kopplade till Retrieve Search Inputs som visas i canvasen.
Steg 2: anslut Google Sheets
Konfigurera Google Sheets-noderna som läser sökingångar och skriver status/resultat.
- Öppna Retrieve Search Inputs och ställ in Document ID till
https://docs.google.com/spreadsheets/d/[YOUR_ID]/edit#gid=0och Sheet Name till fliken med namnetAdd your search here. - I Retrieve Search Inputs behåller ni filtret på Status (uppslagskolumn) för att bara hämta rader som väntar.
- Öppna Append Rows to Sheet och ställ in Document ID till
https://docs.google.com/spreadsheets/d/[YOUR_ID]/edit#gid=2023033319och Sheet Name tillResults. - Bekräfta att Append Rows to Sheet använder Operation
appendOrUpdateoch att Matching Columns inkluderarplace_id. - I Mark Status Successful och Mark Status Failed behåller ni Operation som
updateoch kolumnvärdet för URL som{{ $('Retrieve Search Inputs').first().json.URL }}. - Inloggning krävs: Anslut era googleSheetsOAuth2Api-uppgifter i Retrieve Search Inputs, Append Rows to Sheet, Mark Status Successful och Mark Status Failed.
Tips: Säkerställ att bladet Results innehåller alla kolumner som listas i Append Rows to Sheet (t.ex. place_id, title, address) för att undvika mappningsproblem.
Steg 3: ställ in tolkning av sökfråga och SERPAPI-anrop
Extrahera frågeparametrar från inmatnings-URL:erna och anropa SERPAPI Maps-endpointen.
- I Parse Query and Geo ställer ni in keyword till
{{ $json.URL.match(/\/search\/(.*?)\//)[1] }}och geo till{{ $json.URL.match(/(@[^\/?]+)/)[1]}}. - Öppna SERPAPI Maps Request och ställ in URL till
https://serpapi.com/search.json. - I SERPAPI Maps Request låter ni Send Query vara aktiverat och lägger till följande frågeparametrar: engine
google_maps, q{{ $json?.search_parameters?.q || $json.keyword }}, ll{{ $json?.search_parameters?.ll|| $json.geo }}, typesearchoch start{{ $json.start|| 0 }}. - Inloggning krävs: Anslut era serpApi-uppgifter i SERPAPI Maps Request.
⚠️ Vanlig fallgrop: Om formatet på er inmatnings-URL ändras kan regex:en i Parse Query and Geo returnera tomma värden, vilket gör att SERPAPI misslyckas.
Steg 4: konfigurera loopning och aggregering av resultat
Hantera paginering och konsolidera SERPAPI-resultat till en enhetlig datamängd.
- I Parse Next Start Index behåller ni Mode inställt på
runOnceForEachItemoch behåller den tillhandahållna JavaScript-koden för att extrahera nästastart-värde. - Konfigurera Loop Continuation Check med villkor för att kontrollera att search_parameters.start och serpapi_pagination.next inte är tomma med
{{ $json.search_parameters.start }}och{{ $json.serpapi_pagination.next }}. - Säkerställ att den sanna grenen i Loop Continuation Check fortsätter till SERPAPI Maps Request och att den falska grenen går till Combine SERPAPI Results.
- I Combine SERPAPI Results behåller ni den tillhandahållna koden som aggregerar
local_resultsöver alla SERPAPI-anrop.
Steg 5: bearbeta och avduplicera utdata
Dela upp, rensa och avduplicera SERP-resultaten innan de infogas i bladet Results.
- I Split Result Items ställer ni in Field to Split Out till
allData. - I Filter Empty Entries ställer ni in villkoret för att kontrollera att
{{ $json[0] }}inte är tomt. - Behåll JavaScript-koden i Format Data Payload för att slå ihop alla objekt per item och returnera poster som inte är null.
- I Eliminate Duplicate Records ställer ni in Operation till
removeDuplicates, Compare tillselectedFieldsoch Fields to Compare tillplace_id.
Steg 6: konfigurera utdata och statusuppdateringar
Skriv den rensade datan till Google Sheets och uppdatera bearbetningsstatus baserat på om körningen lyckas eller misslyckas.
- Bekräfta att Eliminate Duplicate Records är kopplad till Append Rows to Sheet för att lagra slutresultaten.
- Säkerställ att Append Rows to Sheet är kopplad till Mark Status Successful för att sätta Status till
✅. - Verifiera att SERPAPI Maps Request har sin felutgång kopplad till Mark Status Failed, som sätter Status till
❌.
Tips: Behåll Append Rows to Sheet Cell Format som RAW för att undvika oönskade formateringsändringar i er Results-flik.
Steg 7: testa och aktivera ert arbetsflöde
Validera arbetsflödet från början till slut och aktivera sedan timvis bearbetning.
- Klicka på Execute Workflow på Manual Run Trigger för att genomföra en testkörning.
- Bekräfta att Append Rows to Sheet lägger till rader i Results-fliken och att Mark Status Successful uppdaterar status för inmatningsraden till
✅. - Om fel uppstår, kontrollera att Mark Status Failed uppdaterar status för inmatningsraden till
❌och granska SERPAPI-svaret. - Aktivera arbetsflödet så att Hourly Schedule Trigger körs automatiskt varje timme.
Vanliga fallgropar
- Google Sheets-inloggningar kan gå ut eller kräva specifika behörigheter. Om något slutar fungera, börja med att kontrollera n8n:s test av credential-anslutningen och delningsinställningarna för Sheet.
- Om du använder Wait-noder eller extern rendering varierar processtiderna. Öka väntetiden om noder längre fram misslyckas på tomma svar.
- SerpAPI:s rate limits och kvoter är på riktigt. Om du börjar se misslyckade körningar, kontrollera användningen i din SerpAPI-dashboard och bekräfta att din API-nyckel fortfarande är aktiv.
Vanliga frågor
Cirka 30 minuter om dina Sheets och din SerpAPI-nyckel är redo.
Ingen kodning krävs. Du kopplar främst konton, lägger till din SerpAPI-nyckel och mappar några kalkylarksfält.
Ja. n8n har ett gratis self-hosted-alternativ och en gratis provperiod på n8n Cloud. Cloud-planer börjar på 20 USD/månad för högre volym. Du behöver också räkna in SerpAPI-kostnader (det varierar med plan och volym, men är vanligtvis billigare än den officiella Google Maps API:n för det här användningsfallet).
Två alternativ: n8n Cloud (hanterat, enklast att komma igång) eller self-hosting på en VPS. För self-hosting är Hostinger VPS prisvärd och klarar n8n bra. Self-hosting ger obegränsade körningar men kräver grundläggande serverhantering.
Ja, och det är en vanlig justering. Lägg till flera Google Maps-sök-URL:er som separata input-rader i arket “Retrieve Search Inputs” och justera sedan formateringskoden så att varje output-rad innehåller en kolumn för “källfråga” eller “plats”. Om du vill ha olika output-ark per stad kan du routa items efter “Parse Query and Geo” med en If-nod och skriva till olika Google Sheets-noder.
Oftast är det ett behörighetsproblem: Google-kontot som är kopplat i n8n kommer inte åt kalkylarket, eller så har Sheet-ID:t ändrats. Kontrollera n8n:s Google Sheets-credential igen, öppna sedan kalkylarket och bekräfta att det är delat med samma konto. Säkerställ också att fliknamnet på målarket matchar vad noden förväntar sig. Liten missmatch, stor huvudvärk.
Med n8n Cloud Starter kan du köra ett bra antal körningar varje månad för mindre kampanjer, och högre nivåer hanterar mer. Om du kör self-hosted finns ingen körningsgräns, men din server och din SerpAPI-kvot blir de faktiska begränsningarna. I praktiken kör de flesta team detta per sök-URL och hämtar några hundra platser per körning utan problem, och schemalägger sedan uppdatering dagligen eller veckovis.
Ofta, ja. Det här arbetsflödet behöver loopa genom resultatsidor, slå ihop batchar och deduplicera innan du skriver till Sheets — den typen av logik blir snabbt klumpig (och dyr) i Zapier. n8n hanterar branching och kodsteg snyggt, och self-hosting betyder att du kan köra det så ofta du vill utan att oroa dig för per-task-debitering. Zapier eller Make kan fortfarande funka om du bara vill ha ett litet tvåstegsflöde, som “ny rad i Sheets → skicka Slack-meddelande”. Om du är osäker, prata med en automationsexpert så får du ett rakt svar utifrån din situation.
Strukturerade leadlistor är en tillväxtspak som de flesta team behandlar som tråkigt merarbete. Sätt upp detta en gång, så håller sig ditt Google Sheets fyllt med nya, deduplicerade Google Maps leads medan du fokuserar på outreach som faktiskt konverterar.
Kontakta oss
Hör av dig, så diskuterar vi hur just din verksamhet kan dra nytta av alla fantastiska möjligheter som AI skapar.