4 min

2 h

Building a Multi-Source Competitive Intelligence Pipeline with Trustpilot, LinkedIn, and the Web

For Signar, I built an n8n pipeline that monitors a sales team’s competitors on Trustpilot, LinkedIn and their websites, then turns that public data into scored sales signals. The goal: save two hours of manual searching per week. The lesson: finding data is easy, making it useful is not.

The problem

Competitive intelligence in sales is manual, sporadic and hard to track. When a competitor goes on a hiring spree or piles up negative reviews about its support, the signal is public, but you have to catch it in time and decide whether it deserves action.

Existing tools (Google alerts, social listening, market intelligence) are too generic, closed, expensive beyond 20 monitored companies, and noisy. I wanted to control the sources, the filtering, the output format and where the AI fits in.

What I built

One loop per competitor: collection from three sources, cleaning, assembly of a structured context, AI analysis, deduplication, storage in Supabase, then prioritization.

Overview of the n8n workflow, multi-source competitive intelligence pipeline

n8n orchestrates, it doesn’t process: the business logic lives in the transformation nodes, the HTTP calls and the prompt.

The three sources:

Source What it brings Difficulty Noise
Trustpilot Direct customer pain (support, pricing, onboarding) Medium Medium
LinkedIn Moves: partnerships, hiring, launches High Very high
Website Official messaging and how it changes (pricing, offer, target) Medium Medium

Technical choices:

  • Supabase stores the competitor list and the signals (source, type, severity, confidence, sales angle, recommended action, hash, dates).
  • OpenRouter gives access to several models: Claude for reasoning, GPT-4o-mini for high-volume classification.
  • Apify for LinkedIn: a paid dependency, but cheaper than maintaining a scraper against anti-bot protections, for a weekly crawl.
  • Native n8n HTTP for Trustpilot and the web, with a JavaScript rendering fallback only when the page looks empty, as in the Scrapy technology detection project.

A few steps that matter:

  1. Domain normalization at the start of the loop. A badly handled www or https breaks HTTP calls further down: better to reject the entry early.
  2. LinkedIn filter before the AI. I drop internal congratulations, employer branding, shares with no added content and event posts. I keep launches, targeted hiring, partnerships and leadership changes.
  3. Standard paths for the web (/blog, /news, /ressources, /changelog…), tried in order until readable content shows up.
  4. Systematic cleaning: tags, scripts, navigation, footer, duplicates, encodings, truncation beyond a token threshold.
  5. Context in separate blocks (Trustpilot, LinkedIn, website, client profile) and strict JSON output. The model mixes up sources less.
  6. Anti-duplicate hash on domain, source, signal type and the first 200 characters of content. Without it, the same three-month-old review comes back on every crawl.
  7. Urgency score severity × confidence: above 0.6, a Teams or Slack notification, otherwise the weekly review.

Each signal comes out with a sales angle (“highlight support quality”) and a recommended action (“prepare a demo focused on support”), ready to use in a CRM or a summary email.

Trustpilot HTTP node configuration in n8n, GET request filtered on 1-3 star reviews from the last 30 days

What broke

Trusting the AI too much. My first version sent raw HTML to the model and asked it to “find the interesting signals.” The result was unpredictable, expensive and often useless.

The model is only as good as what you feed it

The same prompt gives a confused answer on raw HTML and a usable output on a clean context. Upstream cleaning is the real lever.

LinkedIn noise. Out of 100 posts collected for one company, I sometimes kept 3 or 4. The pattern-based pre-AI filter cut costs and sped up processing.

JavaScript sites. One competitor had a /blog page that only returned a JS shell. The model dutifully analyzed “Loading… Please enable JavaScript.” as editorial content. The Playwright fallback fixes it, but slows this branch down noticeably.

The bloated workflow. After a few weeks, more than 60 nodes. I split it: one main workflow for the loop, one sub-workflow per source, each testable on its own.

Too many signals. Some versions surfaced 40 signals per week per company. Nobody read them. Keeping the 3 to 5 truly useful ones changed adoption.

What worked

Cross-referencing sources. One observed case: Trustpilot complaints about support response time over 30 days, Customer Success and Support openings on LinkedIn, and a “How we’re improving our customer support” article on the website. Separately, it’s anecdotal. Together, it’s a company under operational strain, and an angle worth passing to a salesperson.

Repeated signals beat spectacular ones: the same complaint 8 times in 3 weeks is a pattern, which the pipeline aggregates.

Indicative breakdown of usable signals: Trustpilot 42%, website 35%, LinkedIn 23%.

Limits and what I’d do differently

Scoring is still heuristic (thresholds tuned by hand), LinkedIn depends on an Apify actor, Trustpilot yields nothing under 10 reviews, and there’s no trend history and no human validation loop.

I’d change three things: define the signal schema before the first prompt (every change touched the prompt, parsing, table and display), structure the workflows as sub-workflows from the start instead of piling up v2_final_corrigé.json files, and build a fixed test set of companies with known signals to measure every change.

Key takeaways

Public data is abundant; the value comes from sorting it. AI classifies, summarizes and adds context, but only after collection, cleaning and structuring. A salesperson doesn’t want to read data: they want to know why to act now and what to say.

Read next

4AI Detection of Business Signals: Building a Useful RevOps SystemAlgoliaDetecting Company Expansion Signals with WTTJ, LinkedIn, and n8n40The SDR Lead Machine