{
  "id": "GNCdvewzo4dEsUYN",
  "name": "Competitor Price Tracker",
  "active": false,
  "isArchived": false,
  "versionId": "022552b6-a7a4-4028-8841-923149421d57",
  "settings": {
    "executionOrder": "v1",
    "availableInMCP": true
  },
  "connections": {
    "Daily 08:00 Trigger": {
      "main": [
        [
          {
            "node": "Read Competitor List",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Read Competitor List": {
      "main": [
        [
          {
            "node": "Loop Over Competitors",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Scrape Pricing Page": {
      "main": [
        [
          {
            "node": "Extract and Compare Price",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract and Compare Price": {
      "main": [
        [
          {
            "node": "Price Changed?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Price Changed?": {
      "main": [
        [
          {
            "node": "Alert Price Change",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Update Last Checked",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Alert Price Change": {
      "main": [
        [
          {
            "node": "Update Price and Timestamp",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Update Price and Timestamp": {
      "main": [
        [
          {
            "node": "Loop Over Competitors",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Loop Over Competitors": {
      "main": [
        [
          {
            "node": "Done",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Scrape Pricing Page",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Update Last Checked": {
      "main": [
        [
          {
            "node": "Loop Over Competitors",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "nodes": [
    {
      "id": "c8c38140-bb37-4722-b4fa-547af8196adc",
      "name": "Daily 08:00 Trigger",
      "type": "n8n-nodes-base.scheduleTrigger",
      "typeVersion": 1.3,
      "position": [
        0,
        272
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "cronExpression",
              "expression": "0 8 * * *"
            }
          ]
        }
      }
    },
    {
      "id": "3b315f7c-77d9-4840-bb30-a13713b463c4",
      "name": "Read Competitor List",
      "type": "n8n-nodes-base.googleSheets",
      "typeVersion": 4.7,
      "position": [
        224,
        272
      ],
      "parameters": {
        "resource": "sheet",
        "operation": "read",
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $vars.COMPETITOR_SHEET_ID }}"
        },
        "sheetName": {
          "__rl": true,
          "mode": "name",
          "value": "Competitors"
        },
        "options": {
          "returnAllMatches": "returnAllMatches"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      }
    },
    {
      "id": "d9f12fe0-d4e3-4f4a-9588-065b91fc015d",
      "name": "Done",
      "type": "n8n-nodes-base.noOp",
      "typeVersion": 1,
      "position": [
        672,
        0
      ],
      "parameters": {}
    },
    {
      "id": "04f0ae26-f0d8-42b6-9e96-6434e1a3a837",
      "name": "Scrape Pricing Page",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.4,
      "position": [
        672,
        192
      ],
      "parameters": {
        "method": "GET",
        "url": "={{ $json.url }}",
        "options": {
          "timeout": 15000,
          "response": {
            "response": {
              "neverError": true,
              "responseFormat": "text",
              "outputPropertyName": "body"
            }
          }
        }
      }
    },
    {
      "id": "1505802e-d432-429f-a943-20bc622f5b7a",
      "name": "Extract and Compare Price",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        896,
        192
      ],
      "parameters": {
        "mode": "runOnceForEachItem",
        "language": "javaScript",
        "jsCode": "const html = $input.item.json?.body ?? '';\nconst competitorName = $('Loop Over Competitors').item.json.name;\nconst competitorUrl = $('Loop Over Competitors').item.json.url;\nconst lastPrice = $('Loop Over Competitors').item.json.last_price ?? '';\n\nconst pricePatterns = [\n  /\\$[\\d,]+\\.?\\d*/,\n  /USD\\s*[\\d,]+\\.?\\d*/i,\n  /[\\d,]+\\.?\\d*\\s*USD/i,\n  /\u20ac[\\d,]+\\.?\\d*/,\n  /\u00a3[\\d,]+\\.?\\d*/,\n  /[\\d,]+\\.?\\d*\\s*VND/i,\n  /[\\d,.]+/\n];\n\nlet currentPrice = '';\nfor (const pattern of pricePatterns) {\n  const match = html.match(pattern);\n  if (match) {\n    currentPrice = match[0].trim();\n    break;\n  }\n}\nif (!currentPrice) currentPrice = 'NOT_FOUND';\n\nconst priceChanged = currentPrice !== 'NOT_FOUND' && currentPrice !== lastPrice;\nconst now = new Date().toISOString();\n\nreturn {\n  json: {\n    name: competitorName,\n    url: competitorUrl,\n    current_price: currentPrice,\n    last_price: lastPrice,\n    price_changed: priceChanged,\n    checked_at: now\n  }\n};"
      }
    },
    {
      "id": "1affff4f-09fc-499f-a4c3-1cbcfbdbb520",
      "name": "Price Changed?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.3,
      "position": [
        1120,
        192
      ],
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict"
          },
          "conditions": [
            {
              "leftValue": "={{ $json.price_changed }}",
              "operator": {
                "type": "boolean",
                "operation": "true"
              },
              "rightValue": ""
            }
          ],
          "combinator": "and"
        }
      }
    },
    {
      "id": "8ba89714-b8bc-48e3-9447-37d55041244e",
      "name": "Alert Price Change",
      "type": "n8n-nodes-base.slack",
      "typeVersion": 2.5,
      "position": [
        1344,
        96
      ],
      "parameters": {
        "resource": "message",
        "operation": "post",
        "authentication": "accessToken",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "name",
          "value": "#pricing-alerts"
        },
        "messageType": "text",
        "text": "={{ '\ud83d\udcb0 *Price Change Detected!*\\n*' + $json.name + '*\\nOld: ' + ($json.last_price || 'unknown') + ' \u2192 New: ' + $json.current_price + '\\n\ud83d\udd17 ' + $json.url }}"
      },
      "credentials": {
        "slackApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "id": "72aec372-320b-4cc1-a82f-4c2e3f9e6763",
      "name": "Update Price and Timestamp",
      "type": "n8n-nodes-base.googleSheets",
      "typeVersion": 4.7,
      "position": [
        1568,
        272
      ],
      "parameters": {
        "resource": "sheet",
        "operation": "update",
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $vars.COMPETITOR_SHEET_ID }}"
        },
        "sheetName": {
          "__rl": true,
          "mode": "name",
          "value": "Competitors"
        },
        "columns": {
          "mappingMode": "defineBelow",
          "value": {
            "url": "={{ $json.url }}",
            "last_price": "={{ $json.current_price }}",
            "last_changed": "={{ $json.checked_at }}",
            "last_checked": "={{ $json.checked_at }}"
          },
          "matchingColumns": [
            "url"
          ],
          "schema": [
            {
              "id": "url",
              "displayName": "url",
              "required": false,
              "defaultMatch": true,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "last_price",
              "displayName": "last_price",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": false
            },
            {
              "id": "last_changed",
              "displayName": "last_changed",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": false
            },
            {
              "id": "last_checked",
              "displayName": "last_checked",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": false
            }
          ]
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      }
    },
    {
      "id": "e8e370db-2761-4d93-8128-2de144f7aded",
      "name": "Loop Over Competitors",
      "type": "n8n-nodes-base.splitInBatches",
      "typeVersion": 3,
      "position": [
        448,
        272
      ],
      "parameters": {
        "batchSize": 1
      }
    },
    {
      "id": "9c3e173a-4091-48c5-9524-33a00bbdadf5",
      "name": "Update Last Checked",
      "type": "n8n-nodes-base.googleSheets",
      "typeVersion": 4.7,
      "position": [
        1344,
        288
      ],
      "parameters": {
        "resource": "sheet",
        "operation": "update",
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $vars.COMPETITOR_SHEET_ID }}"
        },
        "sheetName": {
          "__rl": true,
          "mode": "name",
          "value": "Competitors"
        },
        "columns": {
          "mappingMode": "defineBelow",
          "value": {
            "url": "={{ $json.url }}",
            "last_checked": "={{ $json.checked_at }}"
          },
          "matchingColumns": [
            "url"
          ],
          "schema": [
            {
              "id": "url",
              "displayName": "url",
              "required": false,
              "defaultMatch": true,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "last_checked",
              "displayName": "last_checked",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": false
            }
          ]
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      }
    }
  ],
  "tags": [],
  "meta": {
    "aiBuilderAssisted": true,
    "builderVariant": "mcp"
  },
  "description": "Daily automated competitor pricing monitor. Reads competitor URLs from Google Sheets, scrapes pricing pages, compares prices, sends Slack alerts on changes, and logs results back to the sheet."
}