Automated battery industry newsletter service β curates news from global sources, generates AI summaries, and delivers personalized daily/weekly emails.
Battery Scout is a full-stack newsletter platform that:
- Scrapes battery industry news from Google News across 8+ languages
- Summarizes articles using Google Gemini AI
- Categorizes content into 6 industry-relevant topics
- Personalizes newsletters based on subscriber preferences
- Delivers daily/weekly emails via automated GitHub Actions
βββββββββββββββββββ
β React Frontend β β User signup/unsubscribe
β (Vite + TS) β
ββββββββββ¬βββββββββ
β REST API
β
βββββββββββββββββββ
β FastAPI Backendβ β Subscription management
β (Python 3.11) β
ββββββββββ¬βββββββββ
β
β
βββββββββββββββββββ
β Supabase β β Database (subscribers, articles)
β (PostgreSQL) β
βββββββββββββββββββ
GitHub Actions (daily cron)
β
1. scrape_news.py β Fetch & summarize articles
2. send_email.py β Send personalized emails
- Python 3.11+
- Node.js 18+
- Supabase account (for database)
- Google Gemini API key (for AI summaries)
- Gmail account (for sending emails)
cd backend
# Install dependencies
pip install -r requirements.txt
# Set environment variables (create .env file)
export SUPABASE_URL=your_supabase_url
export SUPABASE_SERVICE_KEY=your_service_key
export GEMINI_API_KEY=your_gemini_key
export GMAIL_USER=your_email@gmail.com
export GMAIL_APP_PASSWORD=your_app_password
export UNSUBSCRIBE_SALT=random_secret_string
# Run the API server
python main.py
# Server runs on http://localhost:8000cd frontend
# Install dependencies
npm install
# Set environment variables (create .env file)
echo "VITE_API_URL=http://localhost:8000" > .env
# Start dev server
npm run dev
# App runs on http://localhost:8080Battery Scout/
βββ backend/
β βββ main.py # FastAPI server & API endpoints
β βββ scrape_news.py # News scraping & AI summarization
β βββ send_email.py # Email delivery service
β βββ supabase_client.py # Database operations
β βββ utils.py # Validation & helpers
β βββ email_template.py # HTML email templates
β βββ requirements.txt
β
βββ frontend/
β βββ src/
β β βββ components/ # React components
β β βββ pages/ # Route pages
β β βββ lib/
β β β βββ api.ts # Backend API client
β β βββ integrations/ # Supabase client (legacy)
β βββ package.json
β βββ vite.config.ts
β
βββ .github/
β βββ workflows/
β βββ daily_email.yml # Automated daily newsletter
β
βββ README.md
| Variable | Description | Required |
|---|---|---|
SUPABASE_URL |
Your Supabase project URL | β |
SUPABASE_SERVICE_KEY |
Supabase service role key | β |
GEMINI_API_KEY |
Google Gemini API key | β |
GMAIL_USER |
Gmail address for sending | β |
GMAIL_APP_PASSWORD |
Gmail app password | β |
UNSUBSCRIBE_SALT |
Secret for token generation | β |
FRONTEND_URL |
Production frontend URL | Optional |
PORT |
Server port (default: 8000) | Optional |
| Variable | Description |
|---|---|
VITE_API_URL |
Backend API URL (e.g., http://localhost:8000) |
GET /β Health checkGET /api/topicsβ Get available categoriesGET /api/contentβ Get sample articlesGET /api/statsβ Get subscriber statisticsPOST /api/signupβ Subscribe to newsletterPOST /api/unsubscribe/verifyβ Verify unsubscribe tokenPOST /api/unsubscribe/confirmβ Confirm unsubscribe
See full API docs at http://localhost:8000/docs (Swagger UI)
The newsletter runs automatically via GitHub Actions:
- Daily at 14:00 UTC (9am EST / 6am PST)
- Scrapes news from past 24 hours
- Generates AI summaries
- Sends personalized emails
Manual trigger: Go to Actions tab β Daily Newsletter β Run workflow
- Companies & Deals β Partnerships, acquisitions, factory openings
- Policy & Regulation β Tariffs, subsidies, government regulations
- Supply Chain β Lithium, cobalt, nickel mining and pricing
- Lithium-ion & Solid-state β Battery tech breakthroughs
- Sodium-ion & Alternatives β Next-gen battery chemistries
- Recycling & Second-life β Circular economy, reuse, recycling
- North America (US, Canada)
- Europe (Germany, France, UK, Sweden, etc.)
- Asia (China, Japan, South Korea, India)
- Global (all regions)
News is scraped in 8 languages: English, Chinese, German, Japanese, Korean, Hungarian, Swedish, French, Spanish
# Set all environment variables in your platform
# Deploy from backend/ directory# Set VITE_API_URL to your backend URL
# Deploy from frontend/ directory
vercel --prodRun the migration in frontend/supabase/migrations/ to set up tables.
# Frontend tests
cd frontend
npm test
# Backend (manual testing)
cd backend
python scrape_news.py # Test scraping
python send_email.py # Test email sending- Backend changes: Edit Python files, restart server
- Frontend changes: Hot reload via Vite
- Database schema: Update Supabase migrations
- New categories: Update
NEW_CATEGORIESinsupabase_client.py
- Never commit
.envfiles - Use service role key for backend (not anon key)
- Rotate
UNSUBSCRIBE_SALTif exposed - Use Gmail app passwords (not account password)
Frontend can't reach backend
- Check
VITE_API_URLis set correctly - Verify backend CORS allows frontend domain
No articles scraped
- Check Gemini API quota/limits
- Verify Google News RSS is accessible
Emails not sending
- Verify Gmail app password is correct
- Check Gmail "Less secure app access" settings
MIT License - see LICENSE file for details
This is a personal project, but suggestions are welcome! Open an issue to discuss changes.
For questions about the newsletter: [Your Contact Info]
Built with β€οΈ for battery industry professionals