Pluggable Trend Signal → Personalized Digest Engine
Transform GitHub Trending (extensible to Product Hunt, Reddit, etc.) into personalized recommendations, delivered via multiple channels (email, WeChat, etc.).
English | 简体中文
🎯 Personalized Ranking - Multi-dimensional scoring based on keywords, language preferences, and focus areas
🔌 Pluggable Architecture - Three-layer decoupling: Collector, Ranker, Notifier
📧 Multi-channel Delivery - Email (SMTP), WeChat (via WeClaw local bridge)
🚀 Zero Installation - npx github-trending-radar --demo
📊 JSON Output - Pipeline-friendly and automation-ready
🎨 Beautiful Templates - HTML emails + plain text WeChat messages
- Fetch daily trending projects from GitHub Trending
- Score and rank by personal profile (keywords, languages, directions)
- Generate recommendation reasons and actionable ideas (in Chinese by default)
- Deliver to your email or personal WeChat
- Support dry-run testing and JSON output
Most Trending digests are generic. This project is opinionated — it answers:
Which trending projects are worth my time for my current work?
Beyond popularity, it adds a practical relevance layer:
- ✅ Keyword match score
- ✅ Programming language preference
- ✅ Project direction hints
- ✅ Actionable ideas (how to apply it)
┌─────────────────────────────────────────────────────────┐
│ CLI / Task Layer │
└─────────────────────────────────────────────────────────┘
│
┌───────────────────┼───────────────────┐
│ │ │
▼ ▼ ▼
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ Collectors │───▶│ Rankers │───▶│ Notifiers │
└──────────────┘ └──────────────┘ └──────────────┘
│ │ │
├─ GitHub ├─ RuleBased ├─ Email (SMTP)
├─ Product Hunt ├─ LLM (future) ├─ WeChat (WeClaw)
└─ Reddit └─ Hybrid └─ Telegram (future)
Three-layer design:
- Collectors - Data source abstraction (current: GitHub, future: Product Hunt, Reddit)
- Rankers - Ranking strategy (current: RuleBased, future: LLM / Hybrid)
- Notifiers - Notification channels (current: Email, WeChat, future: Telegram)
Experience the product value in 30 seconds, no configuration needed:
npx github-trending-radar --demo
# Or use short alias
npx gtr --demoDemo Mode Features:
- ✅ Uses preset [AI Product Builder] profile
- ✅ Shows only Top 3 highly relevant projects (focused)
- ✅ Beautiful terminal output (colors + symbols)
- ✅ Auto-guide to configuration
Use your config but don't send emails:
# Dry run (no emails sent)
npx github-trending-radar --dry-run
# Or use short alias
npx gtr --dry-run# Send email (requires SMTP env vars)
npx github-trending-radar --to=your@email.com- Node.js 18+ recommended
pnpmpackage manager- SMTP account for email delivery
Complete setup in 3 minutes:
pnpm install
npx tsx scripts/send-trending-digest.ts initInteractive flow:
- Choose developer type (AI Product, Full-stack, DevOps, Indie Hacker, Data Engineer)
- Choose notification channels (Email, WeChat)
- Configure email (auto-detect QQ/Gmail/163/126)
- Test run
Auto-generates .env.local, no manual editing needed.
pnpm install
cp .env.example .env.localThen edit .env.local with your settings.
# Choose notification channels (default: email)
# Options: email, wechat
# Multiple channels: email,wechat
NOTIFIER_CHANNELS=emailSMTP_USER=your@qq.com
SMTP_PASSWORD=your_smtp_authorization_code
MAIL_FROM=your@qq.com
TRENDING_EMAIL_TO=your@gmail.comAuto SMTP detection:
- Explicit SMTP config → Use these
@qq.com→ Auto-use QQ Mail (smtp.qq.com:465)@gmail.com→ Auto-use Gmail (smtp.gmail.com:465)@163.com→ Auto-use 163 Mail (smtp.163.com:465)@126.com→ Auto-use 126 Mail (smtp.126.com:465)
Full SMTP variables:
SMTP_HOST= # SMTP server address (optional)
SMTP_PORT= # SMTP port (default 465)
SMTP_SECURE= # Use SSL (default true)
SMTP_USER= # Username (required)
SMTP_PASSWORD= # Password or auth code (required)
MAIL_FROM= # Sender (default: same as SMTP_USER)
TRENDING_EMAIL_TO= # Recipient (optional, default: same as SMTP_USER)WECLAW_API_URL=http://127.0.0.1:18011
WECHAT_TO=filehelper@im.wechatSetup:
- Start WeClaw local bridge:
weclaw start(WeClaw) - Scan QR code to login WeChat
- Default HTTP API listens on
127.0.0.1:18011 - Set
WECHAT_TOto recipient, e.g.,filehelper@im.wechat
TRENDING_PROFILE_NOTE= # Override default profile description
TRENDING_PROFILE_KEYWORDS= # Append keywords (comma-separated)
TRENDING_REPO_LIMIT=10 # Repos to scan
TRENDING_RECOMMENDATION_LIMIT=5 # Repos to recommendEmail only:
NOTIFIER_CHANNELS=email
SMTP_USER=your@qq.com
SMTP_PASSWORD=your_authorization_code
TRENDING_EMAIL_TO=your@gmail.comWeChat only:
NOTIFIER_CHANNELS=wechat
WECLAW_API_URL=http://127.0.0.1:18011
WECHAT_TO=filehelper@im.wechatEmail + WeChat:
NOTIFIER_CHANNELS=email,wechat
SMTP_USER=your@qq.com
SMTP_PASSWORD=your_authorization_code
TRENDING_EMAIL_TO=your@gmail.com
WECLAW_API_URL=http://127.0.0.1:18011
WECHAT_TO=filehelper@im.wechatZero installation:
# View help
npx github-trending-radar --help
# Demo mode (zero config - recommended for first use)
npx gtr --demo
# Dry run (no emails, view output)
npx github-trending-radar --dry-run
# Send notifications
npx github-trending-radar --to=your@email.com
# Send to WeChat
npx github-trending-radar --wechat-to=filehelper@im.wechat
# Use short alias
npx gtr --dry-run
# Custom parameters
npx gtr --dry-run --repo-limit=15 --recommendation-limit=5
# JSON output (pipeline-friendly)
npx gtr --dry-run --format=jsonAvailable parameters:
--demo- Demo mode: zero config, uses preset AI Product Builder profile--dry-run- Test mode, no emails sent--to=EMAIL- Recipient email (legacy, same as--email-to)--email-to=EMAIL- Recipient email (overrides env var)--wechat-to=ID- WeChat recipient ID (e.g.,filehelper@im.wechat)--repo-limit=N- Repos to scan (default 10)--recommendation-limit=N- Repos to recommend (default 5)--format=text|json- Output format (default text)
Subcommands:
# Interactive setup wizard
npx gtr init
# View help
npx gtr --help
npx gtr init --helpLocal dry run:
pnpm digest:dry-runSend digest email:
pnpm digest:sendOverride recipient:
pnpm digest:send -- --to=you@example.comControl scan and recommendation counts:
pnpm digest:dry-run -- --repo-limit=15 --recommendation-limit=5The digest contains:
- A short summary for the day
- Your current profile summary
- Focus areas
- Top recommended repositories
- Reasons each repo is relevant
- Practical ideas for how to apply it
Emails are generated in both HTML and plain text.
Choose when running npx gtr init:
- AI Product Builder - AI tools, Agent workflows, Automation
- Full-stack Engineer - Next.js, React, API design, Full-stack
- DevOps/Cloud Native - Docker, K8s, CI/CD, Cloud infrastructure
- Indie Hacker - SaaS tools, MVPs, Growth, Monetization
- Data Engineer - ETL, Data pipelines, Analytics, ML engineering
Adjust the digest without changing code:
TRENDING_PROFILE_NOTEoverrides the profile summary shown in emailsTRENDING_PROFILE_KEYWORDSappends extra matching keywords (comma-separated)
Default profile (if not using init):
- AI tools
- Agent workflows
- Automation pipelines
- Content systems
- Growth tooling
- Productized scripts
Type-check the project:
pnpm typecheckRecommended local validation:
pnpm typecheck
pnpm digest:dry-runThe project includes .github/workflows/digest-email.yml workflow, running daily at 01:00 UTC (09:00 Beijing time).
Setup steps:
- Add to GitHub repo Settings → Secrets:
SMTP_USER
SMTP_PASSWORD
MAIL_FROM
TRENDING_EMAIL_TO
- (Optional) If using WeChat, add:
WECLAW_API_URL
WECHAT_TO
- (Optional) Add personalization to Variables:
NOTIFIER_CHANNELS=email,wechat
TRENDING_PROFILE_NOTE=
TRENDING_PROFILE_KEYWORDS=
TRENDING_REPO_LIMIT=10
TRENDING_RECOMMENDATION_LIMIT=5
Manual trigger: Use workflow_dispatch on GitHub Actions page.
If sending to personal WeChat via local weclaw, use local scheduler instead of GitHub Actions.
Options:
launchdcrontab- Any tool that can schedule
pnpm digest:send
First-time setup:
weclaw login
weclaw start
pnpm digest:send -- --wechat-to=filehelper@im.wechatSee src/collectors/README.md, steps:
- Create new Collector (e.g.,
producthunt.ts) - Implement
Collector<TrendingItem>interface - Export in
src/collectors/index.ts
Example:
// src/collectors/producthunt.ts
import type { Collector, TrendingItem } from './types.js';
export class ProductHuntCollector implements Collector {
readonly name = 'producthunt';
async fetch(limit: number): Promise<TrendingItem[]> {
// Implement Product Hunt API fetching
return items;
}
}See src/rankers/README.md, steps:
- Create new Ranker (e.g.,
llm.ts) - Implement
Rankerinterface - Wire up in task layer factory function
Example:
// src/rankers/llm.ts
import type { TrendingRanker } from './types.js';
export class LlmRanker implements TrendingRanker {
readonly name = 'llm';
rank(repositories, profile, limit) {
return repositories.slice(0, limit).map((repo) => ({
repo,
score: 0,
reasons: [],
practiceIdeas: []
}));
}
}- Create new Notifier (e.g.,
telegram.ts) - Implement
Notifierinterface - Register in
src/tasks/github-trending-digest.tsfactory function
Example:
// src/notifiers/telegram.ts
import type { Notifier, NotifyOptions, NotifyResult } from './types.js';
export class TelegramNotifier implements Notifier {
readonly name = 'telegram';
async notify(options: NotifyOptions): Promise<NotifyResult> {
// Implement Telegram Bot API call
return { success: true, skipped: false };
}
}src/
├── collectors/ # Data source abstraction layer
│ ├── types.ts # Collector interface
│ ├── github.ts # GitHub Trending implementation
│ └── README.md # Extension guide
├── rankers/ # Ranking strategy layer
│ ├── types.ts # Ranker interface
│ ├── rule-based.ts # Rule-based scoring
│ └── README.md # Extension guide
├── notifiers/ # Notification channel layer
│ ├── types.ts # Notifier interface
│ ├── email.ts # Email notification
│ ├── wechat.ts # WeChat (WeClaw)
│ └── index.ts # Unified exports
├── profiles/ # Profile templates
├── trending/ # Profile and type definitions
├── reports/ # Ranking and digest generation
├── tasks/ # End-to-end task orchestration
└── config/ # Environment variable validation
scripts/ # CLI entry points
bin/ # npx executables
GitHub Actions (Recommended):
- Free, stable, zero maintenance
- Secrets encrypted storage
- Daily auto-execution
Local cron:
- Good for debugging or personal use
- Requires machine uptime
- Logs stored locally
Recommendation: Use cron for development, GitHub Actions for production.
Email only:
- Deep reading
- Complete HTML formatting
- Archivable and searchable
WeChat only:
- Instant notification
- Mobile-friendly
- Group collaboration
Email + WeChat:
- Email for detailed reading
- WeChat for quick reminders
- Good for team collaboration
Default profile targets AI products, Agent workflows, and automation.
Customization methods:
-
Append keywords (recommended):
TRENDING_PROFILE_KEYWORDS=langchain,openai,nextjs
-
Override profile description:
TRENDING_PROFILE_NOTE=I am a developer focused on XXX
-
Modify code (advanced): Edit
src/trending/profile.ts
See CONTRIBUTING.md.