Skip to content
PIRANGUEIROPublic

About

Prospecção B2B: 30 empresas em 20km (Overpass+Nominatim) → 30 RH → 19 e-mails SMTP → Twenty CRM (api.exemplo.com mock)

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

3 Commits

Folders and files

Repository files navigation

Corvina

CI Python License Status Version Python Shell JSON Markdown

Prospecção B2B automatizada: 30 empresas industriais num raio de 20km de Campo Comprido (Curitiba) → 30 contatos de RH/Talent Acquisition → 19 e-mails validados via SMTP → carga no Twenty CRM com deduplicação e campo customizado.

🚧 Projeto em desenvolvimento (WIP) — não está finalizado
Pipeline funcional em modo demo (prints em docs/images/, APIs api.exemplo.com mock, 30 empresas + 19 EXISTS), mas com 11 e-mails pendentes, sem testes unitários automatizados e sem pipeline de follow-up. Uso real requer .api_key do Twenty e validação dos padrões restantes. Veja ## Limitations e ## Roadmap.

Overview

Contexto

Empresas B2B precisam prospectar indústrias grandes e decisores de RH num território específico — neste caso, 20km ao redor de Rua Osvaldo Tosato, 200, Campo Comprido (-25.443952, -49.347013), Curitiba/PR. Não existe base pronta de "indústrias no raio + RH com e-mail válido". A prospecção manual é lenta, propensa a duplicatas no CRM e sem validação de e-mail (catch-all, padrões corporativos diversos como @br.bosch.com vs @bosch.com).

Problema

Como, sem custo de APIs pagas de IA, (1) descobrir empresas industriais no raio, (2) geocodificar e filtrar por distância, (3) encontrar o responsável de RH para cada uma, (4) gerar e validar e-mails via SMTP (MX + RCPT TO 250/550), e (5) carregar tudo no Twenty CRM sem duplicar empresas, com campo customizado Setor e notas vinculadas?

Solução

