Skip to content
zarif/automatesGet Still Building
Research guideUpdated · Zarif

How to Build a Weekly AI Article Recommendation Workflow

Build a weekly n8n workflow that pulls new articles from your sources, drops repeats, has AI rank the rest, checks every link, and emails a short list.

Article cards pass through a blue sorting rack into a short reading stack inside an envelope, with a duplicate set aside.

Once a week, this workflow sends you a short list of articles worth reading, each with a working link and one line on why it matters.

It does six things. It collects new links from a small list of sources you trust, cleans up their details, drops anything old or already sent, has AI score what's left against your interests, checks that every link still works, and sends the list. The AI ranks and explains. It never makes up the reading list.

The simplest version runs on n8n with RSS feeds, an n8n Data Table, one language-model call, and Gmail or Slack. Run it weekly, look over what it picks, and let your feedback shape the next list.

If the picks are headed for a public newsletter, hand the approved items to a separate newsletter workflow. This guide only covers finding and ranking the articles.

How the workflow fits together

Here's the full path:

Weekly schedule
  -> Source list
  -> Read feeds
  -> Normalize article fields
  -> Reject old and previously seen URLs
  -> Score remaining articles with AI
  -> Apply quality threshold
  -> Sort and keep the top items
  -> Verify URLs
  -> Build digest
  -> Send email or Slack message
  -> Record delivered URLs and feedback fields

The order matters. Plain rules are cheaper and more reliable than asking a model. A date check can tell you an article is seven days old. A lookup in your history can tell you a link already went out. Neither needs AI, so they run first and the model only sees what's left.

StageBest mechanismWhy
Weekly timingSchedule TriggerPredictable cadence and timezone
Source collectionRSS Read or source APIPreserves real titles, URLs, and timestamps
FreshnessDate ruleObjective and inexpensive
Exact deduplicationCanonical URL lookupPrevents repeat recommendations
Semantic relevanceLanguage modelUnderstands topic fit and usefulness
Final availabilityHTTP status checkStops dead links reaching the digest
HistoryData TableProvides memory across weekly runs

Step 1: Decide what deserves a spot

Don't start with nodes. Start by writing down, on one screen, what a good pick looks like.

Cover five things:

  1. Topics: what you actually want to learn about.
  2. Reader: who the list is for.
  3. How recent: usually seven to ten days for a weekly list.
  4. What counts as solid: original sources, technical docs, research, or write-ups from people doing the work.
  5. What to skip: rewritten press releases, thin listicles, the same announcement covered five times, paywalled pages, topics you don't care about.

Here's an example for someone running AI automations:

Recommend articles about AI agents, workflow automation, model releases,
enterprise adoption, and measurable small-business use cases.

Prefer primary sources, technical implementation detail, original data,
and credible operator lessons. Reject generic trend summaries, copied
launch announcements, unsupported predictions, and articles older than
10 days. The reader should learn something they can apply this month.

Without this, "best" means nothing. A viral article can be a bad pick for your reader, while a quiet product changelog can change something you run every day.

Step 2: Make a short list of sources

Start with 10 to 20 sources. Give each one these fields:

  • source name
  • feed or endpoint URL
  • topic lane
  • source type
  • trust tier
  • active status

A Google Sheet is easy to edit by hand. An n8n Data Table keeps everything inside the workflow. Either way, use one row per source, so you can switch off a noisy feed without touching the automation.

Favor sources that publish their own work: AI labs, product changelogs, research groups, standards bodies, and people writing up what they built. Add general news sites only when they keep catching stories your list misses.

RSS is still the cleanest input when a site offers it. n8n has an official RSS Read node for pulling a feed. When there's no feed, use the site's official API. Scraping the page is a last resort, because a layout change can break it without warning.

Step 3: Pick a weekly time

Use the n8n Schedule Trigger and set the workflow's timezone yourself. Thursday morning is a good default. The list arrives before end-of-week reading time and misses the Monday inbox pile.

Name the workflow for what it does, like Send weekly AI reading recommendations. Name each node for its job too, not "HTTP Request 3": Load active sources, Reject previously sent URLs, Score editorial value. When a feed breaks three months from now, those names are how you'll find the problem.

Once a week is enough unless speed actually matters. The point is a thoughtful list, not breaking news.

Step 4: Put every article in the same shape

