How to Automate Brand Mention Monitoring with n8n

By The LightCube Labs team

The Problem

Brand mentions appear on blogs, news sites, and forums at random hours, and nobody on a small team has time to refresh search results every morning. Google Alerts emails pile up unread in the inbox, the same article shows up three times, and a critical review can sit unanswered for days. Paid listening tools solve this but cost more than many small teams can justify. This guide shows how to build an n8n workflow that polls a Google Alerts RSS feed every 6 hours, removes mentions you have already seen, posts only new ones to Slack, and keeps a running log you can chart for volume trends.

What You Will Need

Step-by-Step Workflow Setup

1 Schedule the polling run

Every n8n workflow needs a starting point. The Schedule Trigger node fires the workflow on a fixed interval, which suits RSS polling because Google Alerts feeds only refresh a few times per day anyway.

Add a Schedule Trigger node to a new n8n workflow and configure:

Node: Schedule Trigger
Trigger Rules: Add Rule
Trigger Interval: Hours
Hours Between Triggers: 6
Trigger at Minute: 5

In n8n, setting the minute to 5 avoids firing exactly on the hour, when many shared hosts are busy. The trigger emits a timestamp that later nodes can reuse for the seenAt column.

Expression: {{ $now.toISO() }}
Sample output:
{
  "timestamp": "2026-11-04T06:05:00.000-08:00",
  "Readable date": "November 4th 2026, 6:05:00 am",
  "Day of week": "Wednesday"
}

Remember to activate the workflow with the toggle in the top right, otherwise the Schedule Trigger only runs when you test manually.

2 Fetch the Google Alerts RSS feed

In Google Alerts, set Deliver to RSS feed, then copy the feed link from the alert list. The HTTP Request node downloads that Atom XML so the next n8n node can parse it.

Add an HTTP Request node to the n8n canvas and configure:

Node: HTTP Request
Method: GET
URL: https://www.google.com/alerts/feeds/YOUR_USER_ID/YOUR_FEED_ID
Authentication: None
Response Format: Text
Put Output in Field: data
Options > Timeout: 20000
Options > Redirects > Follow Redirects: On

Setting the response format to Text matters. If you leave it on autodetect, n8n may convert the XML to JSON and change the shape your Code node expects.

Sample output:
{
  "data": "<feed xmlns=\"http://www.w3.org/2005/Atom\"><entry><title>Acme launches new API</title><link href=\"https://www.google.com/url?q=https://example.com/acme-api\"/><published>2026-11-04T03:12:00Z</published></entry></feed>"
}

3 Read the existing mention log

To avoid alerting twice on the same article, the n8n workflow needs to know what it has already logged. A Google Sheets node reads every row from the Mentions tab before the parser runs.

Add a Google Sheets node and configure:

Node: Google Sheets
Resource: Sheet Within Document
Operation: Get Row(s)
Document: By ID (your spreadsheet ID)
Sheet: Mentions
Return All: On
Settings > Always Output Data: On

Turning on Always Output Data is important. On the very first run the sheet is empty, and without this setting n8n stops the branch because zero items were returned.

Sample output:
{
  "row_number": 2,
  "title": "Acme launches new API",
  "link": "https://example.com/acme-api",
  "published": "2026-11-04T03:12:00Z",
  "seenAt": "2026-11-04T06:05:00.000-08:00"
}

4 Parse the feed and deduplicate

The Code node does the heavy lifting in this n8n workflow. It splits the Atom XML into entries with a regular expression, unwraps the Google redirect URL, and compares each link against the sheet log. A regex keeps this portable, since the cheerio package requires NODE_FUNCTION_ALLOW_EXTERNAL on self-hosted n8n.

Add a Code node and configure:

Node: Code
Mode: Run Once for All Items
Language: JavaScript

const xml = $('HTTP Request').first().json.data;
const seen = new Set($('Read Mention Log').all().map(i => i.json.link));
const entries = xml.split('<entry>').slice(1);
const out = [];
for (const e of entries) {
  const title = (e.match(/<title[^>]*>([\s\S]*?)<\/title>/) || [])[1] || '';
  const raw = (e.match(/<link[^>]*href="([^"]+)"/) || [])[1] || '';
  const link = decodeURIComponent((raw.match(/[?&]q=([^&]+)/) || [])[1] || raw);
  const published = (e.match(/<published>([^<]+)/) || [])[1] || '';
  if (link && seen.has(link) === false) {
    out.push({ json: { title: title.replace(/<[^>]+>/g, ''), link, published } });
    seen.add(link);
  }
}
return out;

