AutomationFlowsAI & RAG › Monitor and Classify Brand Mentions From Instagram and Google with Gemini

Monitor and Classify Brand Mentions From Instagram and Google with Gemini

ByApify @apify on n8n.io

This workflow runs daily to find new brand mentions from Instagram hashtags and Google Search via Apify, deduplicates them in an n8n Data Table, classifies each mention with Google Gemini for sentiment and urgency, and sends high-urgency alerts to a Slack channel. Runs every day…

Cron / scheduled trigger★★★★☆ complexityAI-powered24 nodes@Apify/N8N Nodes ApifyData TableAgentOutput Parser StructuredSlackGoogle Gemini Chat
AI & RAG Trigger: Cron / scheduled Nodes: 24 Complexity: ★★★★☆ AI nodes: yes Added:

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

This workflow follows the Agent → Datatable 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": "sDQyXDAg2LSoWAn9",
  "meta": {
    "aiBuilderAssisted": true,
    "templateCredsSetupCompleted": true
  },
  "name": "Brand Mention Monitor \u2014 Instagram + Google Search (Apify)",
  "tags": [],
  "nodes": [
    {
      "id": "73a777d1-4974-488f-87d1-9ba237824caf",
      "name": "Daily at 9am UTC",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        -48,
        480
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "triggerAtHour": 9
            }
          ]
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "6ff9a6aa-3036-4ede-ba23-2a16cd361630",
      "name": "Brand Config",
      "type": "n8n-nodes-base.set",
      "position": [
        304,
        480
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "cfg-1",
              "name": "instagramHashtags",
              "type": "array",
              "value": "={{ [\"nike\"] }}"
            },
            {
              "id": "cfg-2",
              "name": "googleQueries",
              "type": "string",
              "value": "yourbrand"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "661b9493-3e84-4f32-a937-1659ea19fda1",
      "name": "Scrape Instagram",
      "type": "@apify/n8n-nodes-apify.apify",
      "position": [
        640,
        288
      ],
      "parameters": {
        "actorId": "apify~instagram-hashtag-scraper",
        "timeout": 300,
        "operation": "Run actor and get dataset",
        "customBody": "={{ JSON.stringify({ hashtags: $json.instagramHashtags, resultsType: \"posts\", resultsLimit: 30 }) }}",
        "authentication": "apifyOAuth2Api"
      },
      "credentials": {
        "apifyOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "15a6a413-9386-4d9a-8102-69777a3958cf",
      "name": "Normalize Instagram",
      "type": "n8n-nodes-base.set",
      "position": [
        944,
        288
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "ig-1",
              "name": "mention_id",
              "type": "string",
              "value": "={{ \"instagram:\" + $json.id }}"
            },
            {
              "id": "ig-2",
              "name": "platform",
              "type": "string",
              "value": "instagram"
            },
            {
              "id": "ig-3",
              "name": "text",
              "type": "string",
              "value": "={{ ($json.caption || \"\").slice(0, 1000) }}"
            },
            {
              "id": "ig-4",
              "name": "url",
              "type": "string",
              "value": "={{ $json.url }}"
            },
            {
              "id": "ig-5",
              "name": "author",
              "type": "string",
              "value": "={{ $json.ownerUsername }}"
            },
            {
              "id": "ig-6",
              "name": "timestamp",
              "type": "string",
              "value": "={{ $json.timestamp }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "70dbac36-e942-40d2-986b-e82a56fd8886",
      "name": "Merge mentions",
      "type": "n8n-nodes-base.merge",
      "position": [
        1232,
        496
      ],
      "parameters": {},
      "typeVersion": 3.2
    },
    {
      "id": "e7d35407-d60d-46b5-b9a5-da2599b60c4d",
      "name": "Scrape Google",
      "type": "@apify/n8n-nodes-apify.apify",
      "position": [
        640,
        672
      ],
      "parameters": {
        "actorId": "apify~google-search-scraper",
        "timeout": 300,
        "operation": "Run actor and get dataset",
        "customBody": "={{ JSON.stringify({ queries: $json.googleQueries, maxPagesPerQuery: 1 }) }}",
        "authentication": "apifyOAuth2Api"
      },
      "credentials": {
        "apifyOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "f4080c4c-a00a-43ed-9268-52a994a69593",
      "name": "Split & Normalize Google",
      "type": "n8n-nodes-base.code",
      "position": [
        944,
        672
      ],
      "parameters": {
        "jsCode": "const pages = $input.all();\nconst results = [];\nfor (const page of pages) {\n  const organic = (page.json && page.json.organicResults) || [];\n  for (const r of organic) {\n    if (!r || !r.url) continue;\n    results.push({ json: { mention_id: 'google:' + r.url, platform: 'googleSearch', text: ((r.description || r.title || '')).slice(0, 1000), url: r.url, author: r.displayedUrl || '', timestamp: r.date || new Date().toISOString() } });\n  }\n}\nreturn results;"
      },
      "typeVersion": 2
    },
    {
      "id": "b70ca4e5-60f2-4dad-b9ea-927e37724ccd",
      "name": "Filter to New Mentions",
      "type": "n8n-nodes-base.dataTable",
      "position": [
        1440,
        496
      ],
      "parameters": {
        "filters": {
          "conditions": [
            {
              "keyName": "mention_id",
              "keyValue": "={{ $json.mention_id }}"
            }
          ]
        },
        "matchType": "allConditions",
        "operation": "rowNotExists",
        "dataTableId": {
          "__rl": true,
          "mode": "list",
          "value": "lF94fS7ljkp2s814",
          "cachedResultUrl": "/projects/PoNHavfrDzYXmYsO/datatables/lF94fS7ljkp2s814",
          "cachedResultName": "Brand monitoring DB"
        }
      },
      "typeVersion": 1.1
    },
    {
      "id": "2a15be3a-6389-4286-947e-e9a8fbddfba6",
      "name": "Classify Mention",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        1696,
        496
      ],
      "parameters": {
        "text": "=Analyze this brand mention and ECHO BACK the source fields plus your classification.\n\nSOURCE (copy unchanged into output):\nmention_id: {{ $json.mention_id }}\nplatform: {{ $json.platform }}\ntext: {{ $json.text }}\nurl: {{ $json.url }}\nauthor: {{ $json.author }}\ntimestamp: {{ $json.timestamp }}\n\nCLASSIFY (add):\nsentiment: positive / neutral / negative\nurgency: low / medium / high\nrelevance: integer 1-10 (10 = clearly about the brand, 1 = false-positive)\nsummary: 1-line summary\ntopic: short category (e.g. product feedback, support issue, praise, competitor)\n\nReturn JSON with all ten fields.",
        "options": {
          "systemMessage": "You are a brand-mention analyst. Echo source fields unchanged, add classification fields."
        },
        "promptType": "define",
        "hasOutputParser": true
      },
      "typeVersion": 3.1
    },
    {
      "id": "db397e07-67e8-40b7-a3c0-3473ed5851bb",
      "name": "Mention Schema",
      "type": "@n8n/n8n-nodes-langchain.outputParserStructured",
      "position": [
        1840,
        688
      ],
      "parameters": {
        "jsonSchemaExample": "{\"mention_id\":\"src-id\",\"platform\":\"instagram\",\"text\":\"sample\",\"url\":\"https://example.com\",\"author\":\"someone\",\"timestamp\":\"2026-01-01T00:00:00Z\",\"sentiment\":\"positive\",\"urgency\":\"low\",\"relevance\":7,\"summary\":\"brief\",\"topic\":\"product feedback\"}"
      },
      "typeVersion": 1.3
    },
    {
      "id": "8aca122f-0535-4163-bdeb-0b6293be41e7",
      "name": "Relevance >= 6?",
      "type": "n8n-nodes-base.if",
      "position": [
        2096,
        448
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 3,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "6ecb2359-1761-4d4f-b2ca-ec7657c32624",
              "operator": {
                "type": "number",
                "operation": "gte"
              },
              "leftValue": "={{ $json.output.relevance }}",
              "rightValue": 6
            }
          ]
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "4cac30bd-0ca9-45f5-8123-fd50f2a2a763",
      "name": "High Urgency?",
      "type": "n8n-nodes-base.if",
      "position": [
        2352,
        448
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 3,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "or",
          "conditions": [
            {
              "id": "2f2c5da1-6c19-4510-923c-b5e823f2f0c2",
              "operator": {
                "type": "string",
                "operation": "contains"
              },
              "leftValue": "={{ $json.output.urgency }}",
              "rightValue": "medium"
            },
            {
              "id": "aa04306a-585a-402a-bc3c-ff79261a5a94",
              "operator": {
                "type": "string",
                "operation": "contains"
              },
              "leftValue": "={{ $json.output.urgency }}",
              "rightValue": "high"
            }
          ]
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "4bafb8f7-3f4d-40b5-a156-c00b1bd42f5a",
      "name": "Slack high-urgency alert",
      "type": "n8n-nodes-base.slack",
      "position": [
        2672,
        448
      ],
      "parameters": {
        "text": "={{ \":rotating_light: *High-urgency brand mention*\\n*Platform:* \" + $json.output.platform + \"\\n*Sentiment:* \" + $json.output.sentiment + \"\\n*Summary:* \" + $json.output.summary + \"\\n*Link:* \" + $json.output.url }}",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "list",
          "value": "C0AEVPUCC66",
          "cachedResultName": "apify-n8n-use-cases"
        },
        "otherOptions": {
          "mrkdwn": true,
          "includeLinkToWorkflow": false
        },
        "authentication": "oAuth2"
      },
      "credentials": {
        "slackOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.4
    },
    {
      "id": "0717c005-3517-42e6-a53b-05614e70a25c",
      "name": "Insert row",
      "type": "n8n-nodes-base.dataTable",
      "position": [
        1440,
        704
      ],
      "parameters": {
        "columns": {
          "value": {
            "mention_id": "={{ $json.mention_id }}"
          },
          "schema": [
            {
              "id": "mention_id",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "mention_id",
              "defaultMatch": false
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "mention_id"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "dataTableId": {
          "__rl": true,
          "mode": "list",
          "value": "lF94fS7ljkp2s814",
          "cachedResultUrl": "/projects/PoNHavfrDzYXmYsO/datatables/lF94fS7ljkp2s814",
          "cachedResultName": "Brand monitoring DB"
        }
      },
      "typeVersion": 1.1
    },
    {
      "id": "a7767a24-ea6a-4bc6-aef4-95617a864fb9",
      "name": "Google Gemini Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
      "position": [
        1696,
        688
      ],
      "parameters": {
        "options": {}
      },
      "credentials": {
        "googlePalmApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.1
    },
    {
      "id": "bcfddee7-63e8-481f-ad46-ed7f6e537f57",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        560,
        160
      ],
      "parameters": {
        "width": 576,
        "height": 352,
        "content": "## Instagram mentions\nThe Instagram Hashtag Scraper Actor pulls recent posts for your hashtag(s) \u2014 caption, author, engagement, link. The Set node reshapes each post into a standard mention. Add your Apify credential on the Actor node."
      },
      "typeVersion": 1
    },
    {
      "id": "99a53442-3d66-4818-8d2b-bb7277991fbb",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        560,
        544
      ],
      "parameters": {
        "width": 576,
        "height": 368,
        "content": "## Google mentions\nThe Google Search Scraper Actor sweeps the open web (Reddit, forums, news, blogs) for your queries. The Code node splits the results into the same mention shape. Uses the same Apify credential."
      },
      "typeVersion": 1
    },
    {
      "id": "fa1c05fd-8844-4bce-b2c5-e62313e21d49",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        192,
        272
      ],
      "parameters": {
        "width": 320,
        "height": 512,
        "content": "## Set your brand\nTell the workflow what to watch:\n\u2022 instagramHashtags \u2014 your brand hashtag(s), e.g. [\"apify\"]\n\u2022 googleQueries \u2014 open-web searches, e.g. apify, apify site:reddit.com\nEverything downstream runs off these two values."
      },
      "typeVersion": 1
    },
    {
      "id": "be3ef70e-fe28-40c2-a859-42780738dc01",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -160,
        272
      ],
      "parameters": {
        "width": 320,
        "height": 512,
        "content": "## Scheduled workflow start\nRuns every day at 9am UTC, then fans out to the two mention sources in parallel. Change the time in this node to fit your cadence."
      },
      "typeVersion": 1
    },
    {
      "id": "ffd03181-af11-4788-b261-e0af60f35474",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1184,
        288
      ],
      "parameters": {
        "width": 416,
        "height": 592,
        "content": "## Merge and dedupe\nBoth lanes combine into one stream. The Data Table check drops anything already seen, matched on mention_id, and writes each new mention to the \"Brand monitoring DB\" table so it is skipped next run. Point both Data Table nodes at your table."
      },
      "typeVersion": 1
    },
    {
      "id": "0fe10b66-5401-45f1-88d0-eb4ef58696df",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1648,
        288
      ],
      "parameters": {
        "width": 336,
        "height": 592,
        "content": "## Classify with Gemini\nGoogle Gemini scores each new mention for sentiment, urgency, relevance (1-10), and topic, and echoes the source fields back through the structured-output parser. Add your Google Gemini credential on the model node."
      },
      "typeVersion": 1
    },
    {
      "id": "1efa35f8-456f-40b8-9519-354fb4531a60",
      "name": "Sticky Note6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2032,
        288
      ],
      "parameters": {
        "width": 496,
        "height": 320,
        "content": "## Keep what matters\nTwo gates decide what earns an alert: relevance of 6 or higher, then urgency of medium or high. Adjust either threshold to make alerts louder or quieter."
      },
      "typeVersion": 1
    },
    {
      "id": "04b0de2d-84cc-44b6-b407-46a637e1c5ef",
      "name": "Sticky Note7",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2576,
        240
      ],
      "parameters": {
        "width": 288,
        "height": 416,
        "content": "## Slack alert\nHigh-urgency mentions post to your channel within seconds, with platform, sentiment, a one-line summary, and a link to the source. Pick your channel and add the Slack credential."
      },
      "typeVersion": 1
    },
    {
      "id": "9a7c55f3-aaf7-483a-a459-0a4ce55f363c",
      "name": "Sticky Note8",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -928,
        -96
      ],
      "parameters": {
        "width": 704,
        "height": 1088,
        "content": "## Brand Mention Monitor - Instagram + Google Search\n\n**What it does** \nEvery morning it finds fresh mentions of your brand on Instagram (by hashtag) and across the open web via Google Search (Reddit, forums, news, blogs), classifies each one with Google Gemini for sentiment, urgency, and relevance, logs them to an n8n Data table, and posts a Slack alert the moment anything high-urgency appears. No manual searching, no separate monitoring tool.\n\n\n**How it works** \nSchedule (daily 9 am UTC) \u2192 Brand Config \u2192 two parallel lanes (Instagram Hashtag Scraper, Google Search Scraper) \u2192 normalize \u2192 merge \u2192 dedupe against the Data table \u2192 classify with Gemini \u2192 keep relevance 6 or higher \u2192 if urgency is medium or high \u2192 Slack alert.\n\n\n**Setup** \n1. Add three credentials: Apify (OAuth), Google Gemini, and Slack (OAuth).\n2. Create one Data Table named \"Brand monitoring DB\" with a `mention_id` (string) column, and point both Data Table nodes at it.\n3. In Brand Config, set `instagramHashtags` (e.g. `[\"apify\"]`) and `googleQueries` (e.g. `apify`, `apify site:reddit.com`).\n4. In the Slack node, pick your alert channel.\n5. Activate.\n\n\n**Cost**\n\nA few dollars per month on a daily schedule: two Apify Actor runs plus roughly 30 short Gemini classifications per day. (Confirm against current Apify Actor and Gemini pricing before publishing externally.)\n\n\n**Why Apify**\n\nSocial platforms actively block generic data-extraction tools, so DIY scrapers break within weeks. Apify maintains the proxy infrastructure and the platform-specific Actors (Instagram Hashtag Scraper, Google Search Scraper) and keeps them working as the platforms change, so a workflow that has to return data every morning actually does."
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "binaryMode": "separate",
    "availableInMCP": true,
    "executionOrder": "v1"
  },
  "versionId": "703197ac-6d0f-4434-a7d9-f04692b1cc59",
  "connections": {
    "Insert row": {
      "main": [
        []
      ]
    },
    "Brand Config": {
      "main": [
        [
          {
            "node": "Scrape Instagram",
            "type": "main",
            "index": 0
          },
          {
            "node": "Scrape Google",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "High Urgency?": {
      "main": [
        [
          {
            "node": "Slack high-urgency alert",
            "type": "main",
            "index": 0
          }
        ],
        []
      ]
    },
    "Scrape Google": {
      "main": [
        [
          {
            "node": "Split & Normalize Google",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Mention Schema": {
      "ai_outputParser": [
        [
          {
            "node": "Classify Mention",
            "type": "ai_outputParser",
            "index": 0
          }
        ]
      ]
    },
    "Merge mentions": {
      "main": [
        [
          {
            "node": "Filter to New Mentions",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Relevance >= 6?": {
      "main": [
        [
          {
            "node": "High Urgency?",
            "type": "main",
            "index": 0
          }
        ],
        []
      ]
    },
    "Classify Mention": {
      "main": [
        [
          {
            "node": "Relevance >= 6?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Daily at 9am UTC": {
      "main": [
        [
          {
            "node": "Brand Config",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Scrape Instagram": {
      "main": [
        [
          {
            "node": "Normalize Instagram",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Normalize Instagram": {
      "main": [
        [
          {
            "node": "Merge mentions",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Filter to New Mentions": {
      "main": [
        [
          {
            "node": "Insert row",
            "type": "main",
            "index": 0
          },
          {
            "node": "Classify Mention",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Google Gemini Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "Classify Mention",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Split & Normalize Google": {
      "main": [
        [
          {
            "node": "Merge mentions",
            "type": "main",
            "index": 1
          }
        ]
      ]
    }
  }
}

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 daily to find new brand mentions from Instagram hashtags and Google Search via Apify, deduplicates them in an n8n Data Table, classifies each mention with Google Gemini for sentiment and urgency, and sends high-urgency alerts to a Slack channel. Runs every day…

Source: https://n8n.io/workflows/16120/ — 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

Automatically scan major financial newswires for biotech catalyst events, score them with AI sentiment analysis, and surface ranked trade candidates — all without manual monitoring.

RSS Feed Read, Data Table, HTTP Request +4
AI & RAG

V2 (2026) available! An intelligent, fully automated news aggregation system that collects articles from multiple sources (RSS feeds + Google Search), uses AI to classify and summarize the most import

N8N Nodes Serpapi, Text Classifier, Output Parser Structured +6
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

This workflow automates end-to-end ESG (Environmental, Social, and Governance) sustainability reporting for enterprise sustainability teams, compliance officers, and green governance leads. It solves

Agent, OpenAI Chat, Output Parser Structured +12
AI & RAG

This template is designed for B2B sales teams, recruiters, and business development professionals who want to identify sales opportunities by monitoring hiring signals from target companies. It's part

@Apify/N8N Nodes Apify, Google Sheets, Agent +4