Feeds name their fields differently and write dates differently. Before you filter anything, convert every item into one common record:

json
{
  "title": "Article title",
  "url": "https://publisher.example/article",
  "canonicalUrl": "https://publisher.example/article",
  "publishedAt": "2026-08-10T09:00:00Z",
  "source": "Publisher",
  "sourceTier": "primary",
  "topicLane": "ai-agents",
  "excerpt": "Feed-provided description",
  "collectedAt": "2026-08-12T02:00:00Z"
}

The canonicalUrl is the clean version of the link, the one you'll use to spot repeats. To get it, strip tracking tags like utm_source, utm_medium, and utm_campaign, lowercase the domain, drop anything after a #, and pick one rule for trailing slashes. That way the same article shared in three campaigns counts as one.

Don't let AI fill in missing dates or links. If a required field is missing, send the item to a review list or drop it. A made-up date makes the freshness check meaningless.

Step 5: Drop old, repeated, and empty items

Run the cheap checks first:

  1. URL uses HTTP or HTTPS.
  2. Publication date is inside the freshness window.
  3. Title and excerpt aren't empty.
  4. Canonical URL hasn't appeared in the current batch.
  5. Canonical URL doesn't exist in delivery history.
  6. Source is active.

Keep your sent history in a Data Table with canonicalUrl, firstSeenAt, sentAt, digestId, score, and an optional feedback field. n8n describes Data Tables as storage that stays around between workflow runs. A spreadsheet or database works too. What matters is that the history survives after each run ends.

Matching links won't catch the same story on two different sites. So add a second repeat check after scoring. Compare cleaned-up titles, or ask the model for a short storyKey like openai-new-agents-sdk-release. Keep the best source for each story key. Original sources win ties.

Step 6: Have AI score what's left

Only send the model the details that survived. Sending full articles costs more, runs slower, raises copyright questions, and opens the door to prompt injection, where text inside an article tries to give the model instructions. For most feeds, the title, source, excerpt, date, and your Step 1 rules are enough for a first ranking.

Ask for one JSON object per article:

json
{
  "relevance": 0,
  "originality": 0,
  "actionability": 0,
  "credibility": 0,
  "overallScore": 0,
  "topic": "",
  "storyKey": "",
  "summary": "",
  "whyRead": "",
  "confidence": 0,
  "rejectReason": ""
}

Use a 0-to-100 scale and set the weights yourself:

overallScore =
  relevance * 0.35 +
  actionability * 0.30 +
  credibility * 0.20 +
  originality * 0.15

Then apply a fixed cutoff after the model answers. For example, require an overall score of at least 72, confidence of at least 0.7, and no reject reason.

The model never touches the title, source, link, or date. Carry those straight from the feed record and attach the AI's scores and summary to them. This is the main thing that stops the list from containing made-up articles.

A prompt that works

Use a prompt shaped like this:

You are ranking a candidate article for a weekly reading digest.

Editorial policy:
[insert the saved policy]

Candidate metadata:
[insert title, source, source tier, date, topic lane, and excerpt]

Score relevance, actionability, credibility, and originality from 0 to 100.
Recommend only material that teaches the audience something usable or
changes an important decision. Penalize generic summaries, promotional
copy, duplicated announcements, and claims unsupported by the supplied
metadata.

Return only the required structured fields. Do not create, rewrite, or
infer a URL. If the metadata is insufficient, lower confidence and explain
the rejection briefly.

Add two or three examples from past weeks: one clear yes, one clear no, and one borderline case. Examples keep the model's taste steady far better than words like "excellent" or "insightful."

Step 7: Keep the list varied

Sorting by score alone often gives you five takes on the same announcement. Add limits after scoring:

  • maximum two articles per topic lane
  • maximum one article per story key
  • maximum two articles per publisher
  • at least one technical or primary source
  • five to ten recommendations total

If only three articles clear the bar, send three. A short list you can trust trains you to open it. A padded one trains you to ignore it.

For each pick, show:

  • linked original title
  • publisher and date
  • two-sentence factual summary
  • one sentence explaining why it matters to this reader
  • topic label
  • optional estimated reading time only when the source supplies it

Send a quick request to each chosen link. Accept pages that load and redirects that are clearly intentional. Reject errors, redirect loops, and links that land on a parked domain.

