Automated, prompt-driven news generation and publishing pipeline for WordPress.
This project ingests topics and sources from an Excel workbook, gathers fresh inputs via RSS, Google News (SerpAPI), and Telegram channels, then uses the OpenAI API to draft articles, summarize them, and publish to a WordPress site — all on an adjustable weekly schedule.
- Topic- & schedule-driven: Uses
blog_config.xlsxto decide what to post and when (per weekday). - Multi-source research:
- RSS via
feedparser - Google News via SerpAPI
- Telegram via
Telethon
- RSS via
- Content generation with OpenAI (configurable prompts, style, and sentiment).
- Post-processing: auto title, summary, and tags generation.
- WordPress publishing (REST API), including optional featured image upload.
- SQLite persistence, duplicate protection, and simple history retrieval to avoid repetition.
- Structured logging to
logs/operations.log.
good-news/
├─ main.py # Orchestrates daily run: read schedule → gather sources → generate → post
├─ blog_config.xlsx # Scheduler (weekly) + source registry + blocked domains
├─ articles.db # SQLite database (created automatically if missing)
├─ prompts/
│ ├─ prompter.py # Builds the news/history prompts from research + past posts
│ ├─ writer.py # OpenAI calls for article writing and summarization
│ ├─ writer_system_prompt.txt
│ ├─ writer_template.txt
│ ├─ article_template.txt
│ ├─ past_article_template.txt
│ └─ logged_prompts/ # Saved, filled prompts for traceability
├─ utils/
│ ├─ scraper.py # RSS + SerpAPI + generic page parse + (optional) News site parsing
│ ├─ telegram_scraper.py # Telegram channel fetch via Telethon
│ ├─ db_utils.py # Insert/fetch utilities around SQLite (posted_articles etc.)
│ ├─ poster.py # WordPress REST API helpers (media upload, post create)
│ └─ logger.py # Shared logger setup → logs/operations.log
├─ logs/
│ └─ operations.log
├─ requirements.txt
├─ .env_sample # Example environment variables
└─ .env # Your local secrets (not committed)
Note: The WordPress helper (
utils/poster.py) expects standard WP REST API credentials (see Configuration below).
┌──────────────────┐ ┌──────────────────────────┐
│ blog_config.xlsx│ │ blocked_domains sheet │
└─────────┬────────┘ └────────────┬─────────────┘
│ │
(weekday: topics) (filter source URLs)
│ │
▼ ▼
┌────────────┐ ┌───────────────────────────────┐
Sources ═══════> │ utils/* │ │ Research DB (in memory) │
(RSS/Serp/Tele) │ scraper.py │──────▶│ title, text, source, link... │
│ telegram_* │ └────────────────┬──────────────┘
└─────┬──────┘ │
│ │
▼ ▼
┌───────────────────┐ ┌─────────────────────────┐
│ prompts/prompter │ │ prompts/writer (OpenAI) │
│ build_*_prompt │────────▶│ write_article + summary │
└─────────┬─────────┘ └────────────┬────────────┘
│ │
▼ ▼
┌────────────┐ ┌──────────────┐
│ SQLite │◀─────────────────│ db_utils │
│ articles.db│ (dedupe, log) │ insert/fetch │
└─────┬──────┘ └──────┬───────┘
│ │
▼ ▼
┌────────────────┐ ┌────────────────┐
│ WordPress REST │◀──────────────│ utils/poster │
│ (publish) │ │ (media + post)│
└────────────────┘ └────────────────┘
- Python ≥ 3.9
- A WordPress site with REST API enabled and an Application Password
- OpenAI API key
- SerpAPI key (for Google News results)
- Optional: Telegram API credentials if using Telegram sources
Install dependencies:
python -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
pip install -r requirements.txtCopy .env_sample to .env and set values:
# OpenAI
OPENAI_API_KEY=sk-...
# Google News (SerpAPI)
SERPAPI_KEY=...
# WordPress REST (Application Password recommended)
WP_API_BASE=https://your-site.com/wp-json/wp/v2
WP_USERNAME=your-admin-user
WP_APP_PASSWORD=abcd abcd abcd abcd
# Telegram (optional, for telegram_scraper)
api_id=123456
api_hash=your_telegram_api_hashIf you use Basic Auth instead of Application Passwords, adapt
utils/poster.pyaccordingly.
Sheets:
weekly_scheduler— a simple week grid (Mon–Sun) with topic names in cells.main.pylooks at today’s column to decide which topic(s) to post.sources— registry of feeds and channels:desc_topic_primary,desc_topic_secondarydesc_channel(RSS,SERP,Telegram)desc_name,desc_payload(URL or channel handle)bool_visibility(enable/disable)score_quality(weighting)limit(per-run cap)
blocked_domains— domains to exclude (e.g.finance.yahoo.com,bloomberg.com).
Default run for “today’s” topics:
python main.pyThis will:
- Load the weekly schedule for the current weekday.
- Load matching sources (
bool_visibility == True). - Collect research:
- SERP (Google News via SerpAPI)
- RSS feeds
- Telegram channels (optional)
- Build news + history prompts.
- Call OpenAI to write the article, then summarize and tag it.
- Save to SQLite (
articles.db) and publish to WordPress.
Logs are written to logs/operations.log.
- Run components in isolation:
utils/scraper.py: testresearch(),scrapeRSS()with a smalllimit.prompts/prompter.py: verify token counts and history assembly.prompts/writer.py: dry-run writing with shorter max tokens / temperature for speed.utils/poster.py: publish to a draft post type first.
- Keep
blocked_domainsup to date to avoid paywalls/blocked content. - Start with a “staging” WordPress site and low posting frequency.
- Respect robots.txt and site terms.
- Avoid copying large portions of paywalled content; prefer summarization and fair use.
- Attribute sources in generated text where appropriate.
- Add rate limits/backoff when scaling scraping.
This project is provided as-is. By using it, you agree to operate at your own responsibility and risk.
- Copyright and fair use: Ensure that any generated or scraped content complies with local copyright laws and fair use policies.
- AI content policies: Always review generated content before publishing to make sure it aligns with your site's editorial standards and AI policies.
- Web scraping: Not all websites allow scraping. Check each site's terms of service and robots.txt before enabling sources.
- The authors and contributors assume no liability for misuse of this codebase.