{
  "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
          }
        ]
      ]
    }
  }
}