If a link fails, don't swap in one the model suggests. Use a working backup you already collected, or drop the item.

This last check catches articles taken down after collection, broken tracking links, and sites that moved. It's also the difference between a real reading list and an AI-written list of links that only look real.

Step 9: Send it and save what went out

Email is the best default for a personal weekly list. Slack works for a team. Notion or Google Docs work when people mark up the list before a meeting.

Make the subject line say exactly what's inside:

Your 7 AI reads for August 10-16

After the send succeeds, write every sent link to your history. Don't write sentAt before it succeeds. If the email fails, those articles would otherwise be marked as sent and never show up again.

Add simple feedback buttons:

  • useful
  • not relevant
  • already knew this
  • source quality issue

Look at the feedback once a month and update topics, source trust levels, and exclusions yourself. Don't let the model rewrite its own rules after every click. Rules you set should change because you decided to change them.

Keep it from failing quietly

A scheduled workflow that breaks without telling you is worse than no workflow. You just stop noticing what you're missing.

Add these:

  • retry network and model calls up to three times with a short backoff
  • configure a workflow-level error workflow that sends the failed workflow name, execution ID, and error
  • store the current digest ID so a retried run cannot send the same email twice
  • cap the number of candidates entering the model step
  • record counts at every gate: collected, fresh, unseen, scored, accepted, verified, delivered
  • alert when collected items fall to zero or change unusually from the normal range

The digest ID matters more than it looks. Picture a run that sends the email, then crashes before it records that it did. The retry would send the same email again. Saving the digest ID lets the retry see the work is already done. That property, where running something twice has the same effect as running it once, is called idempotency.

n8n's error-handling documentation covers error workflows and the Error Trigger. The rule is simple: every failure should be visible, and every retry should be safe.

Cost and scale

It stays cheap because rules shrink the pile before the model sees it. Say 20 feeds produce 300 items a week. The date check and history lookup might cut that to 80. Source rules and basic checks might cut it again to 30. The model scores 30 short records, not 300 full articles.

As it grows, split it into two workflows:

  1. a daily ingestion workflow collects, normalizes, and deduplicates
  2. a weekly recommendation workflow reads unseen candidates, scores them, and sends the digest

That way a broken feed doesn't stop the weekly send, and you can test each part on its own. If you build reusable sub-workflows, have each one take an article in and hand an article back, without depending on anything else from the run.

Common mistakes

Searching the whole web every run

You get noisy results that change from week to week. Start with your source list. Add wider discovery later as a separate, lower-trust lane.

Links are data you collected, not text the model writes. Keep the source link exactly as it came in and check it before sending.

Only checking for repeats within one week

The same article will show up again next week. Keep your sent history between runs.

Summarizing before filtering

You end up paying to summarize items a date check or history lookup would have dropped for free. Filter first, score second, and summarize only the finalists, only when you need to.

Publishing without a person checking

For a private list, sending automatically is usually fine. For a public newsletter or a client brief, add an approval step before anything goes out. The cost of a bad pick is much higher.

No error alert

A broken feed, an expired login, or a model rate limit can all look like a quiet week. Nothing arrives and nothing complains. An error alert turns that silence into something you can fix.

Checklist

  • Write the editorial policy and exclusions
  • Create a 10-to-20-source registry
  • Set an explicit workflow timezone
  • Normalize title, canonical URL, source, excerpt, and date
  • Create persistent URL history
  • Filter freshness and exact duplicates before AI
  • Require structured scoring output
  • Preserve source URLs outside the model output
  • Enforce diversity and quality thresholds
  • Verify finalist URLs
  • Make delivery idempotent
  • Add retries and a workflow-level error alert
  • Test with a good feed item, an old item, a duplicate, a missing date, and a dead URL
  • Review feedback monthly

Where to start

Build the small version first: trusted RSS feeds, a seven-day window, sent history, one scoring call, five picks, email delivery. It's useful, you can explain every pick, and it's easy to keep running.

Add wider web search, embeddings, per-person profiles, or more delivery channels only after the list keeps surfacing articles you actually read. Your source list and your Step 1 rules will matter more than how clever the model is.

END OF ARTICLE

Want the next story in your inbox?

For people who build with AI and want judgment instead of a roundup.

One story from the AI world, told properly, and what I make of it.