GODRICH

Marketing Automation Basics: 9 News Workflows

n8n connects apps by wiring boxes together, no backend code. In marketing or PR and searched marketing automation basics, tired of checking ten news sites by

Auto-plays · click a tile to jump to its section · all nine in one zip

These nine are arranged to match how a real monitoring habit grows. It starts with pulling in one source (01), then moves to two ways of combining sources (02 stitching a stream together, 03 counting by source separately), narrows things down two ways (04 by keyword, 05 by date), cleans the result two ways (06 removing repeats, 07 shaping a table), splits by condition once (08), and finally wraps all of that into something that runs on its own every day (09). A team usually adds these one at a time, in roughly this order, as manual news-checking turns into an automated habit.

01Basic RSS read

Instead of opening a site by hand to check for new posts, an RSS Read node pulls the latest list as-is, and a Set node keeps only the title, link, and date. This is the shape to reach for when watching a favorite blog or taking a first step into automation — the simplest version before anything else gets added.

RSS ReadSet → title/link/pubDateV2 실행 확인
{
  "name": "Keep Fields",
  "type": "n8n-nodes-base.set",
  "typeVersion": 3.5,
  "parameters": {
    "mode": "manual",
    "assignments": {
      "assignments": [
        { "name": "title", "value": "={{ $json.title }}", "type": "string" },
        { "name": "link", "value": "={{ $json.link }}", "type": "string" },
        { "name": "pubDate", "value": "={{ $json.pubDate }}", "type": "string" }
      ]
    }
  }
}

02Merge two RSS feeds, newest first

Two RSS Read nodes pull from different sites, a Merge node in append mode stitches the streams into one, and Sort puts the newest posts first. Once you're reading several outlets in one place or watching a competitor's blog alongside your own industry feed, a single source stops being enough.

RSS Read ×2Merge appendSort desc → V2 실행 확인
{
  "name": "Merge Append",
  "type": "n8n-nodes-base.merge",
  "typeVersion": 3.2,
  "parameters": {
    "mode": "append",
    "numberInputs": 2
  }
}

03Summarize counts across feeds

Where item 02 blends two sources into one stream, this one keeps them apart: two Aggregate nodes collect titles per source, and a Code node builds a summary object with a count and top 3 titles for each. It's built for comparing output per source or gathering material for a weekly report — counting separately beats mixing everything together.

RSS Read ×2Aggregate ×2 → Merge by positionCode 요약 → V2 실행 확인
{
  "name": "Build Summary",
  "type": "n8n-nodes-base.code",
  "typeVersion": 2,
  "parameters": {
    "jsCode": "const bbc = $json.bbcTitles || [];\nconst ars = $json.arsTitles || [];\nconst summary = {\n  bbc: { count: bbc.length, titles: bbc.slice(0, 3) },\n  ars: { count: ars.length, titles: ars.slice(0, 3) }\n};\nreturn [{ json: { summary } }];"
  }
}

04Filter by keyword, keep top N

A Filter node keeps only posts whose title contains a keyword (case-insensitive), and Limit trims that down to the top 3. When the goal is getting alerts for one topic only and cutting the noise, narrowing first beats forwarding everything and sorting later.

Filter contains(대소문자 무시)Limit 3V2 실행 확인
{
  "conditions": {
    "options": { "caseSensitive": false, "version": 2 },
    "conditions": [
      {
        "leftValue": "={{ $json.title }}",
        "rightValue": "ai",
        "operator": { "type": "string", "operation": "contains" }
      }
    ],
    "combinator": "and"
  }
}

05Keep only the last N days

Filter compares pubDate against now minus 3 days using the dateTime condition's after operator, keeping only recent posts. For excluding stale posts from a weekly roundup and keeping things fresh, filtering by date alone is enough — no keyword needed.

Filter dateTime after$now.minus(days:3)V2 실행 확인
{
  "conditions": [
    {
      "leftValue": "={{ $json.pubDate }}",
      "rightValue": "={{ $now.minus({ days: 3 }) }}",
      "operator": { "type": "dateTime", "operation": "after" }
    }
  ],
  "combinator": "and"
}

06Only new items across runs

Remove Duplicates' Remove Items Processed in Previous Executions operation filters out links already seen in an earlier run, and Set stamps the survivors with isNew. If the point is running the same schedule daily without repeat alerts, dedupe inside a single run isn't enough — this remembers across executions instead.

Remove Duplicatesscope: workflowV2 실행 확인
{
  "name": "Remove Seen Links",
  "type": "n8n-nodes-base.removeDuplicates",
  "typeVersion": 2,
  "parameters": {
    "operation": "removeItemsSeenInPreviousExecutions",
    "logic": "removeItemsWithAlreadySeenKeyValues",
    "dedupeValue": "={{ $json.link }}",
    "options": { "scope": "workflow" }
  }
}

