n8n Competitor Analysis Workflow: AI Change Alerts by Email
AnswerEvery founder and agency owner does the same ritual: open a rival's pricing page, squint at it, and try to remember whether the Pro plan was $49 or $59 last month. That ritual doesn't scale past two competitors, and it fails exactly when it matters — the week they quietly raise prices or rewrite their pitch.
Contents
- What should a competitor analysis workflow actually watch?
- How does the workflow work, node by node?
- How is the AI extraction prompt written so it returns one field, not prose?
- How do diffing and alerting work? (Sheets as memory, Gmail as the alarm)
- DIY vs the $29 tool — the honest comparison
- What breaks — and how to think about it before it does
- What we verified in the workflow file
- Use it today
What should a competitor analysis workflow actually watch?
Every founder and agency owner does the same ritual: open a rival's pricing page, squint at it, and try to remember whether the Pro plan was $49 or $59 last month. That ritual doesn't scale past two competitors, and it fails exactly when it matters — the week they quietly raise prices or rewrite their pitch.
An n8n competitor analysis workflow replaces the ritual with a small daily agent: it fetches the pages you list, uses AI to read the one value you care about on each, compares it to what it saw last time, and emails you only when something actually moved. Below we walk through a real, working version node by node — the Competitor Watch — n8n monitor ($29, one-time) that we ship — and we're upfront that it's a paid workflow. We also show you an honest DIY version you can build yourself with n8n's free core nodes, and a straight comparison table so you can decide which one is worth your time.
Most "competitor monitoring AI" pitches try to watch everything and end up alerting on nothing useful. In practice, four page types carry almost all the signal:
- Pricing pages — the single highest-value target. A plan price change, a new tier, or a removed annual discount is a direct signal about their margins and positioning. This is where automated competitor price monitoring in n8n earns its keep.
- Homepage headline — when a competitor rewrites their hero copy, they're telling you who they now think their customer is. Positioning shifts show up here weeks before anywhere else.
- Plan/feature pages — a feature moving from Enterprise to Pro, or a new add-on appearing, changes how you should sell against them tomorrow.
- Jobs/careers pages — "Hiring: Head of Enterprise Sales" or three ML engineer openings is roadmap intelligence hiding in plain sight.
The key design decision: watch one specific value per page, not the whole page. "The Pro plan monthly price" is a monitorable fact. "The pricing page" is a firehose of markup noise that changes every deploy. Every reliable n8n website change monitor we've seen follows this one-value-per-watch rule.
How does the workflow work, node by node?
These are the real nodes from the Competitor Watch PRO workflow file (workflowstacks-competitor-watch.n8n.json) — actual n8n node names and types, not a mock diagram:
Every day 8:00(n8n-nodes-base.scheduleTrigger, typeVersion 1.2) — a Schedule Trigger set tointerval: days,triggerAtHour: 8. n8n's Schedule Trigger supports seconds through months plus custom cron; daily-at-an-hour is the sane default for competitor pages.Get watch list(n8n-nodes-base.googleSheets, v4.5) — reads a Google Sheet tab calledWatcheswith four columns: URL, Label, Watch For, Last Value. The sheet is both your config UI and the workflow's memory.Fetch the page(n8n-nodes-base.httpRequest, v4.2) — a plain HTTP Request per row,url: {{ $json.URL }}, response formattext. No scraping service, no API key for this step.Read the value (AI)(@n8n/n8n-nodes-langchain.openAi, v1.8) — sends the stripped page text togpt-4o-miniwith a prompt built to return exactly one value (more on that prompt below).Shape the check(n8n-nodes-base.set) — an Edit Fields node that lines up five fields for the diff: URL, Label, Watch For, Old Value (the sheet'sLast Value), and the new Last Value (the AI's trimmed answer).Did it change?(n8n-nodes-base.if, v2.2) — an If node with two AND-ed string conditions: new value is not equal to old value, and new value is not equal toNOT_FOUND.Email the change(n8n-nodes-base.gmail, v2.1) — fires only on the true branch. Subject:⚡ {{ Label }} changed: {{ Watch For }}. Body showsWas:/Now:with(first check)as the fallback for a brand-new watch.Update Last Value(n8n-nodes-base.googleSheets, update operation) — writes the new value back to the sheet, matching rows on the URL column. Both branches of the If node route here, so the sheet always reflects the latest read.
There's also a sticky note node in the file (Setup instructions) with the full ~8-minute setup checklist, so the playbook travels inside the workflow itself.
How is the AI extraction prompt written so it returns one field, not prose?
This is where most homegrown competitor monitoring agents fail: the LLM returns a paragraph ("The Pro plan appears to be priced at $59 per month, though...") and your diff logic drowns in phrasing changes. The prompt in the real workflow does four specific things:
- Constrains the output format in the first sentence: "You extract one specific value from a web page's raw text. Return ONLY that value as a short plain string — no explanation, no quotes." The model is told what it is before it's told what to do.
- Injects the human's intent per row:
What to find: {{ $('Get watch list').item.json['Watch For'] }}— so the same prompt works for a price on one row and a headline on another. - Pre-cleans the HTML in the expression itself: the page body is run through
.replace(/<[^>]+>/g, ' ')to strip tags,.replace(/\s+/g, ' ')to collapse whitespace, and.slice(0, 6000)to cap tokens. The model sees readable text, not markup, and your OpenAI bill stays at gpt-4o-mini pennies. - Defines an explicit failure token: "If you cannot find it, return exactly: NOT_FOUND." That gives the downstream If node a machine-checkable failure state instead of an apologetic paragraph.
Deterministic output shape + explicit failure token is the whole trick. If you write your own prompt, copy those two properties and you'll avoid 90% of flaky-diff pain.
How do diffing and alerting work? (Sheets as memory, Gmail as the alarm)
The workflow has no database — the Google Sheet is the memory. Each row's Last Value column stores what the AI read on the previous run.
The diff is deliberately simple: the Did it change? If node does a string is not equal to comparison between today's AI answer and the stored Last Value, AND-ed with a guard that today's answer isn't NOT_FOUND. That second condition matters: a page that temporarily fails to parse should not fire a "your competitor changed their price!" alert.
On the true branch, the Gmail node sends a short plain-text email — label, URL, what was being watched, Was: old value, Now: new value. On the first ever check, Old Value is empty and the email shows (first check) instead.
Either way, Update Last Value writes today's reading back to the sheet, matched on URL. Two honest nuances we confirmed in the file:
- If the AI returns
NOT_FOUND, no email is sent, butNOT_FOUNDis written to the sheet. On the next successful read you'll get a change email showingWas: NOT_FOUND— which effectively doubles as a "the page broke and recovered" notification. - The unchanged branch also rewrites the sheet with the same value. Harmless, and it keeps the update logic to a single node.
The result: zero emails on quiet days. The alert channel stays high-signal, which is the entire point of a competitor monitoring agent — if it cried wolf daily, you'd filter it to a folder and be back to manually refreshing pricing pages.
DIY vs the $29 tool — the honest comparison
First, the honest part: Competitor Watch is paid. It's $29, one-time — not a subscription — and it needs no scraping or monitoring service API. You do bring your own connections: a Google account for Sheets/Gmail and an OpenAI API key for the extraction step (gpt-4o-mini, which costs pennies per month at daily volume).
And you genuinely can build a simpler version yourself with n8n's free core nodes. The DIY shape:
- Schedule Trigger — daily, pick an hour (the node supports seconds/minutes/hours/days/weeks/months or a cron expression).
- HTTP Request — fetch the competitor page as text.
- Code node (JavaScript or Python) — strip the HTML, hash the text (or slice out a region), and compare it against the previous value stored with
$getWorkflowStaticData('global'). - If node — string "is not equal to" comparison → email node on the true branch.
That works, and if you only watch one page and don't mind noise, build it — grab ideas from our free n8n templates while you're at it. Here's the honest trade-off table:
| DIY (free core nodes) | Competitor Watch ($29 one-time) | |
|---|---|---|
| Build time | 1–3 hours incl. debugging | ~8 min setup (playbook inside the workflow) |
| What's compared | Page hash / raw text region | One AI-extracted value per page ("the Pro plan price") |
| False positives | High — hashes change on nonces, timestamps, cookie banners | Low — semantic value diff, NOT_FOUND guard |
| Memory | Workflow static data (invisible, lost on copy) or your own Sheet wiring | Google Sheet you can open, audit, and edit |
| Multi-competitor | You wire the loop yourself | Add a row to the sheet |
| Layout changes | Break your selector/hash silently | AI re-finds the value in changed markup (within limits — see below) |
| Extra services | None | None — no scraping API; BYO OpenAI key + Google account |
| Cost | $0 + your hours | $29 once + LLM pennies |
If your hourly rate is above ~$15, the math is short. If you'd rather not touch n8n at all, have us build it for you.
What breaks — and how to think about it before it does
No website change monitor is bulletproof, n8n or otherwise. Known failure modes, honestly stated:
- JS-rendered pages. The HTTP Request node fetches raw HTML. If the price is injected client-side by JavaScript (common on React/Vue pricing pages), the fetched text won't contain it and the AI will correctly return
NOT_FOUND. Fixes: point the watch at a server-rendered URL, or swap the fetch step for a rendering service — which breaks the "no extra API" property, so treat it as a per-page exception. - Bot blocks. Cloudflare challenges and aggressive WAFs can serve the workflow a challenge page instead of content. A daily single request from one IP usually passes, but some sites will block it. Symptom: persistent
NOT_FOUNDfor a page that looks fine in your browser. - Layout changes. AI extraction is far more resilient than a CSS selector — it reads text, not DOM paths — but a full pricing-page redesign (e.g., prices moved into images, or split across a toggle) can still defeat it. The
NOT_FOUNDwrite-through means you'll notice: the next good read emails you aWas: NOT_FOUNDrecovery alert. - False-positive diffs. Exact string comparison means
$59/movs$59 / monthcounts as a change if the site rephrases. The one-value prompt keeps this rare, and a vagueWatch Formakes it worse — "the Starter plan price" beats "the pricing" every time. Be specific and this mostly disappears. - Checking too often. Resist cranking the Schedule Trigger to hourly. Competitor prices change monthly, not hourly; hourly checks multiply LLM spend, look bot-like to WAFs, and buy you nothing. Daily at 8:00 is the shipped default for a reason.
What we verified in the workflow file
We don't describe workflows we haven't opened. For this post we read the actual workflowstacks-competitor-watch.n8n.json shipped in the bundle and confirmed:
- 9 nodes total, including the setup sticky note; execution order v1.
- Exact node names/types:
Every day 8:00(scheduleTrigger 1.2),Get watch list(googleSheets 4.5),Fetch the page(httpRequest 4.2),Read the value (AI)(langchain openAi 1.8, gpt-4o-mini),Shape the check(set 3.4),Did it change?(if 2.2),Email the change(gmail 2.1),Update Last Value(googleSheets 4.5, update op matched on URL). - The diff logic: two AND-ed conditions —
Last Value ≠ Old ValueandLast Value ≠ NOT_FOUND— so parse failures never trigger alerts. - The connection graph: true branch → Gmail → sheet update; false branch → sheet update directly. Every run ends with the sheet current.
- The prompt: strips tags with a regex, collapses whitespace, truncates to 6,000 characters, demands a bare string, and defines
NOT_FOUNDas the exact failure token. - Against n8n's official docs (docs.n8n.io, checked 2026-08-27): Schedule Trigger's exact name and its
Trigger at Hourdaily option; the If node's string "is not equal to" operation; the Code node's JavaScript/Python support for the DIY route. - The commercial terms in the bundle registry: $29 one-time, no scraping-service API required, free updates included.
Use it today
If you've read this far, you already know which pages you'd watch — a rival's pricing page, their homepage headline, maybe their careers page. Setup is a four-column Google Sheet and about eight minutes of connecting credentials:
- Create a sheet tab
Watcheswith URL / Label / Watch For / Last Value (leave Last Value empty). - Import the workflow, connect Google Sheets, Gmail, and your OpenAI key.
- Put your email in the Gmail node's To field, activate, done. It runs daily at 8:00 and stays silent until something moves.
→ Get Competitor Watch — n8n monitor ($29, one-time). One-time payment, no subscription, no scraping API, free updates.
Prefer to build the DIY version first? Fair — start from our free n8n templates and upgrade when the false positives get old. And if competitor intel is one piece of a bigger reporting habit, pair it with the Rank Tracker bundle for weekly Google position emails and the weekly client report template — or see how agencies automate client reports end to end. The founders who win aren't the ones refreshing rivals' pages; they're the ones who found out first without looking.
Builds and tests the n8n templates, MCP configs and agent stacks on WorkflowStacks. Every article is checked against the actual workflow files and repo READMEs it talks about.