Ambassador / Creator Partner Program (CPP) discovery and monitoring bot.
Watches a curated list of ambassador-style X accounts. When they post about a project, researches whether the project has an active paying program (Ambassador / CPP / Creator / Partner / Yap-to-earn). If yes, alerts via Telegram with the program link.
+-------------------+
watchlist X polling -------->| tweets table |
+---------+---------+
|
v Gemini Flash: "promo?"
+-------------------+
| mentions table |--> existing project? repeat mention, skip enrichment
+---------+---------+
|
v (new project only)
+-------------------+
| enricher |
| - crawl bio/site |
| - search docs |
| - classify pages |
+---------+---------+
|
active program found? |
yes -> programs table | no -> tracked_no_program (recheck weekly)
|
v
+-------------------+
| project self- |
| monitor (X + |
| program pages) |
+---------+---------+
|
v
+-------------------+
| Telegram alert |
+-------------------+
new— first seen, awaiting enrichmentenriching— enrichment job in flighttracked_with_program— has at least one active program; self-monitor poll runstracked_no_program— researched, none found; rechecked weeklydead— no activity 30d+
Two layers make us early instead of reactive:
- Discovery nets (Layer 4, proactive): X keyword search for program-launch phrasing + funding-announcement search, so we catch the launch tweet directly rather than waiting for the watchlist reshare wave. (Quest platforms are deliberately skipped — too noisy / low pay; the reward-per-person filter handles low-value programs instead.)
- Legitimacy scoring (0–100): followers, account age, real docs, CoinGecko
listing, and known funding. Alerts fire above
MIN_QUALITY_SCOREand the score is shown so you judge borderline cases. Quality over quantity.
Anyone can DM the bot /start to subscribe — alerts broadcast to all active
subscribers (no per-user config). Commands: /start, /airdrops,
/noairdrops, /status, /stop. Subscribers who block the bot are auto-deactivated.
| Category | Who gets it | Meaning |
|---|---|---|
ambassador / creator / partner |
all subscribers | formal paid program |
early_stage |
all subscribers | quality funded project, no program yet — get on their radar |
airdrop / points / yap |
only /airdrops opt-ins |
farming audience |
TELEGRAM_CHAT_ID is now optional — if set, that admin chat always receives every
alert. Low-pay programs are dropped via MIN_REWARD_PER_PERSON_USD (programs with
an unknown reward are still surfaced — we can't tell, so we let you decide).
- X data (
X_READER):burner= free Playwright login with multi-account rotation;readapi= paid read-only API (twitterapi.io/Apify) with no suspension risk. Flip with one env var, no code change. - Program verdict (
PROGRAM_VERDICT_PROVIDER):gemini(free) for everything, orclaude(paid) for just the final high-stakes "is this a real program?" call.
| Concern | Service | Limit |
|---|---|---|
| X data | Playwright burner(s) or read API | rotate burners when banned |
| LLM | Gemini 2.0 Flash | 15 RPM / 1M tok/day |
| Program verdict (opt) | Claude Haiku | paid, cached |
| Search | Google CSE | 100/day |
| Search fallback | Brave | ~67/day |
| Legitimacy | CoinGecko search | free, unkeyed |
| Funding feed | DefiLlama dashboard scrape (free, via Playwright) + X funding-search net; DefiLlama Pro key optional | |
| Telegram | Bot API | unlimited |
| DB / queue | Postgres + pg-boss | local |
cp .env.example .env
# Fill in: GEMINI_API_KEY, GOOGLE_CSE_API_KEY+CX, BRAVE_SEARCH_API_KEY,
# TELEGRAM_BOT_TOKEN+CHAT_ID, X_USERNAME+PASSWORD
docker compose build
docker compose up -d postgres
docker compose run --rm app npm run migrate
docker compose up -d
docker compose logs -f appSeed the watchlist:
docker compose exec postgres psql -U cpp -d cpp_hunter -c \
"INSERT INTO watchlist_accounts (handle) VALUES ('trekdefi'), ('0xpuah') ON CONFLICT DO NOTHING;"- ✅ Scaffold + schema
- ✅ Playwright X client — login + fetch latest tweets
- ✅ Gemini classifier — promo detection
- ✅ Enricher — site crawl + search + program detection
- ✅ Telegram alerting (multi-channel by category)
- ✅ Discovery nets (Layer 4 — X keyword + funding search) + legitimacy scoring
- Project self-monitoring (Layer 3 — still stubbed in
project-monitor.ts)
npm run telegram:test # validates bot token + sends a test message
npm run discover:test yellow ethereum # funding feed + CoinGecko legitimacy
npm run x:test # burner login + a sample fetch (needs X creds)- Port
5434for Postgres on the host (avoids mevu's 5432). - X session is persisted to a named docker volume so login survives restarts.
- All search results are cached in
search_cacheto preserve the 100/day Google quota.