Back to index
Live · Case study 002

02 — Technical case study

Lead-gen
engine.

Pipeline ETL en 8 fases que convierte una región geográfica en una secuencia de cold emails B2B hipersegmentados — con previews HTML personalizados generados por IA y compliance LSSI-CE de serie.

Role
Solo engineer
Year
2026
Status
Live · production
Scope
Pipeline · CLI · Compliance
Stack
Python · Playwright · Claude
Sector
Sales · Outreach · NDA

01

Pipeline.

Numbered stages · CSV between

Cada fase es un script independiente con un único contrato — lee CSV, escribe CSV. Re-ejecutables, atómicas, debuggables paso a paso.

  1. 01

    Scrape Maps

    Iteración sobre N localidades × M categorías vía Google Places API (New). Emite data/leads_raw.csv con place_id, web declarada, geo y metadata. Idempotente — re-ejecutable sin duplicar.

  2. 02

    Qualify

    Filtra leads que no cumplen criterios de "web pobre": ausencia de sitio, no-https, redirección a redes sociales (linktr.ee, instagram, facebook), PageSpeed mobile < 50, o load > 5s. Razón de descarte registrada en cada fila.

  3. 02.5

    Enrich emails (cascade)

    Búsqueda en cascada hasta encontrar email: (1) scraping de la web propia → (2) Google Custom Search snippets → (3) bio Instagram → (4) "About" Facebook. Marca enrichment_status con la fuente exacta o not_found.

  4. 03

    Generate previews

    Claude genera HTML personalizado por lead — hero, secciones, CTA — con brief de estilo determinista. Playwright abre Chromium headless en viewport 1440×2000 y captura PNG. Archivos quedan en previews/<place_id>/.

  5. 04

    Send

    Envío vía Gmail SMTP con app password. Preview embebido inline cid: para máximo impacto visual. Throttle 75s ± 25% entre envíos, max 50/run, blacklist y log de envíos en data/sent_log.csv para idempotencia.

  6. 05+

    Multi-channel queue

    Para leads sin email descubierto, scripts secundarios alimentan colas alternativas: 05_whatsapp_queue.py + 06_open_whatsapp.py abren WhatsApp Web pre-rellenado, 07_manual_queue.py exporta CSV para gestión manual.

02

Flow.

CSV-driven · idempotent

// pipeline · stage flow

  config.yaml
       │
       ▼
  ┌──────────────┐    leads_raw.csv
  │ 01 scrape    │ ─────────────────▶ Places API
  └──────┬───────┘
         ▼
  ┌──────────────┐    leads_qualified.csv
  │ 02 qualify   │ ─────────────────▶ PageSpeed API
  └──────┬───────┘    (filter: pobre web)
         ▼
  ┌──────────────┐    + email column
  │ 02.5 enrich  │ ─────────────────▶ web · CSE · IG · FB
  └──────┬───────┘    (cascade fallback)
         ▼
  ┌──────────────┐    previews/<id>/index.html
  │ 03 previews  │ ─────────────────▶ Claude API
  └──────┬───────┘    Playwright PNG
         ▼
  ┌──────────────┐    sent_log.csv
  │ 04 send      │ ─────────────────▶ Gmail SMTP
  └──────────────┘    inline preview · throttle

03

Legal.

Compliance baked-in

Cold email B2B serio — no growth-hack. Cumplimiento LSSI-CE codificado a nivel de pipeline, no de buena voluntad.

Marco legal
LSSI-CE art. 21 — España / UE
Audiencia
Solo personas jurídicas (B2B). Emails personales descartados
Identificación
Remitente, NIF y dirección física en cada email
Opt-out
Link de baja funcional · respuesta automática añade a blacklist
Throttle
75 s ± 25% entre envíos · 50 emails/run · warm-up progresivo
Idempotencia
sent_log.csv evita re-envíos · place_id como clave única

04

Integrations.

8 external APIs orchestrated

Lead source
Google Places API (New) — búsquedas geo-segmentadas con radio configurable
Quality signal
Google PageSpeed Insights API — score mobile, LCP, blocking time
Email enrichment
Cascada — web scraping + Google CSE + Instagram bio + Facebook About
Content generation
Anthropic Claude (sonnet) con prompt de estilo determinista
Visual capture
Playwright Chromium headless · viewport 1440×2000 · screenshot PNG
Color sampling
ColorThief + Pillow para extraer paleta visual del logo/web del lead
Email rendering
Jinja2 templates · Premailer para inline-CSS · cid: para imágenes embebidas
Delivery
Gmail SMTP con app password · BCC opcional · dry-run mode

05

Stack.

Production dependencies

Core

  • Python 3.10+
  • pandas
  • PyYAML
  • python-dotenv
  • Jinja2
  • requests

AI · Visual

  • anthropic 0.39+
  • Playwright 1.45+ (Chromium)
  • Pillow
  • ColorThief
  • Premailer

Web

  • Flask 3.0 (preview server)
  • tldextract

Pipeline

  • 8 numbered stages
  • Idempotent re-runs
  • Single-lead shortcut
  • Dry-run mode

End of case study

Need a pipeline
like this?