Generate a markdown digest from an OPML feed list. No API keys required. Uses only Python stdlib.
ScriptPurposeInputOutputscripts/parse_opml.pyParse OPML → feed listOPML file pathJSON array (stdout)scripts/fetch_feeds.pyFetch feeds → articlesJSON feed list (stdin or --feeds)JSON array (stdout)scripts/build_digest.pyArticles → markdownJSON articles (stdin)Markdown (stdout or --output)
Reference OPML: references/opml-example.opml
All scripts write progress/errors to stderr, data to stdout — safe to pipe.
Make scripts executable once:
bash
chmod +x ~/.openclaw/workspace/skills/rss-digest/scripts/*.py
Set a variable for convenience:
bash
SKILL=~/.openclaw/workspace/skills/rss-digest
Run the full pipeline:
bash
python3 $SKILL/scripts/parse_opml.py ~/feeds.opml \
| python3 $SKILL/scripts/fetch_feeds.py --hours 24 \
| python3 $SKILL/scripts/build_digest.py --period Daily --output ~/digest.md
Open ~/digest.md in Obsidian or cat to terminal.
bash
python3 $SKILL/scripts/parse_opml.py ~/feeds.opml \
| python3 $SKILL/scripts/fetch_feeds.py --hours 168 \
| python3 $SKILL/scripts/build_digest.py --period Weekly --group-by category --output ~/weekly-digest.md
Only include articles matching specific topics:
bash
python3 $SKILL/scripts/parse_opml.py ~/feeds.opml \
| python3 $SKILL/scripts/fetch_feeds.py --hours 24 --keywords "AI,machine learning,LLM" \
| python3 $SKILL/scripts/build_digest.py --title "AI Digest"
--keywords is comma-separated, case-insensitive. Matches title or summary.
Add to crontab ( crontab -e) for a daily digest at 7 AM ET:
cron
0 7 * * * python3 /Users/openclaw/.openclaw/workspace/skills/rss-digest/scripts/parse_opml.py ~/feeds.opml | python3 /Users/openclaw/.openclaw/workspace/skills/rss-digest/scripts/fetch_feeds.py --hours 24 | python3 /Users/openclaw/.openclaw/workspace/skills/rss-digest/scripts/build_digest.py --period Daily --output /Users/openclaw/.openclaw/workspace/vault/daily-recap/rss-$(date +\%Y-\%m-\%d).md
Weekly digest every Monday at 8 AM:
cron
0 8 * * 1 python3 /Users/openclaw/.openclaw/workspace/skills/rss-digest/scripts/parse_opml.py ~/feeds.opml | python3 /Users/openclaw/.openclaw/workspace/skills/rss-digest/scripts/fetch_feeds.py --hours 168 | python3 /Users/openclaw/.openclaw/workspace/skills/rss-digest/scripts/build_digest.py --period Weekly --group-by category --output /Users/openclaw/.openclaw/workspace/vault/daily-recap/rss-weekly-$(date +\%Y-\%m-\%d).md
FlagDefaultDescription--hours N24Articles from last N hours--keywords K(none)Comma-separated filter keywords--feeds FILEstdinJSON feed list file (alternative to piping)--timeout N10HTTP timeout per feed in seconds
FlagDefaultDescription--title STR"RSS Digest"Digest heading title--period STR"Daily"Period label (Daily / Weekly)--output FILEstdoutWrite to file instead of stdout--group-by STR"feed"Group by: feed, category, or none``--max-summary N300Max chars of article summary (0 = omit)--date STRtodayOverride the date label
Export your OPML from any RSS reader (Feedly, NetNewsWire, Reeder, Inoreader, etc.) via their export settings. See references/opml-example.opml for the expected format. Feeds can be flat or nested inside category folders.
The digest is clean markdown with:
Suitable for pasting into Discord (plain markdown), saving to Obsidian, or emailing.