Build a daily tech digest with n8n, RSS and OpenAI
What you'll build: an automated workflow that aggregates 16 RSS sources every morning (Reddit, Hacker News, newsletters, FR/EN blogs), summarizes the news in your language with OpenAI, and sends it to your phone via Gotify.
Level: intermediate — you should already know how to create a basic n8n workflow.
Prerequisites
- A self-hosted n8n instance (v2.30+)
- An OpenAI API key
- A Gotify server (or replace with Email/Slack/Telegram)
Architecture
Schedule Trigger (7:00 AM)
→ 16 HTTP Requests in parallel
→ Merge Sources
→ Code node "Parse & Filter"
→ Aggregate
→ OpenAI
→ Gotify
Step 1 — Schedule Trigger
Set the trigger to cron expression 0 7 * * * to run every day at 7:00 AM. Make sure to configure the timezone in the workflow Settings.
Step 2 — HTTP Request nodes
Create one HTTP Request node per source, all connected to the Schedule Trigger — they run in parallel. Enable continueOnFail: true on each so the workflow keeps going if a source is unavailable.
| Source | URL |
|---|---|
| Reddit (multi-subreddit) | https://www.reddit.com/r/rails+swift+androiddev+selfhosted+homelab+devops+MachineLearning+LocalLLaMA+healthtech+worldnews+technology/.rss?limit=100 |
| Hacker News | https://hnrss.org/frontpage?points=100 |
| Ruby Weekly | https://rubyweekly.com/rss |
| TLDR Tech | https://bullrich.dev/tldr-rss/tech.rss |
| TLDR AI | https://bullrich.dev/tldr-rss/ai.rss |
| TLDR DevOps | https://bullrich.dev/tldr-rss/devops.rss |
| Simon Willison | https://simonwillison.net/atom/everything/ |
| selfh.st | https://selfh.st/news/rss.xml |
| Dev.to Rails | https://dev.to/feed/tag/rails |
| Changelog | https://changelog.com/news/feed |
| RubyFlow | https://rubyflow.com/atom.xml |
| Lobsters | https://lobste.rs/rss |
| Boring Rails | https://boringrails.com/feed |
| Journal du Geek | https://www.journaldugeek.com/feed/ |
| Les Numériques | https://www.lesnumeriques.com/rss.xml |
| Korben | https://korben.info/feed |
Reddit natively supports multi-subreddit feeds using
+in the URL — one HTTP Request covers all of them. Add aUser-Agent: Mozilla/5.0 (compatible; n8n-digest/1.0)header to avoid rate limits.TLDR has no official RSS feed — the open-source project bullrich/tldr-rss generates separate feeds per newsletter.
Step 3 — Merge Sources
Add a Merge node in Append mode and connect all HTTP Request nodes to it.
Enable waitForAllInputs: true — without this, the Merge fires as soon as the first 2 branches complete and ignores the rest.
⚠️ When testing manually, n8n doesn't always trigger all branches in parallel. This option works correctly on scheduled runs.
Step 4 — Code node "Parse & Filter"
This node receives the raw XML from each source and extracts relevant articles. It:
- Automatically detects the source (Reddit, HN, TLDR, etc.)
- Supports both RSS and Atom formats
- Extracts title, URL, date and description from each entry
- Filters out old articles — 48h window on weekdays, 72h on Mondays to cover the weekend
- Deduplicates by URL
- Limits to 5 articles per source
- Returns an empty array if nothing to report — the workflow stops cleanly without calling the LLM
Step 5 — Aggregate
Add an Aggregate node set to Aggregate All Item Data with items as the destination field. This bundles all articles into a single object for prompt construction.
Step 6 — OpenAI
Add an OpenAI node. The prompt is built dynamically in the User Message field via an n8n expression. It:
- Separates French sources (JDG, Numériques, Korben) from English ones
- Includes the title and description of each article for context
- Requests a digest structured into thematic sections: AI, Ruby/Rails, iOS/Android, Self-hosted, DevOps, Healthtech, Tech/Startups, FR News
- Enforces pure Markdown output, no HTML
Step 7 — Gotify
Add a Gotify node:
- Message: ={{ $json.output[0].content[0].text }}
- Title: 🗞️ Tech Digest — Yesterday
- Priority: 7
⚠️ Do not add
contentType: text/markdownin the options — this parameter doesn't exist in Gotify node v1 and silently crashes the workflow.
Common pitfalls
| Problem | Fix |
|---|---|
| Merge fires too early | Enable waitForAllInputs: true |
fetch() silently does nothing in Code node |
n8n's JS sandbox has no network access — use HTTP Request nodes instead |
| Reddit subreddit not detected | Read <category term="..."> from each entry, not <id> |
| Gotify silent crash | Remove the non-existent contentType: text/markdown option |
| Workflow stalls with 0 articles | Return [] from the Code node — n8n stops cleanly |
Going further
- Add a source: one more HTTP Request node connected to the Schedule Trigger and Merge
- Change digest sections: edit the section list in the OpenAI prompt
- Avoid duplicate articles across runs: use
$workflow.staticDatato persist seen URLs - Replace Gotify: Email, Slack, Telegram — the last node is interchangeable