This workflow corresponds to n8n.io template #5976 — we link there as the canonical source.
This workflow follows the Agent → Gmail 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": "LIOY5U6r4W8pmkrH",
"meta": {
"templateCredsSetupCompleted": true
},
"name": "33 Analyze Territory Performance",
"tags": [],
"nodes": [
{
"id": "0568c8de-17a3-4a9b-a3d7-cf9a9e937888",
"name": "Weekly Territory Check",
"type": "n8n-nodes-base.scheduleTrigger",
"position": [
0,
0
],
"parameters": {
"rule": {
"interval": [
{
"field": "weeks",
"triggerAtDay": [
1
],
"triggerAtHour": 9
}
]
}
},
"typeVersion": 1.2
},
{
"id": "065eaed2-28b0-4866-8173-5ec742a40e47",
"name": "Prepare Request Params",
"type": "n8n-nodes-base.set",
"position": [
200,
0
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "01dce1c2-299c-4def-a8d0-0194cae94ea2",
"name": "url",
"type": "string",
"value": "example.com"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "71435f74-f8bf-485e-b16e-0a9092dfdec7",
"name": "Run Bright Data Scraper",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
440,
0
],
"parameters": {
"text": "=From the following URL, extract fields the below fields.\n\nStore ID\nName\nAddress\nRegion\n\nURL: {{ $json.url }}",
"options": {},
"promptType": "define",
"hasOutputParser": true
},
"typeVersion": 2
},
{
"id": "26363bd7-51e1-4a01-a489-e16f4b877b52",
"name": "Send Notification Email",
"type": "n8n-nodes-base.gmail",
"position": [
1040,
-240
],
"parameters": {
"sendTo": "user@example.com",
"message": "=Hello Team!\n\nThe Regional sales data has updated in the google sheets. So go and check it out fast.\n\nRegards,\nYour Name",
"options": {},
"subject": "Regional Sales data has updated",
"emailType": "text"
},
"credentials": {
"gmailOAuth2": {
"name": "<your credential>"
}
},
"typeVersion": 2.1
},
{
"id": "bf4afd69-2309-4aed-89d5-34c704812bc9",
"name": "Split Stores to Items",
"type": "n8n-nodes-base.code",
"position": [
1040,
0
],
"parameters": {
"jsCode": "// n8n Function Node\n// Purpose: Takes wrapped `output` array, returns each store as its own item\n\nconst results = [];\n\n// Grab the output array from first item\nconst stores = items[0].json.output;\n\n// Loop through each store\nfor (const store of stores) {\n results.push({ json: store });\n}\n\nreturn results;\n"
},
"typeVersion": 2
},
{
"id": "6c9ea046-2bc1-40e5-a95e-66a7afbc3bad",
"name": "Update Regional Data Sheet",
"type": "n8n-nodes-base.googleSheets",
"position": [
1260,
0
],
"parameters": {
"columns": {
"value": {
"Region": "={{ $json.region }}",
"Address": "={{ $json.address }}",
"Store ID": "={{ $json.store_id }}",
"Store name": "={{ $json.store_name }}",
"Last updated": "={{ $json.last_updated }}",
"Estimated sales": "={{ $json.estimated_sales }}"
},
"schema": [
{
"id": "Store ID",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Store ID",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Store name",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Store name",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Address",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Address",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Region",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Region",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Estimated sales",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Estimated sales",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Last updated",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Last updated",
"defaultMatch": false,
"canBeUsedToMatch": true
}
],
"mappingMode": "defineBelow",
"matchingColumns": [],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {},
"operation": "append",
"sheetName": {
"__rl": true,
"mode": "list",
"value": "gid=0",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/12hjlzSEhesN4r05t4Bq9w4ttEBzwXEmddDSJZ30N0tA/edit#gid=0",
"cachedResultName": "Sheet1"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "12hjlzSEhesN4r05t4Bq9w4ttEBzwXEmddDSJZ30N0tA",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/12hjlzSEhesN4r05t4Bq9w4ttEBzwXEmddDSJZ30N0tA/edit?usp=drivesdk",
"cachedResultName": "Store data"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.6
},
{
"id": "f4d0b4ea-5842-4730-8cf5-e6627ab54329",
"name": "Bright Data MCP Tool",
"type": "n8n-nodes-mcp.mcpClientTool",
"position": [
580,
280
],
"parameters": {
"toolName": "scrape_as_markdown",
"operation": "executeTool",
"toolParameters": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Tool_Parameters', ``, 'json') }}"
},
"credentials": {
"mcpClientApi": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "d3e22591-7bc7-494d-b917-934a4ffe419a",
"name": "LLM Prompt Handler",
"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
"position": [
400,
280
],
"parameters": {
"model": {
"__rl": true,
"mode": "list",
"value": "gpt-4o-mini"
},
"options": {}
},
"credentials": {
"openAiApi": {
"name": "<your credential>"
}
},
"typeVersion": 1.2
},
{
"id": "f100c167-e28b-480a-87d5-6c143812a96a",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
-40,
-640
],
"parameters": {
"color": 6,
"width": 380,
"height": 820,
"content": "## \u2705 **\ud83d\udd39 Section 1: Trigger & Prepare**\n\n**Nodes:**\n1\ufe0f\u20e3 `Weekly Territory Check` *(Schedule Trigger)*\n2\ufe0f\u20e3 `Prepare Request Params` *(Edit Fields)*\n\n**\ud83d\udca1 What it does:**\n\n* \u23f0 **Weekly Trigger**: The automation starts **automatically** on a set schedule \u2014 e.g., every Monday at 6 AM \u2014 so you don\u2019t need to remember to run it.\n* \ud83d\udcdd **Prepare Request**: This step **sets up the input** \u2014 like choosing which regions to scrape, date filters, or any special parameters you want the scraper to use.\n\n**\u2728 Why it\u2019s powerful for you:**\n\n* You never forget to update your data.\n* Anyone can **adjust input** (e.g., change region) **without touching the rest of the workflow**.\n* Perfect for **zero-code team edits**.\n\n---\n\n"
},
"typeVersion": 1
},
{
"id": "8548ff7c-748e-464c-87b4-39b1bd973bde",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
420,
-1000
],
"parameters": {
"color": 3,
"width": 300,
"height": 1180,
"content": "## \u2705 **\ud83d\udd39 Section 2: Smart Data Collection & Parsing**\n\n**Nodes:**\n3\ufe0f\u20e3 `Run Bright Data Scraper` *(AI Agent)*\n\u2014 uses \u23ec\n\n* `Bright Data MCP Tool` *(MCP Client)*\n* `LLM Prompt Handler` *(OpenAI Chat Model)*\n* `Fix/Format Scraper Output` *(Auto-fixing Output Parser)*\n* `Validation Assistant` *(OpenAI Chat Model1)*\n* `Final Output Formatter` *(Structured Output Parser)*\n\n**\ud83d\udca1 What it does:**\n\n* \ud83e\udd16 The **AI Agent** talks to the **Bright Data MCP Tool** to **scrape live data** from your target sites.\n* \ud83e\udde0 The **LLM Prompt Handler** helps the AI figure out what pages to crawl, what data to look for, and how to handle tricky websites.\n* \ud83e\uddf9 The **Auto-fixer & Parsers** make sure your scraped data is always **clean JSON**, so you never get errors in the next steps.\n\n**\u2728 Why it\u2019s powerful for you:**\n\n* This section handles all the **dirty work** of web scraping & fixing messy data.\n* You **don\u2019t write code or worry about site changes** \u2014 the agent + model fix issues automatically.\n* If a page changes, the AI adjusts how it scrapes, so you\u2019re not stuck fixing broken scrapers every week.\n\n---\n"
},
"typeVersion": 1
},
{
"id": "17a66823-bde6-4205-b1e4-3c6cd1969f2b",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
1000,
-780
],
"parameters": {
"color": 5,
"width": 400,
"height": 960,
"content": "## \u2705 **\ud83d\udd39 Section 3: Process, Save & Notify**\n\n**Nodes:**\n4\ufe0f\u20e3 `Split Stores to Items` *(Code)*\n5\ufe0f\u20e3 `Update Regional Data Sheet` *(Google Sheets)*\n6\ufe0f\u20e3 `Send Notification Email` *(Gmail)*\n\n**\ud83d\udca1 What it does:**\n\n* \u2699\ufe0f The `Split Stores to Items` node **unwraps** the single big output from the scraper \u2192 breaks it into **one item per store** so you can work with them individually.\n* \ud83d\udcca The `Update Regional Data Sheet` node **writes each store\u2019s info** into Google Sheets \u2014 creating a clean, always-up-to-date record of all your stores & their sales.\n* \ud83d\udce7 The `Send Notification Email` node **alerts you automatically** if anything needs attention \u2014 for example, \u201cHey, Region North has 20% higher load than Region South. Reassign recommended!\u201d\n\n"
},
"typeVersion": 1
},
{
"id": "666629f1-e070-49f3-a31b-1c6375c75734",
"name": "Sticky Note5",
"type": "n8n-nodes-base.stickyNote",
"position": [
1480,
-780
],
"parameters": {
"color": 7,
"width": 380,
"height": 240,
"content": "## I\u2019ll receive a tiny commission if you join Bright Data through this link\u2014thanks for fueling more free content!\n\n### https://get.brightdata.com/1tndi4600b25"
},
"typeVersion": 1
},
{
"id": "f4e125ba-f6df-465d-8ce0-b0a6c996f3e0",
"name": "Sticky Note9",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1680,
-640
],
"parameters": {
"color": 4,
"width": 1300,
"height": 320,
"content": "=======================================\n WORKFLOW ASSISTANCE\n=======================================\nFor any questions or support, please contact:\n Yaron@nofluff.online\n\nExplore more tips and tutorials here:\n - YouTube: https://www.youtube.com/@YaronBeen/videos\n - LinkedIn: https://www.linkedin.com/in/yaronbeen/\n=======================================\n"
},
"typeVersion": 1
},
{
"id": "ec9115e3-3507-44e6-b57c-37e5fe7ed046",
"name": "Sticky Note4",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1680,
-300
],
"parameters": {
"color": 4,
"width": 1289,
"height": 2398,
"content": "## \ud83c\udfaf **Your Workflow: Territory Performance Analyzer & Reassigner**\n\n**\u2728 Purpose:**\nEvery week, this automation **scrapes fresh regional sales data**, splits it cleanly, saves it to a tracking sheet, and sends a smart email update if anything needs your attention \u2014 **all without you doing a thing!**\n\n---\n\n## \u2705 **\ud83d\udd39 Section 1: Trigger & Prepare**\n\n**Nodes:**\n1\ufe0f\u20e3 `Weekly Territory Check` *(Schedule Trigger)*\n2\ufe0f\u20e3 `Prepare Request Params` *(Edit Fields)*\n\n**\ud83d\udca1 What it does:**\n\n* \u23f0 **Weekly Trigger**: The automation starts **automatically** on a set schedule \u2014 e.g., every Monday at 6 AM \u2014 so you don\u2019t need to remember to run it.\n* \ud83d\udcdd **Prepare Request**: This step **sets up the input** \u2014 like choosing which regions to scrape, date filters, or any special parameters you want the scraper to use.\n\n**\u2728 Why it\u2019s powerful for you:**\n\n* You never forget to update your data.\n* Anyone can **adjust input** (e.g., change region) **without touching the rest of the workflow**.\n* Perfect for **zero-code team edits**.\n\n---\n\n## \u2705 **\ud83d\udd39 Section 2: Smart Data Collection & Parsing**\n\n**Nodes:**\n3\ufe0f\u20e3 `Run Bright Data Scraper` *(AI Agent)*\n\u2014 uses \u23ec\n\n* `Bright Data MCP Tool` *(MCP Client)*\n* `LLM Prompt Handler` *(OpenAI Chat Model)*\n* `Fix/Format Scraper Output` *(Auto-fixing Output Parser)*\n* `Validation Assistant` *(OpenAI Chat Model1)*\n* `Final Output Formatter` *(Structured Output Parser)*\n\n**\ud83d\udca1 What it does:**\n\n* \ud83e\udd16 The **AI Agent** talks to the **Bright Data MCP Tool** to **scrape live data** from your target sites.\n* \ud83e\udde0 The **LLM Prompt Handler** helps the AI figure out what pages to crawl, what data to look for, and how to handle tricky websites.\n* \ud83e\uddf9 The **Auto-fixer & Parsers** make sure your scraped data is always **clean JSON**, so you never get errors in the next steps.\n\n**\u2728 Why it\u2019s powerful for you:**\n\n* This section handles all the **dirty work** of web scraping & fixing messy data.\n* You **don\u2019t write code or worry about site changes** \u2014 the agent + model fix issues automatically.\n* If a page changes, the AI adjusts how it scrapes, so you\u2019re not stuck fixing broken scrapers every week.\n\n---\n\n## \u2705 **\ud83d\udd39 Section 3: Process, Save & Notify**\n\n**Nodes:**\n4\ufe0f\u20e3 `Split Stores to Items` *(Code)*\n5\ufe0f\u20e3 `Update Regional Data Sheet` *(Google Sheets)*\n6\ufe0f\u20e3 `Send Notification Email` *(Gmail)*\n\n**\ud83d\udca1 What it does:**\n\n* \u2699\ufe0f The `Split Stores to Items` node **unwraps** the single big output from the scraper \u2192 breaks it into **one item per store** so you can work with them individually.\n* \ud83d\udcca The `Update Regional Data Sheet` node **writes each store\u2019s info** into Google Sheets \u2014 creating a clean, always-up-to-date record of all your stores & their sales.\n* \ud83d\udce7 The `Send Notification Email` node **alerts you automatically** if anything needs attention \u2014 for example, \u201cHey, Region North has 20% higher load than Region South. Reassign recommended!\u201d\n\n**\u2728 Why it\u2019s powerful for you:**\n\n* You get **fresh, structured data** to review any time.\n* No manual copy/paste \u2192 your team sees **live performance trends**.\n* Automated emails keep your sales leads or managers in the loop without extra work.\n\n---\n\n## \ud83c\udf89 **\ud83d\udd11 How a Beginner Can Use This**\n\n\u2705 **No coding:** Everything runs with prebuilt nodes.\n\u2705 **Flexible:** Change your schedule, filters, or regions without breaking the flow.\n\u2705 **Scalable:** Easily add more stores, new regions, or extra tools \u2014 e.g., auto-publish to Airtable or a dashboard.\n\u2705 **Fully Automated:** Wake up Monday \u2192 check your sheet \u2192 know exactly where to adjust territories.\n\n---\n\n## \u2705 **\ud83c\udf1f Visual Summary with Icons**\n\n| Section | Steps | Icon |\n| ---------------------- | -------------------------------------------------- | -------- |\n| **1\ufe0f\u20e3 Trigger & Prep** | \ud83d\udd52 Weekly schedule \u2192 \ud83d\udcdd set scrape parameters | \u23f0 \u270f\ufe0f |\n| **2\ufe0f\u20e3 Collect & Fix** | \ud83e\udd16 AI scrapes \u2192 \ud83e\udde0 LLM helps \u2192 \ud83e\uddf9 Fix bad data | \ud83e\udd16 \ud83e\udde0 \ud83e\uddf9 |\n| **3\ufe0f\u20e3 Process & Act** | \ud83d\udd17 Split items \u2192 \ud83d\udcca Save to Sheets \u2192 \ud83d\udce7 Send email | \u2699\ufe0f \ud83d\udcca \ud83d\udce7 |\n\n---\n\n## \ud83d\uddc2\ufe0f **Result:**\n\n**Zero-hassle, fully automated territory management**, designed for **non-coders**, **sales ops**, or any small business owner.\n\n---\n\n"
},
"typeVersion": 1
},
{
"id": "8d32a7e9-423f-4c22-8356-d59302e9afd5",
"name": "Auto-fixing Output Parser",
"type": "@n8n/n8n-nodes-langchain.outputParserAutofixing",
"position": [
720,
280
],
"parameters": {
"options": {}
},
"typeVersion": 1
},
{
"id": "02d03b02-4186-4c9a-aa7c-dd9a0eddf39c",
"name": "OpenAI Chat Model",
"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
"position": [
700,
500
],
"parameters": {
"model": {
"__rl": true,
"mode": "list",
"value": "gpt-4o-mini"
},
"options": {}
},
"credentials": {
"openAiApi": {
"name": "<your credential>"
}
},
"typeVersion": 1.2
},
{
"id": "85bbb951-75ca-48ba-bd56-9763b0d8bd58",
"name": "Structured Output Parser1",
"type": "@n8n/n8n-nodes-langchain.outputParserStructured",
"position": [
860,
500
],
"parameters": {
"jsonSchemaExample": "[\n {\n \"store_id\": \"ST-101\",\n \"store_name\": \"SuperMart Downtown\",\n \"address\": \"123 Main St, Springfield\",\n \"region\": \"North Region\",\n \"estimated_sales\": 125000,\n \"last_updated\": \"2025-07-09\"\n },\n {\n \"store_id\": \"ST-102\",\n \"store_name\": \"SuperMart East Side\",\n \"address\": \"456 Maple Ave, Springfield\",\n \"region\": \"North Region\",\n \"estimated_sales\": 98000,\n \"last_updated\": \"2025-07-09\"\n },\n {\n \"store_id\": \"ST-103\",\n \"store_name\": \"SuperMart Riverside\",\n \"address\": \"789 River Rd, Rivertown\",\n \"region\": \"South Region\",\n \"estimated_sales\": 73000,\n \"last_updated\": \"2025-07-09\"\n },\n {\n \"store_id\": \"ST-104\",\n \"store_name\": \"SuperMart Uptown\",\n \"address\": \"321 Oak St, Rivertown\",\n \"region\": \"South Region\",\n \"estimated_sales\": 67000,\n \"last_updated\": \"2025-07-09\"\n },\n {\n \"store_id\": \"ST-105\",\n \"store_name\": \"SuperMart West End\",\n \"address\": \"555 Elm St, Lake City\",\n \"region\": \"West Region\",\n \"estimated_sales\": 115000,\n \"last_updated\": \"2025-07-09\"\n }\n]\n"
},
"typeVersion": 1.2
}
],
"active": false,
"settings": {
"executionOrder": "v1"
},
"versionId": "e5410ef0-2611-442f-894a-4ebf7ab5ba3d",
"connections": {
"OpenAI Chat Model": {
"ai_languageModel": [
[
{
"node": "Auto-fixing Output Parser",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"LLM Prompt Handler": {
"ai_languageModel": [
[
{
"node": "Run Bright Data Scraper",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Bright Data MCP Tool": {
"ai_tool": [
[
{
"node": "Run Bright Data Scraper",
"type": "ai_tool",
"index": 0
}
]
]
},
"Split Stores to Items": {
"main": [
[
{
"node": "Update Regional Data Sheet",
"type": "main",
"index": 0
}
]
]
},
"Prepare Request Params": {
"main": [
[
{
"node": "Run Bright Data Scraper",
"type": "main",
"index": 0
}
]
]
},
"Weekly Territory Check": {
"main": [
[
{
"node": "Prepare Request Params",
"type": "main",
"index": 0
}
]
]
},
"Run Bright Data Scraper": {
"main": [
[
{
"node": "Split Stores to Items",
"type": "main",
"index": 0
},
{
"node": "Send Notification Email",
"type": "main",
"index": 0
}
]
]
},
"Auto-fixing Output Parser": {
"ai_outputParser": [
[
{
"node": "Run Bright Data Scraper",
"type": "ai_outputParser",
"index": 0
}
]
]
},
"Structured Output Parser1": {
"ai_outputParser": [
[
{
"node": "Auto-fixing Output Parser",
"type": "ai_outputParser",
"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.
gmailOAuth2googleSheetsOAuth2ApimcpClientApiopenAiApi
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
This workflow automatically analyzes sales territory performance, comparing revenue, win rates, and activity across regions. Remove the guesswork from territory planning and drive balanced growth.
Source: https://n8n.io/workflows/5976/ — 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.
Note: This template is for self-hosted n8n instances only
This workflow contains community nodes that are only compatible with the self-hosted version of n8n.
This workflow contains community nodes that are only compatible with the self-hosted version of n8n.
This workflow contains community nodes that are only compatible with the self-hosted version of n8n.
This workflow automatically monitors social media advertising performance across platforms to track campaign effectiveness and ROI. It saves you time by eliminating the need to manually check multiple