07A news digest as an HTML table

Limit keeps the first 8 items, then the HTML node's Convert to HTML Table operation turns them straight into a table. For putting a news table in an email body or a dashboard widget, a table scans faster than a bare list.

Limit 8HTML convertToHtmlTableV2 실행 확인
{
  "name": "Build Table",
  "type": "n8n-nodes-base.html",
  "typeVersion": 1.2,
  "parameters": {
    "operation": "convertToHtmlTable",
    "options": {
      "capitalize": true,
      "caption": "Fox News latest headlines"
    }
  }
}

08Route by keyword (Switch)

Switch splits posts three ways by keyword in the title — ai, security (or breach), and everything else — then each branch's Set stamps a route label and Merge gathers the branches back together. Once auto-sorting into topic channels or alert routing needs more than two outcomes, a single IF branch can't keep up.

Switch 3 routesfallbackOutput: extraV2 실행 확인
{
  "mode": "rules",
  "rules": {
    "values": [
      {
        "conditions": {
          "conditions": [
            { "leftValue": "={{ $json.title }}", "rightValue": "ai",
              "operator": { "type": "string", "operation": "contains" } }
          ]
        },
        "outputKey": "ai"
      }
    ]
  },
  "options": { "fallbackOutput": "extra", "renameFallbackOutput": "other" }
}

09Scheduled digest delivery

Schedule wakes up daily at 08:00 (Manual Trigger tests it right away too), RSS Read fetches the latest posts, Aggregate collects titles and links into arrays, and Markdown pairs them into a digest field. For a daily news digest in a team channel or a personal alert bot, the schedule and the manual test both need to live in the same flow.

Schedule triggerAtHour 8 + ManualAggregate → MarkdownV2 실행 확인
{
  "name": "Build Digest",
  "type": "n8n-nodes-base.markdown",
  "typeVersion": 1,
  "parameters": {
    "mode": "markdownToHtml",
    "markdown": "={{ '# Daily Digest\\n\\n' + $json.title.map((t, i) => '- [' + t + '](' + $json.link[i] + ')').join('\\n') }}",
    "destinationKey": "digest"
  }
}

What you need before importing

Every row below says "none" for prerequisites, but the table still matters because an older n8n install can reject a node's typeVersion. Grading runs V0 (structure), V1 (import-verified), and V2 (executed and confirmed) — all nine here reached V2.

Item Grade Prerequisites n8n version
01 Basic RSS read V2 none 2.38.5
02 Merge two RSS feeds, newest first V2 none 2.38.5
03 Summarize counts across feeds V2 none 2.38.5
04 Filter by keyword, keep top N V2 none 2.38.5
05 Keep only the last N days V2 none 2.38.5
06 Only new items across runs V2 none 2.38.5
07 A news digest as an HTML table V2 none 2.38.5
08 Route by keyword (Switch) V2 none 2.38.5
09 Scheduled digest delivery V2 none 2.38.5

Three ways to bring these in: paste the JSON text straight into the n8n canvas with Ctrl/Cmd+V, use Import from File from the canvas menu on a file from the zip, or run n8n import:workflow --input=file.json from the CLI. Once imported, the Test workflow button in the top-left corner runs it on the spot.

Where this breaks

The quietest trap showed up in item 06 — turning on Set's "Include Other Input Fields" option looked as simple as adding it inside the Options block, and the run still finished with exit 0, but the title field vanished silently while only isNew survived. That option actually lives at the top level of the node, alongside mode and assignments, not inside Options — put it in the wrong spot and n8n just falls back to its default (false) without complaint. The password to open this zip is xu26t3qn, and once unzipped, all nine JSON files sit in workflows/ exactly as built. Item 06's Remove Duplicates has a second gotcha of its own: because it remembers across executions, testing the same workflow repeatedly shrinks the pool of "new" items until it hits zero, and when that happens the downstream Set node never runs at all, so isNew disappears from the output entirely.

FAQ

Does this work on n8n cloud too?

Yes. None of these workflows use community nodes or credentials tied to an account, so they import cleanly through the Import menu. Item 09's Schedule Trigger only fires on its own once the workflow is switched to Active.

What if my n8n version doesn't match?

If you hit a typeVersion error, build that node fresh on your canvas, export it to see the real value, then use that instead. This zip was verified for both import and execution on n8n 2.38.5 running on Node 24.

Do I need to read code to use item 06's dedupe?

No — except for item 03's Code node, the other eight are built entirely from n8n's built-in nodes, so no JavaScript is required to follow along. Item 06 is just a dropdown choice on the Remove Duplicates node, and the option details are in the official n8n docs.

New to n8n? The automation category has more examples like this one, and the about page explains how this site verifies what it publishes.

Enter the archive password

The password is inside this article. You will find it as you read.