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
Comments
Leave a comment
Your comment will appear after moderation.
Your name and email are only used to identify your comment. Your email is never shown publicly. Privacy policy.
Related articles
Pxe
Setting Up a PXE Boot Server with netboot.xyz and dnsmasq
Network booting has become an essential tool for system administrators and developers who need to deploy or test operating systems across…
Read the article →
Github-actions
Run rails tests with github actions matrix strategy
You can easily speedup tests runs by using matrix strategy with github actions. Create a script called for example ci_tests which generates…
Read the article →
Homelab
AdGuardHome on Asuswrt-Merlin
Home should always be a safe place for navigating the internet, especially for children. As they often use it for listening to music or…
Read the article →