Project Brief: Daily-5 News Digest
Status: MVP — Ready to Build Owner: You Tools: FreshRSS (self-hosted, admin-only), n8n, Google Sheets, Telegram, Obsidian, AI (Gemini/GPT) Related project: Video Summarizer (shares Telegram bot + Obsidian vault + security pattern)
1. Problem Statement
Existing RSS aggregation (FreshRSS) solves collection but not curation. Unread counts climb indefinitely, producing the same overwhelm this project exists to escape. The gap isn’t sources — it’s a missing forced-ranking layer that turns “everything” into “the 5 things worth your attention today,” scored against your own stated judgment, not a generic AI vibe-check.

2. Goal
One daily digest (Telegram + Obsidian note), containing exactly 5 items (title, source, link, one-line reason), drawn from all subscribed sources (YouTube, newsletters, blogs), scored using your manually-curated Google Sheet ratings as the primary signal. No backlog, no browsing, no second inbox to manage.
3. Non-Goals (MVP)
- No archive/log of rejected items
- No topic-relevance scoring beyond what’s captured in your sheet’s “Why” column
- No automated reconciliation of new channels/blogs found via exploration — that’s Phase 2 (Section 9)
- No manual FreshRSS browsing — it is admin-only, never a frontend
4. Design Principles
- FreshRSS is plumbing, not a product. It collects; it is never read directly.
- Your judgment is the primary scoring signal. The Google Sheet (H/M/L + Why) is a stronger prior than generic AI quality-scoring — the AI’s job is to apply your stated reasoning to today’s specific items, not invent taste from scratch.
- No memory of rejects. Items not in the top 5 are discarded permanently when marked read.
- Hard cap, always. Exactly 5 items daily, regardless of pool size or quality variance.
- One sheet, one source of truth. YouTube + blogs + newsletters all live in the same sheet structure (Channel/Source, Value H/M/L, Why, Status) so scoring logic doesn’t fork by content type.
5. Architecture — Workflow A: Daily Digest (MVP)
[Schedule Trigger] — once daily, e.g. 6am
↓
[Google Sheets node] — read subscriptions sheet (Channel, Value, Why, Status)
↓
[Code node] — build lookup table: {source_name → Value, Why}
↓
[HTTP Request] — pull unread items via FreshRSS API
↓
[Code node] — match each item to sheet lookup by source name; attach Value+Why as context; batch for AI
↓
[AI node] — score all items in one call, using Value+Why as primary signal + clickbait/depth as secondary
↓
[Code node] — parse AI JSON, sort by score, slice top 5
↓
[Telegram node] — send digest
↓
[Write File node] — write same digest as Obsidian note → `daily news digests/YYYY-MM-DD.md`
↓
[HTTP Request] — mark ALL originally-fetched items as read in FreshRSS
Node-by-Node Build Plan
| # | Node | Purpose | Notes |
|---|---|---|---|
| 1 | Schedule Trigger | Daily kickoff | 6am suggested; adjust to taste |
| 2 | Google Sheets (Read) | Pull subscription ratings | Use sheet URL directly; read all tabs if blogs/newsletters get a separate tab |
| 3 | Code | Build name→rating lookup | Normalize names (lowercase, trim) for matching robustness |
| 4 | HTTP Request | FreshRSS unread items | Google Reader–compatible API; auth via API password |
| 5 | Code | Match + batch | Fuzzy match acceptable for MVP; unmatched sources default to “Unrated” (still eligible, no bonus weight) |
| 6 | AI (Gemini/GPT) | Score + rank | Prompt in Section 7 |
| 7 | Code | Parse, sort, top 5 | Error branch if malformed JSON |
| 8 | Telegram | Send digest | Reuse existing bot/chat ID security pattern |
| 9 | Write File | Obsidian note | Same vault mount as video summarizer project |
| 10 | HTTP Request | Mark all read | Only runs on success — failures don’t silently lose items |
Error handling (minimum for MVP):
- FreshRSS unreachable → Telegram alert, skip mark-as-read
- Google Sheets unreachable → Telegram alert, skip run (don’t score blind)
- AI call fails/unparseable → Telegram alert, skip mark-as-read
6. Google Sheet — Required Structure
Your existing sheet (YouTube-only) needs to extend to cover all source types before Workflow A can use it universally:
| Column | Purpose |
|---|---|
| Source Name | Must reasonably match FreshRSS feed/channel title |
| Type | YouTube / Blog / Newsletter — helps you filter/sort manually later |
| Value (H/M/L) | Your rating |
| Why | Your reasoning — fed directly into AI prompt as context |
| Status | e.g. “Review,” “Keep,” “Drop” — your existing pattern |
Action for you: as you explore Substack, add new rows with Type = Blog, even before you’re sure — Status = “Review” or “Trial” until confirmed.
7. Scoring Prompt (starting draft)
“You will receive today’s content items (title, source, snippet), each tagged with the owner’s personal rating (H/M/L) and stated reasoning (‘Why’) for that source, where available. Score each item 0–100 for today’s digest.
Treat the owner’s Value+Why as the primary signal — e.g. a High-rated source with reasoning ‘deep technical analysis’ should score well if today’s item matches that description, and poorly if it’s an off-brand outlier (e.g. clickbait from a usually-good source). A Low-rated or unrated source can still score well if the specific item is unusually substantive.
Penalize generically: clickbait phrasing, vague superlatives, pure reaction/outrage content.
Return ONLY valid JSON: array of {id, score, reason}. Reason should reference the owner’s stated Why where relevant.”
(Expect 1-2 rounds of tuning once you see real output.)
8. Definition of Done (MVP)
- Google Sheet extended to cover blogs/newsletters (not just YouTube)
- Google Sheets node reads sheet successfully in n8n
- FreshRSS API tested via manual HTTP call
- Workflow A built per Section 5
- Digest received via Telegram and written to Obsidian for 3 consecutive days
- Error branches tested (FreshRSS down, Sheets down, bad AI response)
- No manual FreshRSS browsing during 3-day test window
9. Phase 2 — Workflow B: Retrospective & Reconciliation
Trigger: Manual or weekly schedule, run once Workflow A has ~2 weeks of output.
Purpose: two distinct jobs bundled into one retrospective pass:
- Sheet accuracy check — are High-rated sources actually making the top 5 regularly? Are Low-rated sources sneaking in often (sheet may be stale)? Surface these as a summary for you to manually adjust ratings.
- New source reconciliation — you’ll be adding channels/blogs from Substack/YouTube exploration outside the sheet-first workflow (e.g. subscribing directly in FreshRSS or Substack before rating it). This workflow’s job: diff FreshRSS’s actual subscription list against the Google Sheet, and surface:
- Sources in FreshRSS but not in the sheet → flag as “Unrated, needs review” (these were already scoring as “Unrated” in daily digests, but this surfaces them explicitly so they don’t stay invisible)
- Sources in the sheet marked “Drop” but still active in FreshRSS → flag for cleanup
- (Optional later) Sources getting picked in top-5 disproportionately vs. their rating, or never picked despite High rating
Rough shape (not built yet):
[Schedule Trigger] — weekly
↓
[HTTP Request] — FreshRSS: list all subscriptions
↓
[Google Sheets] — read subscriptions sheet
↓
[Code] — diff the two lists (name matching, same normalization as Workflow A)
↓
[Code] — (optional) pull last 2 weeks of digest history from Obsidian notes, tally which sources scored well
↓
[Telegram or Obsidian] — send/write reconciliation report: "3 new unrated sources found, 1 dropped source still active, X source over/under-performing vs rating"
This is deliberately not spec’d in detail yet — it depends on real Workflow A output existing first, and on you deciding how much of the reconciliation you want automated vs. just a prompt for manual review. Revisit after 2 weeks of MVP running.
10. Success Metric
You stop feeling the “pages and pages” dread, and your Google Sheet stays a living, trustworthy artifact — not another neglected list — because the retrospective workflow keeps it honest without demanding constant manual upkeep.
- Why?
- Manage Clickbait so that I don’t get distracted
- Avoid ads and get to the news faster and more targeted and more succint
- Credible sources - see unfortunate fact of poor guidance on this to younger gen Social Media
- Options
- Freemium
- Feedly - App + Web
- Innoreader
- Artifact - App
- FreshRSS
- Scrape down content using 5 fingers
- Freemium
- Use Case
- Discover
- Use
- Manage Folders
- Filter Search
- Read Article
- API to external RSS reader?
- Resources
- {{video https://youtu.be/A97sPctsnXU?si=0Zc0iFHOAwJ6UMzr}}
- Feedly
- Controlled and Staged content consumption
- App based
- Algorithm for what’s popular
- Add /feed to end of news site to get the RSS feed
- Artifact
- New kid on the block
- AI summary of article
- Feedly
- {{video https://youtu.be/A97sPctsnXU?si=0Zc0iFHOAwJ6UMzr}}