Leads / docs /guide.md
abc1181's picture
Mappls: support static REST key (MAPPLS_API_KEY) as well as OAuth
0b4f70e
|
Raw History Blame Contribute Delete
9.05 kB

LeadGen β€” Step-by-Step Guide (Personal Tool by AJ)

Single-owner India SMB finder: Maps β†’ no-website hunt β†’ scoring β†’ AI icebreakers β†’ Sheets. No bulk sending from this server.


1) What you need before you start

  • A Gmail account (owner β€” this will be the only login allowed via APP_ALLOW_EMAIL)
  • A Hugging Face account (for the Space at https://abc1181-leads.hf.space)
  • Optional but recommended: a Google Cloud project (for Places + OAuth) β€” free tier is enough

2) Create the Hugging Face Space

The code is already pushed to abc1181/Leads (Docker). Just configure envs:

  1. HF β†’ Space abc1181/Leads β†’ Settings β†’ Variables (non-secrets) and Secrets (tokens)
  2. Set the essentials below (Section 3). The Space auto-restarts on save.
  3. Check https://abc1181-leads.hf.space/api/health β†’ should be {"ok":true,"db":"ok","persistence":"on"}. If persistence:off, the Space has no /data bucket β€” it will still run on ephemeral /tmp (banner shows), but add a bucket at /data in Space Settings for durability.

3) Env vars β€” what to create

3.1 Essentials (app won't work without these)

Set in HF Variables unless marked Secret:

Key Where Value / How
APP_ALLOW_EMAIL Variables Your Gmail exactly β€” only this can sign in (middleware.ts:39, lib/auth.ts:14)
GOOGLE_CLIENT_ID Variables From Google Cloud OAuth (see 4.1)
GOOGLE_CLIENT_SECRET Secrets Same OAuth client
NEXTAUTH_SECRET Secrets Random 32b hex: openssl rand -hex 32 (already set)
NEXTAUTH_URL Variables https://abc1181-leads.hf.space (already set)
PLACES_API_KEY Secrets Google Places API key (see 4.2) β€” or leave empty and use the free OSM/Ola rail (Section 4.3)

Also needed (already set, don't change): DATABASE_URL=file:/data/leads.db, CRON_SECRET, ENCRYPTION_KEY

3.2 Optional β€” add when you want more coverage

Key Where Free tier Notes
OLA_API_KEY Secrets 100k/API/mo free India best free β€” docs/maps-providers.md#5
MAPPLS_CLIENT_ID + MAPPLS_CLIENT_SECRET Secrets Free eval, no card India best address hit β€” docs/maps-providers.md#4
FOURSQUARE_API_KEY Secrets 500 free calls Global fallback
HERE_API_KEY Secrets ~5k-250k free (needs card) Global fallback
ENRICH_PROVIDER=hunter + ENRICH_API_KEY Secrets 25-50/mo free Else phone is spine, emails stay unknown
LLM_BASE_URL + LLM_API_KEY + LLM_MODEL=mistral-large-latest Secrets Your gateway Else fallback templates (lib/ai/fallback.ts)
SMTP_HOST/PORT/USER/PASS or RESEND_API_KEY + DIGEST_TO Secrets/Vars 100/d free Else digest is in-app only
MOCK_SOURCES=1 Variables β€” Use for demo with 50 Delhi fixtures, no keys

No billing? Leave PLACES_API_KEY empty β€” the 6-provider rail (lib/sources/maps.ts) runs on OSM Overpass (free, no key) + OLA_API_KEY/MAPPLS_* if you set them. Add Google later and it stacks β€” no rebuild.


4) How to get each credential

4.1 Google OAuth (for Sign-in + Sheets)

  1. https://console.cloud.google.com β†’ Create project β†’ APIs & Services β†’ OAuth consent screen β†’ External β†’ fill App name, Support email β†’ Save
  2. Credentials β†’ Create Credentials β†’ OAuth client ID β†’ Web application β†’ Authorized redirect URI β†’ add: https://abc1181-leads.hf.space/api/auth/callback/google β†’ Create β†’ copy Client ID and Client Secret β†’ paste to HF as above.

4.2 Google Places API (New) β€” $200 free, needs billing

  1. Same Cloud project β†’ APIs & Services β†’ Enable APIs β†’ search Places API (New) β†’ Enable
  2. Credentials β†’ Create Credentials β†’ API key β†’ Restrict β†’ API restrictions β†’ Places API (New) only β†’ Save β†’ copy to PLACES_API_KEY.
  3. Enable billing (Billing β†’ Link account) to get the $200 credit β€” you won't be charged inside free. Our use β‰ˆ $5-10 (lib/sources/places.ts:50 caps to 60 + Details only for no-website). Quota bar turns amber at 80% and degrades to partial.

4.3 Free India maps (no billing) β€” Mappls + Ola

  • Mappls: https://www.mapmyindia.com/api β†’ Sign up β†’ Dashboard β†’ Create project β†’ If you have a Static/REST key (your case), set MAPPLS_API_KEY; if you have OAuth pair, set MAPPLS_CLIENT_ID + MAPPLS_CLIENT_SECRET β€” either works. Free eval, no card.
  • Ola Maps: https://maps.olakrutrim.com β†’ Sign up (Krutrim Cloud) β†’ Credentials β†’ API Key β†’ OLA_API_KEY. 100k/API/mo free from 2026-09-01. GET https://api.olamaps.io/places/v1/nearbysearch?location=lat,lng&radius=&keyword= header X-API-KEY.

4.4 Other free maps (optional)

  • Foursquare: foursquare.com/developers β†’ My Apps β†’ Create App β†’ API Key β†’ FOURSQUARE_API_KEY (500 free).
  • HERE: developer.here.com β†’ Project β†’ API Key β†’ HERE_API_KEY (needs card, pay-as-you-grow).
  • OSM Overpass: No key. Always on at https://overpass-api.de/api/interpreter.

Full per-provider table: docs/maps-providers.md.

4.5 Enrich (emails, optional)

  • Hunter: hunter.io β†’ API key (25 free) β†’ ENRICH_API_KEY with ENRICH_PROVIDER=hunter
  • Apollo: app.apollo.io β†’ API key (50 free) β†’ ENRICH_PROVIDER=apollo

4.6 LLM (AI drafts, optional)

Any OpenAI-compatible gateway. Set LLM_BASE_URL (e.g. https://api.mistral.ai/v1), LLM_API_KEY, LLM_MODEL=mistral-large-latest. Llama banned on any provider (lib/ai/llm.ts:44 β€” AUP). Prompts are PII-free (lib/ai/prompts.ts:8).

4.7 Email digest (optional)

  • Gmail: App Password β†’ SMTP_HOST=smtp.gmail.com, SMTP_PORT=587, SMTP_USER, SMTP_PASS, DIGEST_TO=you@gmail.com
  • Resend: resend.com β†’ API key β†’ RESEND_API_KEY (100/d free)

5) Run locally (optional)

cp .env.example .env.local   # fill with your keys; use absolute DATABASE_URL
# MUST be absolute locally (Prisma CLI vs app resolve differently):
# DATABASE_URL="file:/abs/path/to/leads-app/data/leads.db"
npm install --registry https://registry.npmjs.org/
npx prisma migrate dev       # creates data/leads.db
npm run dev                  # http://localhost:7860
npm test                     # 59 unit (lib 80% lines)
# integration (mock): INTEGRATION=1 MOCK_SOURCES=1 DATABASE_URL="file:$PWD/data/test.db" npx vitest run

6) How to use the app (morning loop)

  1. Searches β†’ New search β†’ pick template (Health/Beauty, Food, B2B/Factory, MidMarket/Upgrade, Generic) β†’ city + radius (geocoded & cached, lib/geo.ts:4) β†’ keywords β†’ Cap 20/50/100/200 β†’ Create. Star it for nightly.
  2. Run search β†’ progress header (per-provider ms/quota) β†’ tabs Hot/Warm/Cold (lib/score.ts:65 threshold) β†’ table (filter by status/source/email/band/phone, sort score/rating) β†’ drawer (AI draft violet, Copy/Regenerate, notes, blocklist).
  3. Verify all (concurrency 5, skips fresh <7d unless forced) → Push to Sheets (master LeadGen Master, tab per search, 21 cols, idempotent on email→phone→company|location via lib/sheets.ts:rowKey) → CSV fallback per run.
  4. Hot queue (/hot) is the morning inbox β€” j/k move, q qualify, c copy icebreaker, ? help.
  5. Dashboard shows Hot/Warm/Cold donut, per-source yield, category intel (Where the buyers are), quotas ($0), recent runs. Bell shows unread Hot + quota warnings.
  6. Settings β†’ Quotas, Keys presence (masked), Scoring weights + Re-score, Templates, Sheets connect/disconnect (OAuth sealed lib/crypto.ts), Blocklist (undo), Danger (purge caches).