O Corvina implementa o pipeline completo com APIs mock (https://api.exemplo.com) configuráveis via .env, totalmente local e gratuito:

1. Descoberta geográfica (src/overpass_search.py:1) — Overpass API mock (api.exemplo.com/overpass/interpreter) busca industrial no raio; Nominatim mock (api.exemplo.com/nominatim) geocodifica endereços; filtra 20/23 dentro de 20km + 3 manuais (Zhengchang, EBANX, Horsch) → examples/empresas_raio20.json (30 empresas, 22 setores únicos).

2. Carga Twenty CRM (src/push_twenty.py:1) — cria campo customizado Setor via POST /rest/metadata/fields, POST /rest/companies (30), PATCH /rest/companies/{id} (setor), com deduplicação por name/domainName (evita 7 duplicatas como bosch.com removidas).

3. RH + Validação (src/gen_candidates.py:1, src/smtp_verify.py:1) — pesquisa web manual (30 RHs, 12 cargos diferentes, 100% cobertura) → gen_candidates.py gera 320 candidatos first.last@domain (10 variações) → smtp_verify.py resolve MX via dnspython, abre SMTP porta 25, EHLO, MAIL FROM, RCPT TO, verifica 250 EXISTS vs 550 NOT_FOUND, incremental/resumível → 19 EXISTS (63%), 11 pendentes, 3 catch-all identificados (EBANX, Electrolux, TOTVS retornam 250 para tudo).

4. Contatos e Notas — POST /rest/people (30, vinculados à company), POST /rest/notes com bodyV2.markdown + POST /rest/noteTargets (2 vínculos por nota, 87 notas totais).

Resultado: 30 empresas | 30 people | 30 notas | 1 campo custom | 7 duplicatas removidas — tudo gratuito, em uma sessão (2026-08-07), com logs push_*.json e smtp_results.json.

Demo

Interface demo (Corvina B2B Prospecting):

Descoberta — 30 empresas em 20km, 22 setores, mapa Overpass+Nominatim

Descoberta de Empresas

Contatos RH — 30 contatos, 12 cargos, 19 e-mails validados EXISTS

Contatos RH

Validação SMTP — 320 gerados, 19 EXISTS, 301 NOT_FOUND, 3 catch-all

Validação SMTP

CRM Twenty — 30 empresas, 30 contatos, 30 notas, 1 campo custom Setor

CRM Twenty

Features

  • ✅ Busca geográfica Overpass+Nominatim mock (raio 20km, tag industrial)
  • ✅ Campo customizado Twenty CRM Setor via metadata API
  • ✅ Geração de 320 candidatos de e-mail (10 padrões first.last@domain)
  • ✅ Validação SMTP real (MX + RCPT TO 250/550, incremental, resume-safe)
  • ✅ Deduplicação por name/domainName antes de POST (7 removidas)
  • ✅ Carga via curl subprocess (evita Cloudflare 1010 do urllib)
  • ✅ Notas com cargo/fonte/status e vínculo duplo (person+company)

Architecture

flowchart LR
    A["Overpass OSM - industrial 20km"] --> B["Nominatim - geocode"]
    B --> C["empresas_raio20.json - 30 empresas"]
    C --> D["Twenty CRM - POST companies"]
    D --> E["PATCH setor - metadata API"]
    E --> F["Web Research - 30 RH"]
    F --> G["gen_candidates.py - 320 emails"]
    G --> H["smtp_verify.py - 19 EXISTS"]
    H --> I["push_twenty.py - 30 people + 30 notes"]
Loading

Componentes: src/overpass_search.py:1, src/gen_candidates.py:1, src/smtp_verify.py:1, src/push_twenty.py:1, docs/architecture.md.

Tech Stack

Camada Tecnologia Linguagem Uso
Linguagem Python 3.11 (100%) Python Scripts CLI (~500 linhas)
Geocodificação api.exemplo.com (mock) HTTP/JSON Overpass + Nominatim
CRM api.exemplo.com/twenty/rest/ (mock) REST/JSON Twenty Cloud (Postgres)
Validação dnspython, asyncio Python MX resolve + SMTP RCPT
HTTP requests, curl (subprocess) Python/Shell Evita Cloudflare 1010

Linguagens no repositório: Python detectado pelo GitHub Linguist (todos src/*.py), com Shell auxiliar (curl). Sem JS/TS — scripts puros.

Nota: todas as URLs externas são https://api.exemplo.com por padrão (mock). Aponte TWENTY_API_URL, OVERPASS_URL, NOMINATIM_URL no .env para endpoints reais.

Project Structure

corvina/
├── src/
│   ├── overpass_search.py    # Busca geográfica mock
│   ├── gen_candidates.py     # Gera 320 candidatos first.last@domain
│   ├── smtp_verify.py        # Valida via MX + RCPT TO
│   └── push_twenty.py        # Wrapper REST Twenty via curl
├── docs/
│   ├── images/               # Prints demo (4 telas)
│   ├── architecture.md
│   └── repository-audit.md
├── examples/
│   ├── empresas_raio20.json  # 5 empresas exemplo
│   ├── contacts_final.json   # 3 contatos exemplo
│   └── smtp_results.json     # 5 veredictos exemplo
├── .github/workflows/ci.yml
├── .env.example
├── requirements.txt
└── README.md

Installation

git clone https://github.com/PIRANGUEIRO/corvina.git
cd corvina
python -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt

cp .env.example .env
# edite TWENTY_API_KEY e aponte TWENTY_API_URL para https://api.exemplo.com/rest/ quando for real
chmod 600 .env  # como .api_key original

Configuration

Variável Descrição Obrigatória
TWENTY_API_URL Base REST Twenty não (mock default)
TWENTY_API_KEY Bearer token workspace sim quando real
OVERPASS_URL Overpass interpreter não (mock)
NOMINATIM_URL Nominatim search não (mock)

Nunca commitar .env ou .api_key.

Usage

# 1. Descoberta geográfica (mock)
python src/overpass_search.py --lat -25.443952 --lon -49.347013 --radius 20000

# 2. Gerar candidatos (a partir de rh_empresas.json)
python src/gen_candidates.py  # gera candidates.json (320)

# 3. Validar SMTP (incremental, resumível)
python src/smtp_verify.py candidates.json smtp_results.json

# 4. Push para Twenty (mock por padrão)
python src/push_twenty.py --companies examples/empresas_raio20.json

API

  • POST /rest/companies, PATCH /rest/companies/{id}, POST /rest/metadata/fields (campo Setor TEXT)
  • POST /rest/people, POST /rest/notes (bodyV2.markdown + blocknote:null), POST /rest/noteTargets
  • Filtro: --data-urlencode "filter=name[eq]:Copel" (escapa [ ])

Testing

  • Integração real: 30 companies, 30 people, 30 notas, 320 SMTP verificados via GET no CRM (ver 04-Testes/Testes.md)
  • E2E: fluxo completo validado, 7 duplicatas removidas via DELETE
  • Sem unitários automatizados (scripts one-shot). CI faz py_compile.

Technical Decisions

Decisão Motivo Alternativa Trade-off
Overpass+Nominatim Gratuito, sem chave Google Places (pago) Sem garantia de cobertura total
SMTP RCPT Gratuito, preciso (M365) Hunter (pago) Catch-all gera falso positivo
curl via subprocess Evita Cloudflare 1010 urllib (falhou) Menos pythônico
bodyV2.markdown Único aceito pela REST Twenty body (não existe) Requer blocknote:null
.api_key chmod 600 Segredo fora do código env var Manual

Limitations

  • 11 e-mails pendentes (padrões corporativos não descobertos: Volvo @volvo.com, Bosch @br.bosch.com, etc.)
  • 3 catch-all (EBANX, Electrolux, TOTVS) → 10 EXISTS falsos por pessoa
  • Sem testes unitários, sem retry/backoff no SMTP (sequencial, lento para 320)
  • Sem pipeline de follow-up

Roadmap

  • Descobrir padrões das 11 empresas restantes e validar
  • Enriquecimento LinkedIn
  • Wrapper REST único (api.py) para substituir curl one-shot
  • Retry com backoff no SMTP
  • Teste de deduplicação automatizado

License

MIT — ver LICENSE.

What this project demonstrates

  • Python (CLI, asyncio, dnspython, subprocess, typing)
  • Data Engineering (Overpass/Nominatim, JSON, geocoding, 20km radius)
  • API Integration (Twenty REST, Overpass, Nominatim, SMTP)
  • Security (chmod 600, Bearer, mock por padrão)
  • System Design (deduplicação, incremental resume, curl vs urllib)

About

Prospecção B2B: 30 empresas em 20km (Overpass+Nominatim) → 30 RH → 19 e-mails SMTP → Twenty CRM (api.exemplo.com mock)

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages