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