AutomationFlowsAI & RAG › Track Daily Brand Mentions From Hacker News to Slack with Gpt-4o-mini…

Track Daily Brand Mentions From Hacker News to Slack with Gpt-4o-mini…

Original n8n title: Track Daily Brand Mentions From Hacker News to Slack with Gpt-4o-mini Sentiment Analysis

ByRahul Joshi @rahul08 on n8n.io

Monitor daily brand visibility and reputation with an automated AI-powered mention tracker. 🔍🤖 This workflow checks Hacker News every morning for new stories matching your brand keyword, classifies each mention’s sentiment and urgency using GPT-4o-mini, and delivers a clean…

Cron / scheduled trigger★★★★☆ complexityAI-powered25 nodesHTTP RequestSlackOpenAI ChatMemory Buffer WindowOutput Parser StructuredAgentError Trigger
AI & RAG Trigger: Cron / scheduled Nodes: 25 Complexity: ★★★★☆ AI nodes: yes Added:

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

This workflow follows the Agent → Error Trigger 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": "Sler1Jv8uyaDt7cZ",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "Track daily brand mentions from Hacker News to Slack with AI sentiment analysis",
  "tags": [],
  "nodes": [
    {
      "id": "2a7612de-ca5d-4f4d-b0d2-8cd75ab96323",
      "name": "Every Day at 09:00",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        -1312,
        464
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "cronExpression",
              "expression": "0 9 * * *"
            }
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "f0061436-e3cf-4516-abbf-35c3e6413505",
      "name": "Brand Config",
      "type": "n8n-nodes-base.set",
      "position": [
        -1088,
        464
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "brand-field",
              "name": "brand",
              "type": "string",
              "value": "OpenAI"
            },
            {
              "id": "keywords-field",
              "name": "keywords",
              "type": "string",
              "value": "OpenAI"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "81966f20-5f1c-4e58-b9b2-8cc6f7726a3a",
      "name": "Fetch Reddit Mentions",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -864,
        464
      ],
      "parameters": {
        "url": "=http://hn.algolia.com/api/v1/search?query={{$json[\"keywords\"]}}&tags=story",
        "options": {},
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "User-Agent",
              "value": "n8n-monitor-bot"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "0e9f423c-3298-4524-a5cf-7a6d799a3d87",
      "name": "Normalize Mentions",
      "type": "n8n-nodes-base.code",
      "position": [
        -640,
        464
      ],
      "parameters": {
        "jsCode": "const items = $input.all();\nconst brand = $('Brand Config').first().json.brand\n\nconst normalized = [];\n\nitems.forEach(item => {\n  const hits = item.json.hits || [];\n  \n  hits.forEach(hit => {\n    normalized.push({\n      platform: 'Hacker News',\n      title: hit.title || '',\n      url: hit.url || `https://news.ycombinator.com/item?id=${hit.objectID}`,\n      snippet: hit.story_text || hit.title || '',\n      author: hit.author || 'unknown',\n      created_at: hit.created_at || new Date(hit.created_at_i * 1000).toISOString(),\n      brand: brand,\n      points: hit.points || 0,\n      num_comments: hit.num_comments || 0\n    });\n  });\n});\n\nreturn normalized.map(item => ({ json: item }));"
      },
      "typeVersion": 2
    },
    {
      "id": "cd01b4a3-fc61-43fb-8d32-b78ccaadd62f",
      "name": "Mentions Exist?",
      "type": "n8n-nodes-base.if",
      "position": [
        -192,
        464
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 1,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "mention-exists",
              "operator": {
                "type": "number",
                "operation": "gt"
              },
              "leftValue": "={{ $items().length }}",
              "rightValue": 0
            }
          ]
        }
      },
      "typeVersion": 2
    },
    {
      "id": "bbb9eddd-8d0f-48d1-b5a8-f794e1462f7c",
      "name": "Build Daily Summary",
      "type": "n8n-nodes-base.code",
      "position": [
        720,
        320
      ],
      "parameters": {
        "jsCode": "const items = $input.all();\nconst brand = items[0]?.json.brand || 'VivekLabs';\n\nconst totalMentions = items.length;\nconst sentimentCounts = {\n  positive: 0,\n  negative: 0,\n  neutral: 0\n};\n\nitems.forEach(item => {\n  const sentiment = item.json.sentiment || 'neutral';\n  if (sentimentCounts[sentiment] !== undefined) {\n    sentimentCounts[sentiment]++;\n  }\n});\n\nconst top10 = items.slice(0, 10);\n\nlet reportText = `*Daily Brand Mentions Report for ${brand}*\\n\\n`;\nreportText += `\ud83d\udcca *Total Mentions:* ${totalMentions}\\n`;\nreportText += `\u2705 Positive: ${sentimentCounts.positive}\\n`;\nreportText += `\u274c Negative: ${sentimentCounts.negative}\\n`;\nreportText += `\u26aa Neutral: ${sentimentCounts.neutral}\\n\\n`;\nreportText += `*Top Mentions:*\\n`;\n\ntop10.forEach((item, index) => {\n  const data = item.json;\n  const emoji = data.sentiment === 'positive' ? '\u2705' : data.sentiment === 'negative' ? '\u274c' : '\u26aa';\n  const title = data.title || 'No title';\n  const platform = data.platform || 'Hackers Info';\n  const topic = data.topic || 'other';\n  const urgency = data.urgency || 'low';\n  const url = data.url || '';\n  \n  reportText += `${index + 1}. ${emoji} *${title}*\\n`;\n  reportText += `   Platform: ${platform} | Topic: ${topic} | Urgency: ${urgency}\\n`;\n  reportText += `   ${url}\\n\\n`;\n});\n\nreturn [{ json: { text: reportText } }];"
      },
      "typeVersion": 2
    },
    {
      "id": "bfea6659-b7e3-4adf-b01c-72062f040af5",
      "name": "Send Daily Report to Slack",
      "type": "n8n-nodes-base.slack",
      "position": [
        944,
        320
      ],
      "parameters": {
        "text": "={{$json[\"text\"]}}",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "id",
          "value": "="
        },
        "otherOptions": {}
      },
      "credentials": {
        "slackApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "6207ae42-847f-4f24-8497-4adddf98d690",
      "name": "No Mentions Message",
      "type": "n8n-nodes-base.set",
      "position": [
        160,
        608
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "no-mentions-text",
              "name": "text",
              "type": "string",
              "value": "=No new AI engine mentions were found today for {{$node[\"Brand Config\"].json[\"brand\"]}}."
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "bcad6160-5453-456d-b264-fc991c42b7ac",
      "name": "Send No Mentions to Slack",
      "type": "n8n-nodes-base.slack",
      "position": [
        496,
        608
      ],
      "parameters": {
        "text": "={{$json[\"text\"]}}",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "id",
          "value": "="
        },
        "otherOptions": {}
      },
      "credentials": {
        "slackApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "8ce97211-b4e1-4e1d-9e15-fd6ebd320247",
      "name": "Checking Score",
      "type": "n8n-nodes-base.if",
      "position": [
        -416,
        464
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 1,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "mention-exists",
              "operator": {
                "type": "number",
                "operation": "gt"
              },
              "leftValue": "={{ $json.num_comments }}",
              "rightValue": 1000
            }
          ]
        }
      },
      "typeVersion": 2
    },
    {
      "id": "def75b6a-d57f-44f2-8a1c-64d0552e6baa",
      "name": "OpenAI Chat Model - GPT-4o-mini",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        32,
        432
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4o-mini",
          "cachedResultName": "gpt-4o-mini"
        },
        "options": {}
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "b49bd7bc-b0ed-4bb2-a495-3eb9dbd83428",
      "name": "Memory - Conversation Buffer",
      "type": "@n8n/n8n-nodes-langchain.memoryBufferWindow",
      "position": [
        160,
        432
      ],
      "parameters": {
        "sessionKey": "\"GEO Classify\"",
        "sessionIdType": "customKey"
      },
      "typeVersion": 1.3
    },
    {
      "id": "6b4a610e-a656-45a3-87e5-9d564efc88f2",
      "name": "Output Parser - Structured JSON",
      "type": "@n8n/n8n-nodes-langchain.outputParserStructured",
      "position": [
        288,
        432
      ],
      "parameters": {
        "jsonSchemaExample": "{\n  \"sentiment\": \"positive | negative | neutral\",\n  \"stance\": \"supports | criticizes | questioning | just mentioning\",\n  \"topic\": \"pricing | quality | support | features | bugs | performance | general | other\",\n  \"urgency\": \"low | medium | high\",\n  \"reason\": \"short explanation string\"\n}"
      },
      "typeVersion": 1.3
    },
    {
      "id": "9428daf8-21da-47cc-9d7d-88c05404ad20",
      "name": "AI Agent - Classify Mention Sentiments",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        96,
        208
      ],
      "parameters": {
        "text": "=Brand: {{$json[\"brand\"]}}\nPlatform: {{$json[\"platform\"]}}\nTitle: {{$json[\"title\"]}}\nSnippet: {{$json[\"snippet\"]}}\n\nDetermine how this mention talks about the brand.\n",
        "options": {
          "systemMessage": "=You are a brand reputation analyst.\n\nClassify each mention of the brand by:\n- sentiment: positive, negative, or neutral\n- stance: supports, criticizes, questioning, or just mentioning\n- topic: one of [pricing, quality, support, features, bugs, performance, general, other]\n- urgency: low, medium, or high.\n\nYou MUST respond with STRICT JSON only, no markdown, like:\n{\n  \"sentiment\": \"positive | negative | neutral\",\n  \"stance\": \"supports | criticizes | questioning | just mentioning\",\n  \"topic\": \"pricing | quality | support | features | bugs | performance | general | other\",\n  \"urgency\": \"low | medium | high\",\n  \"reason\": \"short explanation string\"\n}\n"
        },
        "promptType": "define",
        "hasOutputParser": true
      },
      "typeVersion": 2.1
    },
    {
      "id": "485ed40a-9751-4ba2-aad7-28b8f9f8f6af",
      "name": "Format Sentiment Data",
      "type": "n8n-nodes-base.set",
      "position": [
        496,
        320
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "8e26c379-a8fa-4b5e-9d9b-a12f22686645",
              "name": "sentiment",
              "type": "string",
              "value": "={{ $json.output.sentiment }}"
            },
            {
              "id": "d9267ace-ee8c-4662-aa08-b250c6556ffa",
              "name": "stance",
              "type": "string",
              "value": "={{ $json.output.stance }}"
            },
            {
              "id": "d916c361-c65f-4029-b466-ea7fe76ba5c5",
              "name": "topic",
              "type": "string",
              "value": "={{ $json.output.topic }}"
            },
            {
              "id": "b71b8175-4c7f-45fd-bb29-1ffc3c4b3436",
              "name": "urgency",
              "type": "string",
              "value": "={{ $json.output.urgency }}"
            },
            {
              "id": "7c9dcebe-a2a0-4529-bc0c-ad6cc788898d",
              "name": "reason",
              "type": "string",
              "value": "={{ $json.output.reason }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "cf1fb0da-f564-4230-8b8e-b4d811b04cc5",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1408,
        -384
      ],
      "parameters": {
        "width": 448,
        "height": 704,
        "content": "## Daily AI Engine Mentions Tracker \u2013 Overview\n\nThis workflow tracks daily online mentions of a selected brand and sends a summary to Slack. It checks Hacker News each morning, processes the results, analyzes sentiment and urgency with AI, and sends either a detailed report or a \u201cno mentions today\u201d message. This helps teams monitor brand reputation and identify issues early.\n\n### How it works\n1. A daily trigger runs at 09:00 and loads brand configuration.\n2. Mentions are fetched from Hacker News based on brand keywords.\n3. Mentions are normalized into a clean structure.\n4. AI classifies each mention\u2019s sentiment, stance, topic, and urgency.\n5. A daily summary is generated, showing total mentions and the top 10 items.\n6. Slack receives either a detailed report or a no-mentions message.\n\n### Setup steps\n- Set your brand name and keyword inside the \u201cBrand Config\u201d node.\n- Add Slack credentials and select the channel to send reports.\n- Add OpenAI credentials for GPT-4o-mini.\n- Run a sample execution to verify formatting.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "c71bebc3-69e1-4b2f-b3b5-9316e69d5f5a",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1392,
        352
      ],
      "parameters": {
        "color": 2,
        "width": 448,
        "height": 304,
        "content": "## Trigger & Brand Setup\nRuns daily at 09:00 and loads the brand name + keyword filters.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "0e11af5a-7d41-4fbc-bf13-1a974922145b",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -928,
        352
      ],
      "parameters": {
        "color": 2,
        "width": 224,
        "height": 304,
        "content": "## Fetch Mentions\nQueries Hacker News for new stories matching the brand keyword.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "4ee80f6b-2907-4068-9295-8f324a5865b9",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -688,
        320
      ],
      "parameters": {
        "color": 2,
        "width": 614,
        "height": 336,
        "content": "## Normalize Mentions\nConverts raw API results into a clean structure for AI classification.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "371de316-878a-48c4-a492-394605e7504b",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -16,
        112
      ],
      "parameters": {
        "color": 2,
        "width": 448,
        "height": 464,
        "content": "## AI Classification\nAI evaluates sentiment, stance, topic, and urgency for each mention.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "d15ba049-379e-4f68-a17c-51f614aee438",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        448,
        112
      ],
      "parameters": {
        "color": 2,
        "width": 400,
        "height": 464,
        "content": "## Format Sentiment Output and Summary\nMaps AI-generated sentiment fields into clean JSON for reporting.Builds a daily Slack-friendly summary including top trending mentions.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "84710f35-de7d-4b58-8c4b-5f043d4573a9",
      "name": "Sticky Note6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        864,
        112
      ],
      "parameters": {
        "color": 2,
        "height": 464,
        "content": "## Slack Notifications\nSends either a full daily report or a \u201cno mentions today\u201d message.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "fac8347b-4957-4dee-b866-4955bf268dd7",
      "name": "Error Handling",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1376,
        1040
      ],
      "parameters": {
        "color": 2,
        "width": 584,
        "height": 276,
        "content": "## Error Handling\nCaptures workflow failures and sends details to Slack for quick debugging.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "15ea6ce7-3a12-4b28-aa15-691fbc6e1f83",
      "name": "Error Handler Trigger",
      "type": "n8n-nodes-base.errorTrigger",
      "position": [
        -1232,
        1152
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "7e3a85d0-6586-4a32-b5b3-99aca1fe5f4d",
      "name": "Slack: Send Error Alert",
      "type": "n8n-nodes-base.slack",
      "position": [
        -1024,
        1152
      ],
      "parameters": {
        "text": "=\u26a0\ufe0f *Error in API Error Catalog Workflow*\n*Node:* {{ $json.node.name }}\n*Message:* {{ $json.error.message }}\n*Time:* {{ $json.timestamp }}",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "id",
          "value": "="
        },
        "otherOptions": {},
        "authentication": "oAuth2"
      },
      "credentials": {
        "slackOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.3
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "b9d49bbe-de92-4ac0-afd6-7d04141ab9da",
  "connections": {
    "Brand Config": {
      "main": [
        [
          {
            "node": "Fetch Reddit Mentions",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Checking Score": {
      "main": [
        [
          {
            "node": "Mentions Exist?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Mentions Exist?": {
      "main": [
        [
          {
            "node": "AI Agent - Classify Mention Sentiments",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "No Mentions Message",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Every Day at 09:00": {
      "main": [
        [
          {
            "node": "Brand Config",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Normalize Mentions": {
      "main": [
        [
          {
            "node": "Checking Score",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Build Daily Summary": {
      "main": [
        [
          {
            "node": "Send Daily Report to Slack",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "No Mentions Message": {
      "main": [
        [
          {
            "node": "Send No Mentions to Slack",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Error Handler Trigger": {
      "main": [
        [
          {
            "node": "Slack: Send Error Alert",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Reddit Mentions": {
      "main": [
        [
          {
            "node": "Normalize Mentions",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Format Sentiment Data": {
      "main": [
        [
          {
            "node": "Build Daily Summary",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Memory - Conversation Buffer": {
      "ai_memory": [
        [
          {
            "node": "AI Agent - Classify Mention Sentiments",
            "type": "ai_memory",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI Chat Model - GPT-4o-mini": {
      "ai_languageModel": [
        [
          {
            "node": "AI Agent - Classify Mention Sentiments",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Output Parser - Structured JSON": {
      "ai_outputParser": [
        [
          {
            "node": "AI Agent - Classify Mention Sentiments",
            "type": "ai_outputParser",
            "index": 0
          }
        ]
      ]
    },
    "AI Agent - Classify Mention Sentiments": {
      "main": [
        [
          {
            "node": "Format Sentiment Data",
            "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

Monitor daily brand visibility and reputation with an automated AI-powered mention tracker. 🔍🤖 This workflow checks Hacker News every morning for new stories matching your brand keyword, classifies each mention’s sentiment and urgency using GPT-4o-mini, and delivers a clean…

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

More AI & RAG workflows → · Browse all categories →

Related workflows

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

AI & RAG

This workflow automates end-to-end sustainability lifecycle management for corporate sustainability teams, ESG governance officers, and circular economy programme leads. It addresses the challenge of

Form Trigger, Agent, OpenAI Chat +11
AI & RAG

Automate your content repurposing workflow by transforming long-form articles, blogs, and newsletters into short, high-signal, AI-ready social media snippets. ✍️🤖 This workflow fetches pending content

Airtable, OpenAI Chat, Memory Buffer Window +5
AI & RAG

Streamline management decision-making by automatically evaluating high-priority tenders, generating AI-powered executive summaries, and routing them for approval inside Slack. 🤖📩 This workflow pulls p

Output Parser Structured, OpenAI Chat, Memory Buffer Window +5
AI & RAG

Ensure suppliers never miss a follow-up by automating overdue purchase order tracking and scheduling. 📦⏰ This workflow checks Airtable every weekday morning for open POs older than seven days without

Airtable, Slack, Google Calendar +6
AI & RAG

What this workflow does

OpenAI Chat, Memory Buffer Window, Output Parser Structured +4