AutomationFlowsSlack & Telegram › Monitor Brand Mentions and Route Slack Alerts with Groq and Google News

Monitor Brand Mentions and Route Slack Alerts with Groq and Google News

ByChijioke Ogbonna @cjaey5 on n8n.io

This workflow runs every 15 minutes to monitor Google News (and optionally Reddit/Trustpilot) for brand mentions, deduplicates stories, uses Groq to classify sentiment/intent/severity, sends high-severity alerts to Slack with a suggested reply draft, and logs all results to…

Cron / scheduled trigger★★★★☆ complexity23 nodesRSS Feed ReadHTTP RequestSlackGoogle Sheets
Slack & Telegram Trigger: Cron / scheduled Nodes: 23 Complexity: ★★★★☆ Added:

This workflow corresponds to n8n.io template #17929 — we link there as the canonical source.

This workflow follows the Google Sheets → HTTP Request recipe pattern — see all workflows that pair these two integrations.

The workflow JSON

Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →

Download .json
{
  "id": "UfZSeAXANOavvow3",
  "name": "Brand Monitor Template (Groq + Multi-Source-Ready + Severity Routing + Error Monitoring)",
  "tags": [],
  "nodes": [
    {
      "id": "b5afadd6-80ba-4ad1-b6d5-fdae8bcc3213",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        688,
        -144
      ],
      "parameters": {
        "width": 480,
        "height": 896,
        "content": "## Brand Monitor Template (Groq + Multi-Source-Ready + Severity Routing + Error Monitoring)\n\n### How it works\n\n1. The workflow is triggered every 15 minutes.\n2. It fetches data from Google News RSS and Reddit Search.\n3. The data is then normalized and merged.\n4. The workflow classifies the sentiment and intent of the data using Groq.\n5. Based on the severity, it either logs everything or sends a high severity alert to Slack.\n\n### Setup steps\n\n- - [ ] Set up Google News RSS feed\n- - [ ] Configure Reddit Search\n- - [ ] Set up Groq API\n- - [ ] Configure Slack for high severity alerts\n- - [ ] Set up Google Sheets for logging\n\n### Customization\n\nYou can customize the workflow by adding more data sources, modifying the normalization and merging process, and adjusting the severity thresholds."
      },
      "typeVersion": 1
    },
    {
      "id": "66b6a445-3b05-4a7f-b6ab-b6dbdbad2f0d",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1248,
        -80
      ],
      "parameters": {
        "color": 7,
        "width": 416,
        "height": 736,
        "content": "## Trigger and Data Fetch\n\nThis group contains the trigger node and the nodes responsible for fetching data from Google News RSS and Reddit Search."
      },
      "typeVersion": 1
    },
    {
      "id": "9d6a9c12-7a8c-4c89-81bf-c8d04c2b7e77",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1696,
        -144
      ],
      "parameters": {
        "color": 7,
        "height": 640,
        "content": "## Data Normalization\n\nThis group contains the nodes responsible for normalizing the data from Google News RSS and Reddit Search."
      },
      "typeVersion": 1
    },
    {
      "id": "9067ac9e-dc91-401e-a04c-0acf15f17a4d",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1984,
        128
      ],
      "parameters": {
        "color": 7,
        "height": 320,
        "content": "## Data Merging\n\nThis group contains the node responsible for merging the normalized data."
      },
      "typeVersion": 1
    },
    {
      "id": "3a47132c-fb4f-4c6d-a265-e8b6447dd512",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2256,
        16
      ],
      "parameters": {
        "color": 7,
        "width": 848,
        "height": 320,
        "content": "## Sentiment and Intent Classification\n\nThis group contains the nodes responsible for classifying the sentiment and intent of the data using Groq."
      },
      "typeVersion": 1
    },
    {
      "id": "76d999aa-9b4b-44ca-a6a8-5bb5def0be5a",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        3136,
        -112
      ],
      "parameters": {
        "color": 7,
        "width": 624,
        "height": 432,
        "content": "## Severity Based Alerting\n\nThis group contains the nodes responsible for sending high severity alerts to Slack."
      },
      "typeVersion": 1
    },
    {
      "id": "8bf58afc-91ae-42d9-8020-057061164a7e",
      "name": "Sticky Note6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2496,
        368
      ],
      "parameters": {
        "color": 7,
        "width": 1360,
        "height": 576,
        "content": "## Logging and Error Handling\n\nThis group contains the nodes responsible for logging everything and handling errors."
      },
      "typeVersion": 1
    },
    {
      "id": "1f1f25a9-0696-48b0-ad52-6f360410966f",
      "name": "Run Every 15min",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        1296,
        224
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "minutes",
              "minutesInterval": 15
            }
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "f02c6fe9-aaf1-4d7c-ab10-b8ec4a46394e",
      "name": "Fetch News RSS",
      "type": "n8n-nodes-base.rssFeedRead",
      "onError": "continueErrorOutput",
      "maxTries": 3,
      "position": [
        1520,
        80
      ],
      "parameters": {
        "url": "https://news.google.com/rss/search?q=%22Loubby+AI%22+OR+%22Loubby.ai%22&hl=en-US&gl=US&ceid=US:en",
        "options": {}
      },
      "retryOnFail": true,
      "typeVersion": 1.1,
      "waitBetweenTries": 5000
    },
    {
      "id": "61990070-636c-4c83-9522-0265c50e0e2f",
      "name": "Search Reddit",
      "type": "n8n-nodes-base.httpRequest",
      "notes": "Disabled by default - low mention volume for niche B2B use cases and Reddit blocks unauthenticated requests. Enable + add OAuth2 credential (register a 'script' app at reddit.com/prefs/apps) to use. After enabling, reconnect its output through Normalize Reddit Items -> a Merge node -> Dedupe/Cluster.",
      "disabled": true,
      "position": [
        1520,
        240
      ],
      "parameters": {
        "url": "https://www.reddit.com/search.json",
        "options": {},
        "sendQuery": true,
        "sendHeaders": true,
        "queryParameters": {
          "parameters": [
            {
              "name": "q",
              "value": "Loubby AI"
            },
            {
              "name": "sort",
              "value": "new"
            },
            {
              "name": "limit",
              "value": "25"
            }
          ]
        },
        "headerParameters": {
          "parameters": [
            {
              "name": "User-Agent",
              "value": "n8n-brand-monitor/1.0"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "a48b1fd8-ab5f-4982-ac66-1168c5618020",
      "name": "Get Trustpilot",
      "type": "n8n-nodes-base.httpRequest",
      "notes": "Disabled - no free Trustpilot/G2 API exists. Requires a paid Trustpilot Business API key or G2 partnership feed. Enable and wire through a Merge node into Dedupe/Cluster once you have credentials.",
      "disabled": true,
      "position": [
        1520,
        496
      ],
      "parameters": {
        "url": "https://api.trustpilot.example/PLACEHOLDER-NEEDS-PAID-API-KEY",
        "options": {}
      },
      "typeVersion": 4.2
    },
    {
      "id": "dc989459-9085-4de2-9a43-33c8e67f64a0",
      "name": "Normalize News",
      "type": "n8n-nodes-base.code",
      "position": [
        1776,
        64
      ],
      "parameters": {
        "jsCode": "return $input.all().map(i => ({\n  json: {\n    title: i.json.title || 'Untitled',\n    link: i.json.link || '',\n    snippet: i.json.contentSnippet || '',\n    pubDate: i.json.pubDate || new Date().toISOString(),\n    source: 'google_news',\n    engagementScore: 0\n  }\n}));"
      },
      "typeVersion": 2
    },
    {
      "id": "453a7a7f-f1a4-41b9-9867-9ed2fd18729f",
      "name": "Normalize Reddit",
      "type": "n8n-nodes-base.code",
      "disabled": true,
      "position": [
        1744,
        336
      ],
      "parameters": {
        "jsCode": "// Normalize Reddit items\nconst posts = $input.first().json.data?.children || [];\nreturn posts.map(p => ({\n  json: {\n    title: p.data.title,\n    link: 'https://www.reddit.com' + p.data.permalink,\n    snippet: (p.data.selftext || '').slice(0, 400),\n    pubDate: new Date(p.data.created_utc * 1000).toISOString(),\n    source: 'reddit',\n    engagementScore: (p.data.score || 0) + (p.data.num_comments || 0)\n  }\n}));"
      },
      "typeVersion": 2
    },
    {
      "id": "68c86558-580d-4d81-90b7-22cff0f7bc8f",
      "name": "Merge Sources",
      "type": "n8n-nodes-base.merge",
      "notes": "Currently bypassed since only Google News is active. Reconnect this node between your sources and Dedupe/Cluster if you enable Reddit and/or Trustpilot.",
      "position": [
        2032,
        288
      ],
      "parameters": {
        "mode": "combine",
        "options": {},
        "combineBy": "combineAll"
      },
      "typeVersion": 3.1
    },
    {
      "id": "ad7cb8a6-af07-4f37-9262-822cbbb2b4f1",
      "name": "Dedupe Stories",
      "type": "n8n-nodes-base.code",
      "position": [
        2304,
        160
      ],
      "parameters": {
        "jsCode": "// De-duplicate / cluster near-identical stories by normalized title similarity\nconst items = $input.all().map(i => i.json);\n\nfunction normalize(s) {\n  return (s || '').toLowerCase().replace(/[^a-z0-9 ]/g, '').split(/\\s+/).filter(Boolean);\n}\n\nfunction jaccard(a, b) {\n  const setA = new Set(a);\n  const setB = new Set(b);\n  const intersection = [...setA].filter(x => setB.has(x)).length;\n  const union = new Set([...setA, ...setB]).size;\n  return union === 0 ? 0 : intersection / union;\n}\n\nconst SIMILARITY_THRESHOLD = 0.6; // tune this - not a verified industry-standard value, just a starting point\nconst kept = [];\n\nfor (const item of items) {\n  const tokens = normalize(item.title);\n  const isDupe = kept.some(k => jaccard(tokens, normalize(k.title)) >= SIMILARITY_THRESHOLD);\n  if (!isDupe) kept.push(item);\n}\n\nreturn kept.map(k => ({ json: k }));"
      },
      "typeVersion": 2
    },
    {
      "id": "7f87c6a2-3b3c-43db-937a-d09cc9846596",
      "name": "Classify Sentiment",
      "type": "n8n-nodes-base.httpRequest",
      "onError": "continueErrorOutput",
      "maxTries": 3,
      "position": [
        2688,
        160
      ],
      "parameters": {
        "url": "https://api.groq.com/openai/v1/chat/completions",
        "method": "POST",
        "options": {},
        "jsonBody": "={{ JSON.stringify({ model: \"llama-3.3-70b-versatile\", messages: [ { role: \"system\", content: \"You monitor brand mentions for Loubby AI, a Workforce OS company offering AI recruiting (Jabari), AI interviewing (Dara), autonomous AI agents (Autonoms AI), payroll and talent management for global/African remote teams. Competitors include Deel, Remote.com, Rippling, and Papaya Global. Classify the mention and respond ONLY with valid JSON, no markdown: {\\\"sentiment\\\":\\\"positive|neutral|negative\\\",\\\"intent\\\":\\\"complaint|competitor_comparison|viral_moment|pr_risk|praise|unrelated\\\",\\\"severity\\\":\\\"high|medium|low\\\",\\\"reason\\\":\\\"short phrase explaining severity and intent\\\"}. Severity should weigh both the sentiment/intent AND the provided engagement_score (higher engagement = higher potential severity for negative content).\" }, { role: \"user\", content: JSON.stringify({ title: $json.title, snippet: $json.snippet, source: $json.source, engagement_score: $json.engagementScore }) } ], temperature: 0 }) }}",
        "sendBody": true,
        "specifyBody": "json",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth"
      },
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      },
      "retryOnFail": true,
      "typeVersion": 4.2,
      "waitBetweenTries": 5000
    },
    {
      "id": "a9b60ccb-aeba-4a9c-a887-4336b8ba1722",
      "name": "Parse Response",
      "type": "n8n-nodes-base.code",
      "position": [
        2960,
        144
      ],
      "parameters": {
        "mode": "runOnceForEachItem",
        "jsCode": "const raw = $input.item.json.choices[0].message.content;\nlet parsed;\ntry {\n  parsed = JSON.parse(raw);\n} catch (e) {\n  parsed = { sentiment: 'neutral', intent: 'unrelated', severity: 'low', reason: 'parse_error - verify Groq output format' };\n}\nreturn {\n  json: {\n    title: $('Dedupe Stories').item.json.title,\n    link: $('Dedupe Stories').item.json.link,\n    snippet: $('Dedupe Stories').item.json.snippet,\n    source: $('Dedupe Stories').item.json.source,\n    pubDate: $('Dedupe Stories').item.json.pubDate,\n    sentiment: parsed.sentiment,\n    intent: parsed.intent,\n    severity: parsed.severity,\n    reason: parsed.reason\n  }\n};"
      },
      "typeVersion": 2
    },
    {
      "id": "bf90f137-08c2-436a-9984-eae43b00b117",
      "name": "Check Severity",
      "type": "n8n-nodes-base.if",
      "position": [
        3184,
        144
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "29b1468f-a3af-4c38-ae3d-f7358ae13178",
              "operator": {
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $json.severity }}",
              "rightValue": "high"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "85a2f6d2-9a87-4aea-82c4-0063530e9571",
      "name": "Draft Response",
      "type": "n8n-nodes-base.httpRequest",
      "onError": "continueErrorOutput",
      "maxTries": 3,
      "position": [
        3392,
        32
      ],
      "parameters": {
        "url": "https://api.groq.com/openai/v1/chat/completions",
        "method": "POST",
        "options": {},
        "jsonBody": "={{ JSON.stringify({ model: \"llama-3.3-70b-versatile\", messages: [ { role: \"system\", content: \"Draft a short, professional public reply from Loubby AI's team addressing this mention. Tone: empathetic, non-defensive, offers to resolve offline. Max 3 sentences. Respond ONLY with the reply text, no JSON, no preamble.\" }, { role: \"user\", content: \"Title: \" + $json.title + \"\\nSnippet: \" + $json.snippet + \"\\nReason flagged: \" + $json.reason } ], temperature: 0.4 }) }}",
        "sendBody": true,
        "specifyBody": "json",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth"
      },
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      },
      "retryOnFail": true,
      "typeVersion": 4.2,
      "waitBetweenTries": 5000
    },
    {
      "id": "7867cddd-040c-4a8f-aa4d-176f709c851c",
      "name": "Send Alert",
      "type": "n8n-nodes-base.slack",
      "position": [
        3616,
        16
      ],
      "parameters": {
        "text": "=\ud83d\udea8 *HIGH SEVERITY* mention of Loubby AI\n\n*Title:* {{ $('Parse Response').item.json.title }}\n*Source:* {{ $('Parse Response').item.json.source }}\n*Intent:* {{ $('Parse Response').item.json.intent }}\n*Reason:* {{ $('Parse Response').item.json.reason }}\n*Link:* {{ $('Parse Response').item.json.link }}\n\n*Suggested reply (needs human approval before posting):*\n{{ $json.choices[0].message.content }}",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "list",
          "value": "C0ATQN2T51T",
          "cachedResultName": "all-soclear-consult"
        },
        "otherOptions": {}
      },
      "credentials": {
        "slackApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "cec1fa23-7cba-4ba9-bb17-3138abd42eb2",
      "name": "Log To Sheets",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        3712,
        480
      ],
      "parameters": {
        "columns": {
          "value": {},
          "schema": [],
          "mappingMode": "autoMapInputData",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "value": "Sheet1"
        },
        "documentId": {
          "value": "YOUR_GOOGLE_SHEET_ID"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.5
    },
    {
      "id": "22c27dc0-2ce7-4568-bfe1-2de830c53b19",
      "name": "Format Errors",
      "type": "n8n-nodes-base.code",
      "position": [
        2544,
        784
      ],
      "parameters": {
        "mode": "runOnceForEachItem",
        "jsCode": "return {\n  json: {\n    node: $prevNode.name,\n    error: $json.error?.message || $json.message || 'Unknown error',\n    timestamp: new Date().toISOString()\n  }\n};"
      },
      "typeVersion": 2
    },
    {
      "id": "64d761bc-25bb-40a0-a6ba-6338fc51cdc8",
      "name": "Report Errors",
      "type": "n8n-nodes-base.slack",
      "notes": "Set channelId to a separate #automation-errors channel (not your brand-alerts channel).",
      "position": [
        2848,
        784
      ],
      "parameters": {
        "text": "=\u26a0\ufe0f Automation error\\n*Node:* {{ $json.node }}\\n*Error:* {{ $json.error }}\\n*Time:* {{ $json.timestamp }}",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "list",
          "value": "C0B0VR1LN3B",
          "cachedResultName": "anomally-alerts"
        },
        "otherOptions": {}
      },
      "credentials": {
        "slackApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.3
    }
  ],
  "active": false,
  "settings": {
    "binaryMode": "separate",
    "executionOrder": "v1"
  },
  "versionId": "6de828e3-765b-4358-be2a-5cda105aaae3",
  "nodeGroups": [],
  "connections": {
    "Send Alert": {
      "main": [
        [
          {
            "node": "Log To Sheets",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Format Errors": {
      "main": [
        [
          {
            "node": "Report Errors",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check Severity": {
      "main": [
        [
          {
            "node": "Draft Response",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Log To Sheets",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Dedupe Stories": {
      "main": [
        [
          {
            "node": "Classify Sentiment",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Draft Response": {
      "main": [
        [
          {
            "node": "Send Alert",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Format Errors",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch News RSS": {
      "main": [
        [
          {
            "node": "Normalize News",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Format Errors",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Normalize News": {
      "main": [
        [
          {
            "node": "Dedupe Stories",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse Response": {
      "main": [
        [
          {
            "node": "Check Severity",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Run Every 15min": {
      "main": [
        [
          {
            "node": "Fetch News RSS",
            "type": "main",
            "index": 0
          },
          {
            "node": "Search Reddit",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Classify Sentiment": {
      "main": [
        [
          {
            "node": "Parse Response",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Format Errors",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}

Credentials you'll need

Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.

Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

This workflow runs every 15 minutes to monitor Google News (and optionally Reddit/Trustpilot) for brand mentions, deduplicates stories, uses Groq to classify sentiment/intent/severity, sends high-severity alerts to Slack with a suggested reply draft, and logs all results to…

Source: https://n8n.io/workflows/17929/ — original creator credit. Request a take-down →

More Slack & Telegram workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

Slack & Telegram

This workflow continuously monitors the Meta Ads Library for new creatives from a specific competitor pages, logs them into Google Sheets, and sends a concise Telegram notification with the number of

HTTP Request, Telegram, Google Sheets +1
Slack & Telegram

Enhance financial oversight with this automated n8n workflow. Triggered every 5 minutes, it fetches real-time bank transactions via an API, enriches and transforms the data, and applies smart logic to

HTTP Request, Email Send, Google Sheets +1
Slack & Telegram

This workflow automates competitive price intelligence using Bright Data's enterprise web scraping API. On a scheduled basis (default: daily at 9 AM), the system loops through configured competitor pr

HTTP Request, Google Sheets, Slack +1
Slack & Telegram

&gt; n8n, Binance API, Google Sheets, Slack, Telegram, Jira & Email

HTTP Request, Google Sheets, Slack +3
Slack & Telegram

SEO managers, content marketers, bloggers, and growth teams who want to automatically catch declining content performance before it's too late — without manually checking Google Search Console every w

HTTP Request, Google Sheets, Slack +1