AI-powered lead-generation engine that discovers local businesses without a professional website using the official Google Places API, qualifies them as leads, and drafts personalized outreach with human-in-the-loop approval.
Full project spec & roadmap: see issue #1.
- 🔍 Discover businesses via Google Places API (Nearby Search + Place Details) — no scraping, ToS-compliant
- 🧹 Filter: keeps only businesses with no website or only a social/aggregator link (Facebook, Instagram, JustDial, Linktree, ...)
- 🧮 Rule-based lead scoring (rating, review activity, contactability)
- 🗄️ SQLite storage with deduplication on
place_id
- 🤖 Pitch-angle agent: one-line personalized pitch per lead
- ✉️ Outreach-drafting agent: personalized email + WhatsApp drafts (LLM-powered via any OpenAI-compatible API, with template fallback when no key is set)
- 👤 Human-in-the-loop: drafts queue for review — approve or skip, nothing is ever sent automatically
- 📲 WhatsApp click-to-chat deep links (
wa.me) with the approved draft prefilled — sent from your own account, no automation ban risk
python -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
cp .env.example .env # add your keys + personal details
uvicorn app.main:app --reloadOpen interactive docs at http://127.0.0.1:8000/docs
# 1. Discover leads around a location
curl -X POST http://127.0.0.1:8000/discover \
-H 'Content-Type: application/json' \
-d '{"lat": 28.6139, "lng": 77.2090, "radius_m": 3000, "category": "restaurant"}'
# 2. List top qualified leads
curl 'http://127.0.0.1:8000/leads?min_score=50'
# 3. Generate AI drafts for a lead (queued for YOUR review)
curl -X POST http://127.0.0.1:8000/leads/1/drafts
# 4. Review the queue, then approve or skip
curl 'http://127.0.0.1:8000/messages?status=draft'
curl -X POST http://127.0.0.1:8000/messages/2/approve
# 5. Get a one-click WhatsApp link with the draft prefilled
curl http://127.0.0.1:8000/messages/2/whatsapp-link| Variable | Description | Default |
|---|---|---|
GOOGLE_PLACES_API_KEY |
Google Cloud API key with Places API enabled | — (required) |
DATABASE_URL |
SQLAlchemy database URL | sqlite:///./clienthawk.db |
LLM_API_KEY |
Key for any OpenAI-compatible API (empty = template drafts) | empty |
LLM_BASE_URL |
OpenAI-compatible endpoint (OpenAI, Groq, OpenRouter, Ollama) | https://api.openai.com/v1 |
LLM_MODEL |
Model name | gpt-4o-mini |
SENDER_NAME / SENDER_TITLE |
Your name and title used in drafts | — |
SENDER_EMAIL / SENDER_PHONE |
Your contact details for signatures | — |
PORTFOLIO_URL / RESUME_URL |
Links attached to every draft | — |
pytestA built-in dashboard is served at http://127.0.0.1:8000/ — pipeline stats, top leads, and the draft review queue with one-click approve / skip / send / WhatsApp actions.
- 📨 Email sending via Resend with an unsubscribe footer on every email
- 🛑 Opt-out registry: contacts who opt out are never contacted again
- ⏱️ Daily send cap (default 25) to protect sender reputation
- 📋 Mini-CRM:
PATCH /leads/{id}(stage, contact email, notes, follow-up date),GET /pipelinestage counts,GET /followupsdue reminders
Note: if you ran an earlier version, delete
clienthawk.dbonce so the new columns are created.
- 🧩 Chrome extension (
extension/): floating "Add to ClientHawk" button on Google Maps place pages + popup with pipeline stats and one-click capture - 🎯
POST /capture— resolve a business by name (Places Find Place API), store and qualify it - 📊
GET /analytics— response rate, conversion rate, emails sent, funnel counts
- Start the backend (
uvicorn app.main:app --reload) - Open
chrome://extensions, enable Developer mode - Click Load unpacked and select the
extension/folder - Browse Google Maps — a 🦅 button appears on place pages
- Phase 1: Discovery pipeline (Places API, filtering, scoring)
- Phase 2: AI pitch + outreach drafting agents with approval queue
- Phase 3: Email sending (Resend), opt-outs, send caps, mini-CRM, dashboard
- Phase 4: Chrome extension, one-click capture, analytics
- Official APIs only — no Google Maps DOM scraping
- Human approval required before any outbound message
- WhatsApp via click-to-chat links from your own account (no bulk automation)
- Opt-outs persisted, per-day send caps (Phase 3)