This workflow corresponds to n8n.io template #9895 — we link there as the canonical source.
This workflow follows the Google Sheets → Slack 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 →
{
"id": "jSHygjNuZdSzA83e",
"meta": {
"templateCredsSetupCompleted": true
},
"name": "Automated E-commerce Store Monitoring for New Products Using BrowserAct",
"tags": [],
"nodes": [
{
"id": "4a57ae79-3420-41de-8712-3bfb0638ee44",
"name": "Schedule Trigger",
"type": "n8n-nodes-base.scheduleTrigger",
"position": [
-544,
-128
],
"parameters": {
"rule": {
"interval": [
{}
]
}
},
"typeVersion": 1.2
},
{
"id": "ae8004bb-cbc4-463d-bfa1-f4e0025f89a3",
"name": "Get row(s) in sheet",
"type": "n8n-nodes-base.googleSheets",
"position": [
-416,
-128
],
"parameters": {
"options": {},
"sheetName": {
"__rl": true,
"mode": "list",
"value": "gid=0",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1A_SG0aNjbRs9Sdc2uowXyNCI0-h3W4uEpPogD_B3ZM4/edit#gid=0",
"cachedResultName": "Competitor Store List"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1A_SG0aNjbRs9Sdc2uowXyNCI0-h3W4uEpPogD_B3ZM4",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1A_SG0aNjbRs9Sdc2uowXyNCI0-h3W4uEpPogD_B3ZM4/edit?usp=drivesdk",
"cachedResultName": "Shopify New Product Monitor"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.7
},
{
"id": "a4c4d616-994b-47f7-a480-d7b25df1678e",
"name": "Create sheet",
"type": "n8n-nodes-base.googleSheets",
"position": [
0,
-112
],
"parameters": {
"title": "={{ $json.Name }}",
"options": {},
"operation": "create",
"documentId": {
"__rl": true,
"mode": "list",
"value": "1A_SG0aNjbRs9Sdc2uowXyNCI0-h3W4uEpPogD_B3ZM4",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1A_SG0aNjbRs9Sdc2uowXyNCI0-h3W4uEpPogD_B3ZM4/edit?usp=drivesdk",
"cachedResultName": "Shopify New Product Monitor"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.7,
"alwaysOutputData": true
},
{
"id": "96c17b4b-81fc-4367-a1f5-48f6df2012e8",
"name": "Send a message",
"type": "n8n-nodes-base.slack",
"position": [
1280,
-112
],
"parameters": {
"text": "=New Product Added to {{ $('Loop Over Items').first().json.Name }}\nWebsite Please Check it out\n------------------------------------------------------\n{{ $('Schedule Trigger').first().json['Readable date']}}",
"select": "channel",
"channelId": {
"__rl": true,
"mode": "list",
"value": "C09LWT82KHN",
"cachedResultName": "new_product_added"
},
"otherOptions": {},
"authentication": "oAuth2"
},
"credentials": {
"slackOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 2.3
},
{
"id": "09378204-fcb5-4ab3-bc55-d152ced637ff",
"name": "Merge",
"type": "n8n-nodes-base.merge",
"position": [
832,
-128
],
"parameters": {
"mode": "chooseBranch",
"useDataOfInput": 2
},
"typeVersion": 3.2
},
{
"id": "e02d1d99-71f7-4f28-b32c-cf87350b6f6c",
"name": "Sticky Note - Intro",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1104,
-512
],
"parameters": {
"width": 544,
"height": 460,
"content": "## Try It Out!\n### This template is an advanced competitive intelligence tool that automatically monitors competitor Shopify stores and alerts you the moment they launch a new product.\n\n### How it works\n* The workflow runs on a **schedule** to check for new products automatically.\n* It reads your list of competitor stores from a central **Google Sheet**.\n* It **loops** through each competitor one by one.\n* For each competitor, it creates a dedicated tracking sheet and then uses **BrowserAct** to scrape their current product list.\n* The workflow then compares this *new* product list against the *previous* list stored in the tracking sheet.\n* A **Code** node performs a difference check to see if any new products have been added.\n* If a new product is detected, it sends an instant **Slack** alert to your team.\n\n### Requirements\n* **BrowserAct** API account for web scraping.\n* **BrowserAct** n8n Community Node -> ([n8n Nodes BrowserAct](https://www.npmjs.com/package/n8n-nodes-browseract-workflows))\n* **Google Sheets** credentials for storing data.\n* **Slack** credentials for sending alerts.\n* A BrowserAct template named **\u201cCompetitors Shopify Website New Product Monitor\n\u201d**.\n\n### Need Help?\nJoin the [Discord](https://discord.com/invite/UpnCKd7GaU) or Visit Our [Blog](https://www.browseract.com/blog)!\n"
},
"typeVersion": 1
},
{
"id": "84f37a3b-9084-42c1-9a7c-10cf3dcbce2f",
"name": "Sticky Note - How to Use",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1104,
-32
],
"parameters": {
"width": 544,
"height": 212,
"content": "## How to use\n\n1. **Set up Credentials:** Add your credentials for **BrowserAct**, **Google Sheets**, and **Slack**.\n2. **Set up BrowserAct Template:** Ensure you Use the **\u201cCompetitors Shopify Website New Product Monitor\n\u201d** template in your BrowserAct account.\n3. **Prepare Your Google Sheet:** In the main spreadsheet, create a sheet named `Competitor Store List` with columns for competitor `Name`, `Link`, and `Pagination Type`.\n4. **Set Slack Channel:** Update the **Channel ID** in the **Slack** node to your desired alerts channel.\n5. **Activate Workflow:** Activate the workflow to begin scheduled monitoring. The workflow will automatically create and manage the individual tracking sheets for each competitor."
},
"typeVersion": 1
},
{
"id": "26e56a85-706b-47cf-8c4f-744ff76ba4ec",
"name": "Sticky Note - Need Help",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1104,
192
],
"parameters": {
"width": 544,
"height": 152,
"content": "\n### Need Help?\n* #### [How to Find Your BrowseAct API Key & Workflow ID](https://www.youtube.com/watch?v=pDjoZWEsZlE)\n* #### [How to Connect n8n to Browseract](https://www.youtube.com/watch?v=RoYMdJaRdcQ)\n* #### [How to Use & Customize BrowserAct Templates](https://www.youtube.com/watch?v=CPZHFUASncY)\n* #### [How to Use the BrowserAct N8N Community Node](https://youtu.be/j0Nlba2pRLU)\n* #### [Automatically Track Competitor Products | n8n & Google Sheets Template](https://youtu.be/Gsj6IlyxdY0)"
},
"typeVersion": 1
},
{
"id": "4f57eeca-65ca-4d2d-85f9-c3ac2a121caa",
"name": "Sticky Note - Input & Loop",
"type": "n8n-nodes-base.stickyNote",
"position": [
-432,
-368
],
"parameters": {
"color": 6,
"width": 368,
"height": 216,
"content": "### \ud83d\udccb 1. Setup & Loop\n\n* **Schedule Trigger:** Kicks off the entire process automatically.\n\n* **Google Sheets:** This node fetches your master list of competitor stores to be monitored.\n\n* **Loop Over Items:** This node is essential. It ensures the workflow processes each competitor from your sheet individually and in an organized fashion."
},
"typeVersion": 1
},
{
"id": "ba28c483-2847-4942-919b-2fda4f7ca43e",
"name": "Sticky Note - Scrape & Store",
"type": "n8n-nodes-base.stickyNote",
"position": [
-48,
-368
],
"parameters": {
"color": 5,
"width": 560,
"height": 208,
"content": "### \ud83e\udd16 2. Scrape & Store Data\n\nThis section is the data engine for each competitor in the loop.\n\n* **Create sheet:** Creates a dedicated sheet for the competitor if it doesn't exist, keeping your data organized.\n* **BrowserAct Nodes:** These nodes run the scraper to get a fresh list of products from the competitor's live website.\n* **Code Node:** Parses the scraper's output.\n* **Append or update row...:** This node saves the newly scraped product list to the competitor's dedicated sheet, creating a historical record for comparison."
},
"typeVersion": 1
},
{
"id": "4eee11df-f0aa-48e3-8b32-0612749612b4",
"name": "Sticky Note - Compare & Alert",
"type": "n8n-nodes-base.stickyNote",
"position": [
816,
-368
],
"parameters": {
"color": 3,
"width": 624,
"height": 208,
"content": "### \ud83e\udde0 3. Compare & Alert\n\nThis is the intelligence core of the workflow.\n\n* **Get Row Nodes & Merge:** These nodes fetch both the *newly scraped* product list and the *previously saved* list.\n\n* **Code in JavaScript1:** This is the key logic. It compares the two lists and detects if any product names exist in the new list that weren't in the old one.\n\n* **If & Slack:** If the code finds a new product, the `If` node directs the workflow to send an immediate Slack alert, giving you real-time competitive insight."
},
"typeVersion": 1
},
{
"id": "8e99c2b5-ef85-491b-ab56-9888208054f6",
"name": "Get row(s) for Compare",
"type": "n8n-nodes-base.googleSheets",
"position": [
608,
-256
],
"parameters": {
"options": {},
"sheetName": {
"__rl": true,
"mode": "list",
"value": 1605316777,
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1A_SG0aNjbRs9Sdc2uowXyNCI0-h3W4uEpPogD_B3ZM4/edit#gid=1605316777",
"cachedResultName": "hiutdenim - Men"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1A_SG0aNjbRs9Sdc2uowXyNCI0-h3W4uEpPogD_B3ZM4",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1A_SG0aNjbRs9Sdc2uowXyNCI0-h3W4uEpPogD_B3ZM4/edit?usp=drivesdk",
"cachedResultName": "Shopify New Product Monitor"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
},
"executeOnce": true,
"typeVersion": 4.7,
"alwaysOutputData": true
},
{
"id": "b520b61b-025e-4c40-9495-f719c5978d87",
"name": "Compare Datas",
"type": "n8n-nodes-base.code",
"position": [
960,
-128
],
"parameters": {
"jsCode": "// The 'items' variable is an array of objects, where each object\n// corresponds to an input item and has a 'json' property containing its data.\n// In the Function node, items[0] will be the first input (e.g., from Google Sheets Get Row 1)\n// and items[1] will be the second input (e.g., from Google Sheets Get Row 2) if you connect two nodes.\n\nconst list1 = $input.all(); // Assuming your first input is a list of maps/items under a 'data' key\nconst list2 = $('Get row(s) for Compare').all(); // Assuming your second input is a list of maps/items under a 'data' key\n\n// ----------------------------------------------------------------------\n// 1. Create a Set of all 'Name' values from the second list for quick lookup\n// ----------------------------------------------------------------------\nconst namesInList2 = new Set(list2.map(item => item.json.Name).filter(name => name != null));\n\n// ----------------------------------------------------------------------\n// 2. Check if ANY name from list1 is missing in list2\n// The .some() method will stop and return true the moment the condition is met.\n// ----------------------------------------------------------------------\nconst isMissingName = list1.some(item1 => {\n const nameToCheck = item1.json.Name;\n \n // Condition: Is the name NOT null AND is it NOT present in the namesInList2 Set?\n return nameToCheck != null && !namesInList2.has(nameToCheck);\n});\n\n// ----------------------------------------------------------------------\n// 3. Output a SINGLE item with the Alert status\n// ----------------------------------------------------------------------\nif (isMissingName) {\n return [{\n json: {\n \"Alert\": true,\n \"Message\": \"One or more names from the first list are missing in the second list.\"\n }\n }];\n} else {\n return [{\n json: {\n \"Alert\": false,\n \"Message\": \"All names from the first list are present in the second list.\"\n }\n }];\n}"
},
"typeVersion": 2
},
{
"id": "ed459d93-efe4-4b7f-a66c-5a3d8e8cb721",
"name": "Parse Json",
"type": "n8n-nodes-base.code",
"position": [
336,
-112
],
"parameters": {
"jsCode": "// Get the JSON string using the exact path provided by the user.\nconst jsonString = $input.first().json.output.string;\n\nlet parsedData;\n\n// Check if the string exists before attempting to parse\nif (!jsonString) {\n // Return an empty array or throw an error if no string is found\n // Throwing an error is usually better to stop the workflow if data is missing.\n throw new Error(\"Input string is empty or missing at the specified path: $input.first().json.output.string\");\n}\n\ntry {\n // 1. Parse the JSON string into a JavaScript array of objects\n parsedData = JSON.parse(jsonString);\n} catch (error) {\n // Handle JSON parsing errors (e.g., if the string is malformed)\n throw new Error(`Failed to parse JSON string: ${error.message}`);\n}\n\n// 2. Ensure the parsed data is an array\nif (!Array.isArray(parsedData)) {\n throw new Error('Parsed data is not an array. It cannot be split into multiple items.');\n}\n\n// 3. Map the array of objects into the n8n item format { json: object }\n// Each element in this array will be treated as a new item by n8n, achieving the split.\nconst outputItems = parsedData.map(item => ({\n json: item,\n}));\n\n// 4. Return the new array of items\nreturn outputItems;"
},
"typeVersion": 2
},
{
"id": "530fc448-8f83-4c49-8c29-60b3bac8eb05",
"name": "Get workflow Data",
"type": "n8n-nodes-browseract-workflows.browserAct",
"position": [
224,
-112
],
"parameters": {
"taskId": "={{ $json.id }}",
"operation": "getTask",
"waitForFinish": true
},
"credentials": {
"browserActApi": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "e3833253-d698-4144-8999-a638c6999977",
"name": "Run a workflow",
"type": "n8n-nodes-browseract-workflows.browserAct",
"position": [
112,
-112
],
"parameters": {
"workflowId": "57142458383023994",
"inputParameters": {
"parameters": [
{
"name": "Competitor_Store_Link",
"value": "={{ $('Loop Over Items').item.json.Link }}"
},
{
"name": "Pagination_Type",
"value": "={{ $('Loop Over Items').item.json[\"Pagination Type\"] }}"
},
{
"name": "Total_Product",
"value": "10"
}
]
},
"additionalFields": {}
},
"credentials": {
"browserActApi": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "127198eb-8387-45e9-b4f1-ce70c01fbb7c",
"name": "Store Data",
"type": "n8n-nodes-base.googleSheets",
"position": [
544,
-112
],
"parameters": {
"columns": {
"value": {},
"schema": [
{
"id": "Name",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Name",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Price",
"type": "string",
"display": true,
"required": false,
"displayName": "Price",
"defaultMatch": false,
"canBeUsedToMatch": true
}
],
"mappingMode": "autoMapInputData",
"matchingColumns": [
"Name"
],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {},
"operation": "appendOrUpdate",
"sheetName": {
"__rl": true,
"mode": "list",
"value": 1605316777,
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1A_SG0aNjbRs9Sdc2uowXyNCI0-h3W4uEpPogD_B3ZM4/edit#gid=1605316777",
"cachedResultName": "hiutdenim - Men"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1A_SG0aNjbRs9Sdc2uowXyNCI0-h3W4uEpPogD_B3ZM4",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1A_SG0aNjbRs9Sdc2uowXyNCI0-h3W4uEpPogD_B3ZM4/edit?usp=drivesdk",
"cachedResultName": "Shopify New Product Monitor"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.7
},
{
"id": "b637be2d-8c78-4517-a9bc-68fb12eb2019",
"name": "Get Data For Compare",
"type": "n8n-nodes-base.googleSheets",
"position": [
672,
-112
],
"parameters": {
"options": {},
"sheetName": {
"__rl": true,
"mode": "list",
"value": 1605316777,
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1A_SG0aNjbRs9Sdc2uowXyNCI0-h3W4uEpPogD_B3ZM4/edit#gid=1605316777",
"cachedResultName": "hiutdenim - Men"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1A_SG0aNjbRs9Sdc2uowXyNCI0-h3W4uEpPogD_B3ZM4",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1A_SG0aNjbRs9Sdc2uowXyNCI0-h3W4uEpPogD_B3ZM4/edit?usp=drivesdk",
"cachedResultName": "Shopify New Product Monitor"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
},
"executeOnce": true,
"typeVersion": 4.7,
"alwaysOutputData": true
},
{
"id": "db5e7117-f9bf-4cad-8d22-eb2ca4a9e07c",
"name": "Check New Product",
"type": "n8n-nodes-base.if",
"position": [
1088,
-128
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "loose"
},
"combinator": "and",
"conditions": [
{
"id": "db0940fb-0954-4792-8065-eb7147e8068e",
"operator": {
"type": "boolean",
"operation": "exists",
"singleValue": true
},
"leftValue": "={{ $json.Alert }}",
"rightValue": ""
},
{
"id": "03a29ec0-3f86-4d9b-8834-c08b3ddf8953",
"operator": {
"name": "filter.operator.equals",
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.Alert }}",
"rightValue": "=true"
}
]
},
"looseTypeValidation": true
},
"typeVersion": 2.2
},
{
"id": "a7712d64-c968-4131-b6d6-eea600699e86",
"name": "Loop Over Items",
"type": "n8n-nodes-base.splitInBatches",
"position": [
-240,
-128
],
"parameters": {
"options": {}
},
"typeVersion": 3
},
{
"id": "d3e295c7-249c-4c09-bb66-828b1335c23e",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
-432,
-144
],
"parameters": {
"color": 6,
"width": 368,
"height": 240,
"content": ""
},
"typeVersion": 1
},
{
"id": "d34cb56d-dabe-4f4e-ae84-605893f7fafb",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
-48,
-144
],
"parameters": {
"color": 5,
"width": 560,
"height": 240,
"content": ""
},
"typeVersion": 1
},
{
"id": "17fdf64a-8c47-4661-9a32-43be26c24938",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
528,
-368
],
"parameters": {
"color": 5,
"width": 272,
"height": 464,
"content": ""
},
"typeVersion": 1
},
{
"id": "9e96b86b-3615-4c14-be2f-555c7ba386de",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
816,
-144
],
"parameters": {
"color": 3,
"width": 624,
"height": 240,
"content": ""
},
"typeVersion": 1
}
],
"active": false,
"settings": {
"executionOrder": "v1"
},
"versionId": "8b998d65-770d-4218-a6cb-11815c365e72",
"connections": {
"Merge": {
"main": [
[
{
"node": "Compare Datas",
"type": "main",
"index": 0
}
]
]
},
"Parse Json": {
"main": [
[
{
"node": "Get row(s) for Compare",
"type": "main",
"index": 0
},
{
"node": "Store Data",
"type": "main",
"index": 0
}
]
]
},
"Store Data": {
"main": [
[
{
"node": "Get Data For Compare",
"type": "main",
"index": 0
}
]
]
},
"Create sheet": {
"main": [
[
{
"node": "Run a workflow",
"type": "main",
"index": 0
}
]
]
},
"Compare Datas": {
"main": [
[
{
"node": "Check New Product",
"type": "main",
"index": 0
}
]
]
},
"Run a workflow": {
"main": [
[
{
"node": "Get workflow Data",
"type": "main",
"index": 0
}
]
]
},
"Send a message": {
"main": [
[
{
"node": "Loop Over Items",
"type": "main",
"index": 0
}
]
]
},
"Loop Over Items": {
"main": [
[],
[
{
"node": "Create sheet",
"type": "main",
"index": 0
}
]
]
},
"Schedule Trigger": {
"main": [
[
{
"node": "Get row(s) in sheet",
"type": "main",
"index": 0
}
]
]
},
"Check New Product": {
"main": [
[
{
"node": "Send a message",
"type": "main",
"index": 0
}
],
[
{
"node": "Loop Over Items",
"type": "main",
"index": 0
}
]
]
},
"Get workflow Data": {
"main": [
[
{
"node": "Parse Json",
"type": "main",
"index": 0
}
]
]
},
"Get row(s) in sheet": {
"main": [
[
{
"node": "Loop Over Items",
"type": "main",
"index": 0
}
]
]
},
"Get Data For Compare": {
"main": [
[
{
"node": "Merge",
"type": "main",
"index": 1
}
]
]
},
"Get row(s) for Compare": {
"main": [
[
{
"node": "Merge",
"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.
browserActApigoogleSheetsOAuth2ApislackOAuth2Api
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
This workflow is essential for e-commerce store owners, product strategists, and marketing teams who need real-time insight into what their competitors are selling.
Source: https://n8n.io/workflows/9895/ — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
This workflow continuously monitors the TikTok Ads Library for new creatives from specific advertisers or keyword searches, scrapes them via Apify, logs them into Google Sheets, and sends concise noti
This workflow is essential for technical recruiters, talent acquisition teams, and business intelligence analysts who need to dive deep into a pre-qualified list of developers to understand their rece
This workflow contains community nodes that are only compatible with the self-hosted version of n8n.
Simplify financial oversight with this automated n8n workflow. Triggered daily, it fetches cash flow and expense data from a Google Sheet, analyzes inflows and outflows, validates records, and generat
This workflow is essential for dropshippers, e-commerce store owners, and anyone looking to quickly import product catalogs from specific websites into their Shopify store.