Tutorial

How to Build a Complete Google Maps to WhatsApp Outreach Pipeline

Complete pipeline from Google Maps business search to WhatsApp message templates with phone number extraction and message personalization.

An r/coldemail thread asked for a complete pipeline from finding businesses on Google Maps to sending WhatsApp messages. This tutorial covers the full loop: search by category and location, extract phone numbers, generate personalized messages, and create click-to-chat links. All data comes from one API.

Prerequisites

  • Scavio API key
  • Python 3.8+
  • WhatsApp Business account or personal WhatsApp

Walkthrough

Step 1: Batch search Google Maps by category

Search multiple categories across a city.

Python
import requests, os
H = {'x-api-key': os.environ['SCAVIO_API_KEY']}

def batch_maps_search(categories, city):
    all_leads = []
    for cat in categories:
        data = requests.post('https://api.scavio.dev/api/v1/search',
            headers=H,
            json={'platform': 'google', 'query': f'{cat} in {city}',
                  'type': 'maps'}).json()
        for b in data.get('local_results', []):
            b['category'] = cat
            all_leads.append(b)
    return all_leads

categories = ['restaurant', 'dentist', 'gym', 'salon']
leads = batch_maps_search(categories, 'Miami FL')

Step 2: Clean and validate phone numbers

Format phone numbers for WhatsApp (needs country code).

Python
import re

def clean_phone(phone, country_code='1'):
    if not phone:
        return None
    digits = re.sub(r'\D', '', phone)
    if len(digits) == 10:
        digits = country_code + digits
    if len(digits) < 11:
        return None
    return digits

def extract_leads_with_phones(businesses):
    valid = []
    for b in businesses:
        phone = clean_phone(b.get('phone'))
        if phone:
            valid.append({
                'name': b.get('title', ''),
                'phone': phone,
                'category': b.get('category', ''),
                'rating': b.get('rating'),
                'address': b.get('address', ''),
            })
    return valid

Step 3: Generate category-specific WhatsApp messages

Different templates for different business types.

Python
templates = {
    'restaurant': 'Hi! I saw {name} has great reviews ({rating} stars). '
        'I help restaurants increase online orders with a simple website update. '
        'Worth a quick chat?',
    'dentist': 'Hi! I came across {name} and noticed you serve the {area} area. '
        'I help dental practices get more patients through online visibility. '
        'Can I send over a quick case study?',
    'default': 'Hi! I found {name} on Google Maps ({rating} stars -- impressive). '
        'I help local businesses like yours grow their online presence. '
        'Would you be open to a quick chat?'
}

def generate_wa_link(lead, service_templates=templates):
    template = service_templates.get(lead['category'], service_templates['default'])
    msg = template.format(name=lead['name'], rating=lead.get('rating', 'great'),
        area=lead.get('address', '').split(',')[0] if lead.get('address') else 'your')
    encoded = requests.utils.quote(msg)
    return f"https://wa.me/{lead['phone']}?text={encoded}"

Step 4: Export the complete pipeline output

CSV with all lead data and WhatsApp links.

Python
import csv

def export_pipeline(leads, filename='whatsapp_pipeline.csv'):
    with open(filename, 'w', newline='') as f:
        fields = ['name', 'phone', 'category', 'rating', 'address', 'wa_link']
        writer = csv.DictWriter(f, fieldnames=fields)
        writer.writeheader()
        for lead in leads:
            lead['wa_link'] = generate_wa_link(lead)
            writer.writerow({k: lead.get(k, '') for k in fields})
    print(f'Exported {len(leads)} leads to {filename}')

# Pipeline: 4 categories = 4 queries = $0.02 total
leads = batch_maps_search(['restaurant', 'dentist', 'gym', 'salon'], 'Miami FL')
valid = extract_leads_with_phones(leads)
export_pipeline(valid)

Python Example

Python
import os, requests, re
H = {'x-api-key': os.environ['SCAVIO_API_KEY']}

def maps_to_whatsapp(category, city):
    data = requests.post('https://api.scavio.dev/api/v1/search', headers=H,
        json={'platform': 'google', 'query': f'{category} in {city}', 'type': 'maps'}).json()
    for b in data.get('local_results', []):
        phone = re.sub(r'\D', '', b.get('phone', ''))
        if len(phone) >= 10:
            print(f"{b['title']}: https://wa.me/{phone}")

maps_to_whatsapp('salon', 'Austin TX')

JavaScript Example

JavaScript
const res = await fetch('https://api.scavio.dev/api/v1/search', {
  method: 'POST',
  headers: {'x-api-key': process.env.SCAVIO_API_KEY, 'Content-Type': 'application/json'},
  body: JSON.stringify({platform: 'google', query: `${category} in ${city}`, type: 'maps'})
}).then(r => r.json());
res.local_results?.filter(b => b.phone).forEach(b => {
  const phone = b.phone.replace(/\D/g, '');
  console.log(`${b.title}: https://wa.me/${phone}`);
});

Expected Output

JSON
CSV with business name, phone, category, rating, address, and WhatsApp click-to-chat link. Category-specific message templates. 4 categories = $0.02 total.

Related Tutorials

Frequently Asked Questions

Most developers complete this tutorial in 15 to 30 minutes. You will need a Scavio API key (free tier works) and a working Python or JavaScript environment.

Scavio API key. Python 3.8+. WhatsApp Business account or personal WhatsApp. A Scavio API key gives you 500 free credits per month.

Yes. The free tier includes 500 credits per month, which is more than enough to complete this tutorial and prototype a working solution.

Scavio has a native LangChain package (langchain-scavio), an MCP server, and a plain REST API that works with any HTTP client. This tutorial uses the raw REST API, but you can adapt to your framework of choice.

Start Building

Complete pipeline from Google Maps business search to WhatsApp message templates with phone number extraction and message personalization.