Adding each new link to the same Set inside the loop also removes duplicates within a single feed pull. Google sometimes lists one story under two keywords.

Expression: {{ $('Read Mention Log').all().length }}
Sample output:
{
  "title": "Acme launches new API",
  "link": "https://example.com/acme-api",
  "published": "2026-11-04T03:12:00Z"
}

5 Branch on new mentions

If the Code node returns zero items, n8n stops by default, but an explicit IF node makes the logic visible and lets you add a quiet-day branch later, such as a weekly "no mentions" note.

Add an IF node and configure:

Node: IF
Conditions: Number
Value 1: {{ $input.all().length }}
Operation: Is Greater Than
Value 2: 0
Settings > Always Output Data: On

In n8n, the true output continues to Slack and the sheet. The false output can stay unconnected, which ends the run cleanly.

6 Post new mentions to Slack

The Slack node sends one message per mention. Because the incoming data has one item per mention, n8n loops automatically, so no extra n8n loop node is required.

Add a Slack node on the true branch and configure:

Node: Slack
Resource: Message
Operation: Send
Send Message To: Channel
Channel: By Name, brand-mentions
Message Text: New mention: {{ $json.title }}\n{{ $json.link }}\nPublished: {{ $json.published }}
Options > Include Link to Workflow: Off

Invite the Slack app connected to n8n to the brand-mentions channel first, or the node returns a not_in_channel error.

Sample output:
{
  "ok": true,
  "channel": "C04BRAND01",
  "message": { "text": "New mention: Acme launches new API" }
}

7 Append mentions and track volume

The last node writes each new mention back to the log. Reading the data from the IF node, not Slack, keeps the original fields intact.

Add a Google Sheets node and configure:

Node: Google Sheets
Resource: Sheet Within Document
Operation: Append Row
Sheet: Mentions
Mapping Column Mode: Map Each Column Manually
title: {{ $('IF').item.json.title }}
link: {{ $('IF').item.json.link }}
published: {{ $('IF').item.json.published }}
seenAt: {{ $now.toISO() }}

For volume tracking, add a second tab with a COUNTIF formula over the seenAt column grouped by date. A line chart of that tab shows spikes after launches or press coverage, and you can compare weeks without any extra n8n nodes or paid dashboards.

Troubleshooting

The same article keeps getting posted to Slack from n8n

Google wraps links in a redirect URL, so two pulls can differ by tracking parameters. Make sure the n8n Code node unwraps the q parameter before comparing, and confirm the link column in the sheet stores the unwrapped value, not the redirect.

The feed returns empty even though alerts exist

Google Alerts only populates the RSS feed after the first matching result, which can take a day. Test the feed URL in a browser. If it shows an empty feed element, wait, or broaden the alert query.

The n8n workflow stops after the sheet read on the first run

An empty sheet returns zero items and n8n halts downstream nodes in that branch. Enable Always Output Data on the Google Sheets node, and make sure the header row exists so the later Append Row operation can match columns.

Free n8n Workflow Resources

Get started with the free workflow pack on the LightCube Labs templates page.

Production-Ready Workflow Packs

Get this workflow and more, with setup guides, editable configurations, and a shared failure-alert system.

View the Starter ($29) and Pro ($99) Packs

Frequently Asked Questions

How often does a Google Alerts RSS feed actually update?

Google does not publish a schedule, but results typically arrive in batches several times per day. Polling every 6 hours from n8n is a sensible match, and polling more often only adds requests without producing fresher data.

Can I monitor several brand names in one n8n workflow?

Yes. Add one HTTP Request node per feed, or store the feed URLs in a sheet and use a Loop Over Items node. Add a brand column to the log so the n8n dedup check and volume chart stay separate per name.

How do I measure mention volume over time?

Because every new mention is logged with a seenAt timestamp, a pivot table grouped by day gives you volume. Compare it against the previous week to spot unusual spikes worth a closer look.

Will the log sheet grow too large for n8n?

Google Sheets handles tens of thousands of rows, but reading all rows in each n8n run slows down eventually. Archive rows older than 90 days to a second tab once a quarter.