
n8n ile Google Maps Lead Otomasyonu: Adım Adım Rehber
Evet, n8n ile Google Maps müşteri adayı toplama süreci otomatikleştirilebilir. Akış BasedOnB API üzerinden bir tarama işi başlatır, iş bitene kadar kontrollü aralıklarla durumu okur, bütün sonuç sayfalarını çeker ve işletmeleri Google Sheets ya da CRM'e aktarır.
Sağlam bir otomasyon yalnız ilk POST isteğinden oluşmaz. Aynı isteğin iki kez iş açmaması, durum kontrolünün sonsuza kadar sürmemesi, hata dallarının ayrılması ve sonuçların 500'er satırlık sayfalar halinde alınması gerekir. Aşağıdaki örnek, İstanbul'daki diş kliniklerini hedefleyen denetlenebilir bir akış kurar.
Hangi alanların gerçekten işe yaradığından emin değilseniz önce Google Maps müşteri listesi rehberine bakın. Buradaki akış, kategori, konum, hedef kayıt sayısı ve aktarılacak alanların önceden belirlendiğini varsayar.
n8n'i açmadan önce gerekenler
Şunları hazırlayın:
- Dışarıya HTTPS isteği gönderebilen bir n8n kurulumu.
- Tarama okuma ve yazma yetkili bir BasedOnB API anahtarı. Anahtar
bdb_live_ile başlar. place_idgibi sabit bir dış kimliği saklayabilen Sheet, CRM listesi veya tablo.- Idempotency anahtarına dönüşecek kampanya ya da kaynak olay kimliği.
- Net bir sorgu, ülke, il, şehir ve hedef kayıt sayısı.
API anahtarını panelde oluşturun ve n8n içinde Header Auth kimlik bilgisi olarak saklayın. Canlı anahtarı Edit Fields düğümüne, dışa aktarılan akış dosyasına, ekran görüntüsüne veya destek mesajına yapıştırmayın. Güncel adresler ve yanıt alanları BasedOnB API dokümanında bulunur.
Toplu işleri planlamadan önce sınırları bilin. Bir iş en fazla 10 sorgu taşıyabilir. Bir hesapta aynı anda en fazla 2 açık iş bulunabilir. Açık işlerin toplam hedefi 5.000 kaydı geçemez. pending, submitted ve running durumları açık iş sayılır. Bu sınırları görmezden gelen bir zamanlama sonunda 429 kapasite yanıtı alır.
Akışın kısa görünümü
Polling akışı şu sırayı izler:
- Schedule Trigger veya Webhook bir kampanya alır.
- Edit Fields isteği düzenler ve sabit idempotency anahtarını ekler.
- HTTP Request,
POST /api/v1/scrapesisteğini gönderir. - IF,
statusCodealanını kontrol eder; başarılı yanıt tek öğeli polling durumuna çevrilir. - Wait ve Edit Fields, durum dalındaki
attemptdeğerini artırır. - HTTP Request,
GET /api/v1/scrapes/:idçağrısını yapar; Merge yanıtı durum öğesiyle birleştirir. - Switch, HTTP hatalarını,
done,failed,cancelledve açık durumları ayırır. donedalı sonuç sayfalarını çeker ve öncestatusCodealanını kontrol eder.- Her sayfa bir kez ikiye ayrılır:
body.resultsSplit Out'a, tek kontrol öğesibody.pagekontrolüne gider. - Kontrol dalı sonraki cursor değerini bir kez ister ve yanıtı aynı iki dal noktasına döndürür.
Resmi HTTP Request düğümü rehberi kimlik doğrulama, header, sorgu parametresi ve yanıt ayarlarını anlatır. Wait düğümü rehberi ise süreli bekleme ve devam etme davranışını açıklar.
1. Sabit bir istek oluşturun
Tetikleyiciden sonra Edit Fields düğümü ekleyin. İstanbul örneği için alanlar şöyle olabilir:
{
"query": "dental clinics",
"country": "TR",
"state": "TR.34",
"city": "Istanbul",
"target_leads": 250
}
query kategori veya arama ifadesidir. country, state ve city alanı bölgeyi belirler. target_leads, istenen işletme kaydı sayısıdır. Bu değer kullanılabilir krediye ve açık iş sınırlarına uymalıdır.
Ayrıca idempotency_key alanı ekleyin. Örneğin istanbul-dis-klinikleri-2026-08-parti-01 gibi saklanan bir kampanya kimliği kullanın. CRM kampanya kodu veya kaynak sistemdeki olay kimliği de uygundur. Şimdiki zamanı kullanmayın. n8n yeniden çalıştığında yeni bir zaman damgası üretirse sunucu bunu yeni istek sayabilir.
2. Tarama işini başlatın
HTTP Request düğümünü şöyle ayarlayın:
- Method:
POST - URL:
https://www.basedonb.com/api/v1/scrapes - Authentication:
Authorization: Bearer bdb_live_...gönderen Header Auth kimlik bilgisi - Header: Edit Fields içindeki değerden
Idempotency-Key - Body Content Type: JSON
- Body: yukarıdaki beş istek alanı
- Options > Response > Include Response Headers and Status: açık
- Options > Response > Never Error: açık
- Options > Response > Response Format: JSON
Bu yanıt ayarları, n8n'in 2xx dışındaki yanıtları düğümü durdurmadan output olarak vermesini sağlar. Tam öğede statusCode, headers ve body bulunur. Önce $json.statusCode üzerinden dallanın. Yalnız 2xx yanıtı iş durumu mantığına devam etsin. Bu yanıt için Poll State adlı Edit Fields düğümünde job_id = {{$json.body.id}}, job_status = {{$json.body.status}} ve attempt = 0 alanlarını oluşturun. Diğer durum kodlarını ortak HTTP hata dalına gönderin.
Yeni iş çoğu zaman submitted döner. Hazır bir ortak sonuç varsa done da dönebilir. Bu nedenle 2xx kontrolünden sonra, beklemeden önce $json.body.status alanını okuyun.
Aynı idempotency anahtarı ve aynı gövde yeniden gönderildiğinde ilk iş döner. Aynı anahtarı başka şehir, sorgu veya hedef sayısıyla kullanmak çakışma üretir. Anahtarı ve istek gövdesini tek bir kayıt gibi saklayın.
3. Wait, IF ve deneme sınırıyla polling yapın
Başarılı POST sonrasında oluşturulan Poll State öğesini kullanın. job_status alanını şu yollara ayırın:
done: doğrudan sonuç adımına geçin.failedveyacancelled: terminal hata dalına gidin.pending,submittedveyarunning: Wait düğümüne geçin.
Wait için örneğin 15 saniye belirleyin. Beklemeden sonra Edit Fields ile job_id alanını koruyun ve attempt = {{$json.attempt + 1}} yapın. Bu tek durum öğesini iki kola bağlayın. Bir kol doğrudan Merge düğümünün Input 1 girişine gitsin. Diğer kol şu adresi çağırsın:
GET https://www.basedonb.com/api/v1/scrapes/{{$json.job_id}}
Aynı Header Auth kimlik bilgisini ve POST düğümündeki üç Response ayarını kullanın. Durum HTTP yanıtını Merge düğümünün Input 2 girişine bağlayın. Merge ayarını Mode: Combine ve Combine By: Position yapın. Böylece birleşen öğede job_id ve attempt, statusCode ve body yanında kalır. GET yanıtı sayacı silemez.
Merge sonrasında gövdeyi okumadan önce $json.statusCode alanını kontrol edin. 2xx dışındaki öğeleri ortak HTTP hata dalına gönderin. 2xx yanıtında Switch, $json.body.status alanını okuyarak done, failed, cancelled veya açık durum ayrımını yapsın. Açık durum dalındaki ayrı IF, Wait'e dönmeden önce $json.attempt sınırını kontrol etsin.
Wait'e dönmeden önce ikinci bir IF koyun. attempt belirlediğiniz sınıra ulaştığında polling'i durdurun ve iş kimliğiyle sorumlu kişiye bildirim gönderin. Örneğin 15 saniyelik 40 deneme, bu n8n çalışmasının sınırını belirler. Her işin on dakikada biteceğini vaat etmez. Deneme sınırında işi otomatik iptal etmeyin. Sunucudaki iş daha sonra tamamlanabilir.
failed ve cancelled dalları kesinlikle döngüye bağlanmamalıdır. Terminal durumu, iş kimliğini, kampanya kodunu ve varsa istek kimliğini kaydedin. Yeni iş açmak gerekiyorsa bunu hatalı girdiyi inceledikten sonra yapın.
4. Bütün sonuç sayfalarını alın
Sonuç adresini yalnız durum done olduktan sonra çağırın:
GET https://www.basedonb.com/api/v1/scrapes/{{$json.id}}/results
Sorgu parametresi limit değerini 500 yapın. Diğer HTTP Request düğümlerindeki gibi Include Response Headers and Status ile Never Error seçeneklerini açın ve Response Format olarak JSON seçin. Önce $json.statusCode alanını kontrol edin; 2xx dışındaki öğeler ortak hata dalına gitsin. Başarılı tam yanıt şu biçimdedir:
{
"statusCode": 200,
"body": {
"id": "scrape-job-id",
"status": "done",
"results": [],
"page": {
"limit": 500,
"next_cursor": "next-page-token",
"has_more": true,
"total": 1250
}
}
}
Başarılı sayfa yanıtını tek öğe olarak tutup iki kola bağlayın. Veri kolu body.results üzerinde Split Out çalıştırır, sonra satırları eşleyip upsert eder. Kontrol kolu Split Out üzerinden geçmez. Bu koldaki IF, $json.body.page.has_more alanını okur ve işletme başına değil sayfa başına bir kez çalışır.
Kontrol kolu true olduğunda Edit Fields ile job_id = {{$json.body.id}} ve cursor = {{$json.body.page.next_cursor}} oluşturun. Next Results adlı HTTP Request, aynı adresi limit=500 ve bu cursor ile, aynı Response ayarlarını kullanarak çağırsın. Yanıtını ilk sayfanın kullandığı statusCode kontrolüne ve iki kola ayrılma noktasına geri bağlayın. False dalı sayfalamayı bitirir. Bir sayfada en fazla 500 satır olduğundan 1.250 kayıt üç istek gerektirir.
total değerini ilk yanıttaki satır sayısı sanmayın. Kendi sayfa numaranızı üretmeyin. Sunucunun verdiği cursor değerini aynen izleyin. Her sayfayı bir sonraki isteği yapmadan önce hedefe yazmak, yarıda kalan akışı kurtarmayı kolaylaştırır.
5. Google Sheets veya CRM alanlarını eşleyin
Veri dalında body.results dizisini Split Out ile satırlara ayırın. Ardından Edit Fields düğümünde hedef şemayı açıkça kurun:
| BasedOnB alanı | Hedef alan |
|---|---|
place_id | external_id |
title | company_name |
category | category |
address | address |
phone | phone |
website | website |
rating | google_rating |
reviews_count | google_review_count |
Tekrar kontrolü için place_id kullanın. CRM'de doğrudan create yerine upsert seçin. Google Sheets'te önce bu kimliği arayın, varsa satırı güncelleyin, yoksa ekleyin. Sadece append kullanırsanız n8n çalışması tekrar oynatıldığında kopya satırlar oluşur.
Upsert kullanın ve her sayfa için iş kimliği ile cursor değerini saklayın. Tek öğeli kontrol dalı, veri dalı satırları yazarken sonraki sayfayı çekebilir. Mutlaka yazma bittikten sonra çekmek istiyorsanız hedef daldan tek bir sayfa tamamlandı sinyali üretip kontrol öğesini bununla bekletin. Sonraki sayfa IF düğümünü Split Out sonrasına bağlamayın; aksi halde aynı cursor her sonuç için çağrılır.
Aktarımdan sonra lead listesi kalite karnesi ile eksik alan, tekrar, tazelik ve kaynak kontrollerini yapabilirsiniz. Listeyi yapay zeka asistanına verecekseniz yapay zeka ile müşteri adayı bulma rehberi, hangi işi modelin hangi işi veri kaynağının yapması gerektiğini ayırır.
Sık görülen hatalar
Never Error açık olduğu için her HTTP düğümünde iş alanlarından önce $json.statusCode üzerinden dallanın. 2xx dışındaki yanıtlarda $json.body.error.code ve $json.body.error.details alanlarını inceleyin. Hata gövdesi bu amaçlı dalda kullanılabilir.
401 Unauthorized: anahtar eksik, bozuk veya iptal edilmiştir. n8n kimlik bilgisini kontrol edin. Anahtarı execution log içine yazdırmayın.
403 Forbidden: anahtar geçerlidir ancak gereken tarama yetkisi yoktur. Yalnız gereken okuma ve yazma yetkilerine sahip kimlik bilgisini kullanın.
402 Payment Required: hesapta kredi, abonelik veya ödeme işlemi gerekir. Akışı durdurun ve hesap sahibine bildirin.
409 Conflict: aynı idempotency anahtarı farklı gövdeyle kullanılmıştır. Saklanan anahtar ile gövdeyi karşılaştırın. Aynı anahtarı yalnız ilk gövdeyi geri yükledikten sonra yeniden deneyin; bilerek yeni bir iş açacaksanız yeni ve sabit bir anahtar kullanın.
429 Too Many Requests: $json.body.error.details.reason alanını inceleyin. too_many_open_scrapes, 2 açık işten birinin bitmesini beklemeniz demektir. open_leads_limit, beklemeniz veya yeni hedefi açık işlerin toplamı 5.000'i geçmeyecek biçimde azaltmanız demektir. reason yoksa bunu istek hızı sınırı sayın; Retry-After yanıt başlığını veya $json.body.error.details.retry_after_seconds değerini sınırlı bir Wait dalında kullanın. Hızlı döngü başlatmayın.
Boş sonuç sayfası: iş durumunu kontrol edin. İş hâlâ açıkken sonuç adresi boş sayfa döndürebilir. Sonuç isteği, durum kontrolünün yerine geçmez.
Daha geniş olay tabanlı akışlar için Zapier ve Make otomasyon rehberindeki ilkeleri de kullanabilirsiniz. İş kimliği, terminal durumlar ve tekrar güvenli yazma her araçta önemlidir.
Polling mi webhook mu?
Polling kurması ve izlemesi kolaydır. Tek seferlik işler, seyrek zamanlamalar ve API'yi yeni öğrenen ekipler için uygundur. Bedeli, tekrar eden durum çağrıları ve deneme sayısını taşıyan bir n8n çalışmasıdır.
Webhook, işler sık çalışıyorsa veya süreleri değişiyorsa daha iyi seçimdir. n8n tamamlanma olayını alır, imzayı doğrular ve yalnız o zaman sonuç sayfalama dalını başlatır. Yine de hata yönetimi, cursor sayfalaması ve upsert gerekir. Webhook yalnız bitiş bilgisinin nasıl geldiğini değiştirir.
Durum modelini anlamak için sınırlı polling ile başlayın. Tekrarlanan kontroller operasyon yüküne dönüştüğünde webhook'a geçin.
Sık Sorulan Sorular
n8n Google Maps müşteri adaylarını otomatik toplayabilir mi?
Evet. n8n, BasedOnB REST API üzerinden bir Google Maps işletme araması başlatabilir, iş sürerken bekleyebilir, bütün sonuç sayfalarını çekebilir ve satırları Google Sheets ya da CRM'e gönderebilir. API anahtarını iş akışı alanında değil n8n kimlik bilgisinde saklayın.
Bu iş akışı için hangi n8n düğümleri gerekir?
Tetikleyici, Edit Fields, HTTP Request, Wait, IF veya Switch, Merge, Split Out ve hedef sistem düğümünü kullanın. Merge, durum yanıtının yanında polling sayacını korur. Split Out yalnız veri dalında kalır, böylece sayfalama kontrol dalı tek öğe taşır.
Neden Idempotency-Key göndermeliyim?
Bu başlık, tekrarlanan POST isteğini güvenli yapar. Aynı anahtar ve aynı istek yeniden gönderildiğinde yeni iş açılmaz, ilk iş döner. Saat bilgisinden anahtar üretmek yerine sabit bir kampanya veya kaynak olay kimliği saklayın.
n8n iş durumunu ne sıklıkla kontrol etmeli?
Durum isteklerinin arasına Wait düğümü koyun ve en yüksek deneme sayısı belirleyin. Sabit 10 ile 20 saniyelik aralık pratik bir başlangıçtır, ancak bitiş süresi sözü değildir. Sınıra gelince sonsuza kadar sorgulamak yerine akışı durdurup sorumlu kişiye haber verin.
500'den fazla sonucu nasıl alırım?
Bir istekte en fazla 500 satır alın. Tam HTTP yanıtındaki body.page.has_more ve body.page.next_cursor alanlarını okuyun. Sayfalamayı tek öğeli kontrol dalında tutun ve has_more false olana kadar sonuç adresini cursor ile yeniden çağırın.
n8n içinde polling mi webhook mu kullanmalıyım?
Polling ilk akış ve seyrek işler için daha kolaydır. Sık ya da uzun süren işler için imzalı webhook daha uygundur, çünkü n8n tekrar tekrar durum isteği atmak yerine tamamlanma olayını bekler. İki yöntemde de sonuçlar cursor ile sayfalanır.
İş failed veya cancelled olursa ne yapılmalı?
failed ve cancelled durumlarını terminal kabul edin. Sonuç istemeyin ve bu dalı yeniden Wait düğümüne bağlamayın. İş kimliğini ve durumu kaydedin, sorumlu kişiye bildirin ve yeni istek açma kararını ayrıca verin.
İlk işi küçük ve kurtarılabilir tutun
Tek kategori, tek şehir ve gözle kontrol edebileceğiniz bir hedef tabloyla başlayın. Yeni BasedOnB hesabına kart gerekmeden tek seferlik 50 dışa aktarma kredisi gelir. Hedefi büyütmeden önce alan eşlemesini, idempotency anahtarını, hata dalını ve upsert kuralını bu kayıtlarla doğrulayın.
Kimlik bilgisini oluşturun, sınırlı ilk akışı çalıştırın ve her aktarılmış satırın yanında iş kimliğini saklayın. Bu küçük kaynak bilgisi, otomasyonu denetlemeyi ve gerektiğinde onarmayı kolaylaştırır.