Nightly: GitHub Actions 30 20 * * * UTC (02:00 IST) pings /api/health 5Γ— then POST /api/cron/nightly with CRON_SECRET (jobs/runner.ts:38 sequential, roles rolled if >25min). Digest top-10 Hot to DIGEST_TO (self only) + in-app bell.


7) Troubleshooting

  • https://abc1181-leads.hf.space/api/health β†’ ok:true, db:ok, persistence:on means good. persistence:off = no bucket at /data β€” still runs on /tmp but data resets on restart (banner shows).
  • Sign-in 500 β†’ GOOGLE_* or APP_ALLOW_EMAIL wrong, or redirect URI not set to https://abc1181-leads.hf.space/api/auth/callback/google.
  • Search returns 0 / partial β†’ check quota bars in Settings; with no keys, OSM/Ola still work if those keys are set.
  • Chrome "Deceptive site" β†’ fixed in c029112 by making /, /privacy, /terms public (no auto-Google redirect). If still cached, request review at https://transparencyreport.google.com/safe-browsing/search?url=https://abc1181-leads.hf.space

8) Branding & cost

  • Branding: Made by AJ Β· personal tool (sidebar/footer/landing, components/app-shell.tsx:39). No Vercel triangle.
  • Cost: $0 target (docs/runbook.md). Quota bars prove it. 80% banners + auto-degrade, never spend.

Questions? See PRD.md/TRD.md checkboxes (210 ticked, 52 intentionally unticked for live/V1.1/V2/parked).