A simple, stateless system to fetch RSS articles, generate AI-powered digests, and deliver them via email. No database, no complexity—just RSS feeds, an LLM, and your inbox.
- Stateless & Simple: No database, no state tracking, no complex setup
- AI-Powered Digests: Uses any OpenAI-compatible LLM API (OpenAI, DeepSeek, OpenRouter, etc.)
- Email Delivery: Clean HTML digests sent via Gmail SMTP (Google Workspace)
- Flexible Scheduling: Run locally, via cron, or GitHub Actions
- Cost-Effective: ~$0.007/month with Gemini Flash or DeepSeek (~1 cent!)
- Easy to Customize: Simple config files for feeds and prompts
RSS Feeds → Fetch Articles → LLM Analysis → Email Digest
- Fetch: Pull articles from configured RSS feeds (default: last 7 days)
- Analyze: Send all articles to LLM in a single API call to generate digest
- Send: Email the HTML digest via Gmail SMTP
- Clone the repo
git clone git@github.com:DataFrosch/rss-digest.git- Add your favorite RSS feeds in
config/feeds.py. - Set your LLM API key (DeepSeek, OpenAI, or OpenRouter).
- Tweak the prompt to match your interests.
- Set up GitHub Actions to automate your weekly digest.
# 1. Install uv (Python package manager) if you don't have it
curl -LsSf https://astral.sh/uv/install.sh | sh
# 2. Clone and setup
git clone git@github.com:DataFrosch/rss-digest.git
cd rss-digest
uv sync
# 3. Configure environment
cp .env.example .env
# Edit .env with your API keys (see Setup section)
# 4. Run
uv run python src/main.pyLLM Provider - Choose one:
- OpenAI: platform.openai.com → API Keys → Leave
OPENAI_BASE_URLempty - DeepSeek (recommended): platform.deepseek.com → Set
OPENAI_BASE_URL=https://api.deepseek.com - OpenRouter: openrouter.ai/keys → Set
OPENAI_BASE_URL=https://openrouter.ai/api/v1
Google Workspace / Gmail (Email):
- Enable 2-Factor Authentication on your Google Account: myaccount.google.com/security
- Generate an App Password: myaccount.google.com/apppasswords
- Select app: "Mail"
- Select device: "Other (Custom name)" - enter "RSS Digest"
- Click "Generate" and copy the 16-character password
cp .env.example .env
# Edit .env with your keys - see .env.example for provider-specific examplesEdit config/feeds.py to add your RSS feeds:
RSS_FEEDS = {
"Tech News": "https://example.com/feed.xml",
"Your Blog": "https://yourblog.com/rss",
}You can also customize the LLM prompt in the same file.
# Full digest
uv run python src/main.py
# Options:
# --test Process only 5 articles
# --dry-run Generate but don't send email
# --days N Look back N days (default: 7)
# --verbose Detailed logging
# --no-save Don't save HTML file locallyGitHub Actions: Settings → Secrets → Add: OPENAI_API_KEY, OPENAI_BASE_URL (if needed), LLM_MODEL, SMTP_PASSWORD, FROM_EMAIL, RECIPIENT_EMAIL
Cron: 0 9 * * 1 cd /path/to/rss-digest && uv run python src/main.py
- RSS Feeds: Edit
config/feeds.py - LLM Prompt: Edit
DIGEST_GENERATION_PROMPTinconfig/feeds.py - LLM Model: Change
LLM_MODELin.env(see.env.examplefor options) - Email Template: Edit
templates/email_template.html
rss-digest/
├── src/
│ ├── main.py # Main orchestration
│ ├── rss_fetcher.py # RSS feed fetching
│ ├── llm_processor.py # LLM digest generation
│ └── email_sender.py # Email sending
├── config/
│ └── feeds.py # Feed URLs & prompts
├── templates/
│ └── email_template.html
├── .github/workflows/
│ └── weekly_digest.yml # GitHub Actions
├── .env.example # Environment template
└── pyproject.toml # Dependencies
- DeepSeek: ~$0.007/month (less than 1 cent!)
- OpenRouter (Gemini): ~$0.007/month
- OpenAI (GPT-4o-mini): ~$0.05/month
- Gmail SMTP: Free (included with Google Workspace or personal Gmail)
- No articles: Try
--days 14 --verbose - Email fails: Verify Gmail App Password is correct, ensure 2FA is enabled, check
digest.log - LLM errors: Verify API key, check
OPENAI_BASE_URL, check credits
Issues and PRs welcome!
MIT
