Resumen
Agencies y local servicio proveedores necesita un steady pipeline of business leads. Este flujo de trabajo ejecuta cada manana, searches Google Maps via Scavio for businesses in your objetivo categorias y ubicaciones, extrae contact informacion (nombre, address, phone, sitio web, rating), deduplicates contra your existing base de datos, y exporta fresh leads. Searching 5 categorias a traves de 3 ubicaciones costs about 15 credits per dia ($0.075).
Desencadenador
Cron 6 AM UTC diario
Programación
Diario 6 AM
Pasos del flujo de trabajo
Cargar Target Configuracion
Leer objetivo business categorias (plumbers, dentists, etc.) y ubicaciones de un archivo de configuracion.
Search Google Maps via Scavio
For cada category-location pair, call Scavio search on Google Maps to encontrar coincidencia businesses.
Extraer Contact Information
Analizar cada resultado for business nombre, address, phone numero, sitio web, rating, y resena conteo.
Deduplicate Against Database
Verificar cada lead contra your existing leads base de datos by phone o sitio web to avoid duplicates.
Exportar Fresh Leads
Escribir nuevo leads to un CSV o push to your CRM via webhook for immediate follow-up.
Implementacion en Python
import requests, os, json, csv
from pathlib import Path
from datetime import date
API_KEY = os.environ["SCAVIO_API_KEY"]
SH = {"x-api-key": API_KEY, "Content-Type": "application/json"}
CONFIG_FILE = Path("lead_gen_config.json")
SEEN_FILE = Path("seen_leads.json")
LEADS_DIR = Path("leads")
LEADS_DIR.mkdir(exist_ok=True)
def search_maps(query: str) -> list:
resp = requests.post(
"https://api.scavio.dev/api/v1/search",
headers=SH,
json={"query": query, "platform": "google-maps"},
timeout=15,
)
resp.raise_for_status()
return resp.json().get("organic", [])
def extract_lead(result: dict, category: str, location: str) -> dict:
return {
"name": result.get("title", ""),
"address": result.get("address", ""),
"phone": result.get("phone", ""),
"website": result.get("website", result.get("url", "")),
"rating": result.get("rating"),
"reviews": result.get("reviews"),
"category": category,
"location": location,
}
def run():
config = json.loads(CONFIG_FILE.read_text())
seen = set()
if SEEN_FILE.exists():
seen = set(json.loads(SEEN_FILE.read_text()))
new_leads = []
for cat in config["categories"]:
for loc in config["locations"]:
query = f"{cat} in {loc}"
results = search_maps(query)
for r in results:
lead = extract_lead(r, cat, loc)
dedup_key = lead["phone"] or lead["website"] or lead["name"]
if dedup_key and dedup_key not in seen:
seen.add(dedup_key)
new_leads.append(lead)
SEEN_FILE.write_text(json.dumps(list(seen)))
if new_leads:
out = LEADS_DIR / f"leads_{date.today()}.csv"
with open(out, "w", newline="") as f:
writer = csv.DictWriter(f, fieldnames=new_leads[0].keys())
writer.writeheader()
writer.writerows(new_leads)
print(f"Generated {len(new_leads)} new leads on {date.today()}")
for l in new_leads[:10]:
print(f" {l['name']} | {l['phone']} | {l['category']} | {l['location']}")
run()Implementacion en JavaScript
const SH = {'x-api-key': process.env.SCAVIO_API_KEY, 'Content-Type': 'application/json'};
const fs = await import('fs');
const config = JSON.parse(fs.readFileSync('lead_gen_config.json', 'utf8'));
const LEADS_DIR = 'leads';
try { fs.mkdirSync(LEADS_DIR); } catch {}
let seen = new Set();
try { seen = new Set(JSON.parse(fs.readFileSync('seen_leads.json', 'utf8'))); } catch {}
async function searchMaps(query) {
const r = await fetch('https://api.scavio.dev/api/v1/search', {method:'POST', headers:SH, body:JSON.stringify({query, platform:'google-maps'})});
return (await r.json()).organic || [];
}
const newLeads = [];
for (const cat of config.categories) {
for (const loc of config.locations) {
const results = await searchMaps(cat+' in '+loc);
for (const r of results) {
const lead = {name:r.title||'', address:r.address||'', phone:r.phone||'', website:r.website||r.url||'', rating:r.rating, reviews:r.reviews, category:cat, location:loc};
const dedupKey = lead.phone || lead.website || lead.name;
if (dedupKey && !seen.has(dedupKey)) {
seen.add(dedupKey);
newLeads.push(lead);
}
}
}
}
fs.writeFileSync('seen_leads.json', JSON.stringify([...seen]));
if (newLeads.length) {
const header = Object.keys(newLeads[0]).join(',');
const rows = newLeads.map(l => Object.values(l).map(v => '"'+(v===null||v===undefined?'':String(v).replace(/"/g,'""'))+'"').join(','));
const today = new Date().toISOString().split('T')[0];
fs.writeFileSync(LEADS_DIR+'/leads_'+today+'.csv', header+'\n'+rows.join('\n')+'\n');
}
console.log('Generated '+newLeads.length+' new leads');
newLeads.slice(0,10).forEach(l => console.log(' '+l.name+' | '+l.phone+' | '+l.category+' | '+l.location));Plataformas utilizadas
Google Maps
Búsqueda de negocios locales con calificaciones e información de contacto