{
  "name": "01 Price drop & restock alerts (any store)",
  "nodes": [
    {
      "parameters": {
        "content": "## Price drop & restock alerts\nChecks your product URLs every 6 hours and pings you only when a price drops or an item is back in stock.\n\n1. Open **Config** and paste your Apify API token (free account: console.apify.com -> Settings -> API & Integrations).\n2. Paste a Discord/Slack webhook URL and/or a Telegram bot token + chat ID (delete the node you don't use).\n3. Click **Test workflow**, then switch it to **Active**.",
        "height": 340,
        "width": 420
      },
      "name": "How to use",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        0,
        -400
      ],
      "id": "a4353515-f44e-4228-bb14-a2f0840fa928"
    },
    {
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "hours",
              "hoursInterval": 6
            }
          ]
        }
      },
      "name": "Schedule",
      "type": "n8n-nodes-base.scheduleTrigger",
      "typeVersion": 1.2,
      "position": [
        0,
        0
      ],
      "id": "2e822bbc-dd2e-4d8c-89f2-c52ca320d935"
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "2405c9c6-92cf-48d1-8434-35e23811fc7b",
              "name": "apifyToken",
              "value": "YOUR_APIFY_TOKEN",
              "type": "string"
            },
            {
              "id": "a52a7c92-9ef9-4bc2-b5e2-eaf85e7379dd",
              "name": "webhookUrl",
              "value": "https://discord.com/api/webhooks/...",
              "type": "string"
            },
            {
              "id": "57ce47ba-bc1e-4f8d-93b5-f9ed9f3faf61",
              "name": "telegramBotToken",
              "value": "",
              "type": "string"
            },
            {
              "id": "357b8523-e5d6-4c76-a746-3bc2a496f757",
              "name": "telegramChatId",
              "value": "",
              "type": "string"
            },
            {
              "id": "1c00389b-2aed-4bca-be99-ece37080a324",
              "name": "productUrls",
              "value": "https://www.allbirds.com/products/mens-tree-runners, https://www.allbirds.com/products/womens-tree-runners",
              "type": "string"
            },
            {
              "id": "7142274e-eee4-4977-804b-629ad76521bf",
              "name": "minDropPercent",
              "value": 5,
              "type": "number"
            }
          ]
        },
        "options": {}
      },
      "name": "Config",
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        220,
        0
      ],
      "id": "3b7eb8c5-4840-4fd6-8841-555b81ca8d75"
    },
    {
      "parameters": {
        "method": "POST",
        "url": "=https://api.apify.com/v2/acts/martin10291~price-drop-monitor/run-sync-get-dataset-items",
        "sendQuery": true,
        "queryParameters": {
          "parameters": [
            {
              "name": "token",
              "value": "={{ $('Config').item.json.apifyToken }}"
            },
            {
              "name": "timeout",
              "value": "280"
            }
          ]
        },
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={{ JSON.stringify({productUrls: $('Config').item.json.productUrls.split(',').map(s => s.trim()), watchlistName: 'n8n', minDropPercent: Number($('Config').item.json.minDropPercent), onlyChanges: true}) }}",
        "options": {
          "timeout": 300000
        }
      },
      "name": "Run Apify scraper",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        440,
        0
      ],
      "id": "3ef1236f-b645-4b7f-b820-d891b1b31fa6"
    },
    {
      "parameters": {
        "jsCode": "const rows = $input.all();\nif (!rows.length) return [];\nconst d = rows.map(i => i.json).filter(r => ['price_drop','back_in_stock'].includes(r.change));\nif (!d.length) return [];\nconst text = 'Price alert:\\n' + d.map(r => `${r.change === 'price_drop' ? '📉' : '✅'} ${r.title}: ${r.previousPrice} → ${r.price} ${r.currency || ''} ${r.changePercent != null ? '(' + r.changePercent + '%)' : ''}\\n${r.url}`).join('\\n\\n');\nreturn [{ json: { text } }];"
      },
      "name": "Format message",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        660,
        0
      ],
      "id": "5f01ed7a-4b83-46f7-bf21-de37ff7a719e"
    },
    {
      "parameters": {
        "method": "POST",
        "url": "={{ $('Config').item.json.webhookUrl }}",
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={{ JSON.stringify({content: $json.text, text: $json.text}) }}",
        "options": {}
      },
      "name": "Send to Discord or Slack",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        880,
        0
      ],
      "id": "2e0567e6-fca3-41d4-be5c-898ded19b3b0"
    },
    {
      "parameters": {
        "method": "POST",
        "url": "=https://api.telegram.org/bot{{ $('Config').item.json.telegramBotToken }}/sendMessage",
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={{ JSON.stringify({chat_id: $('Config').item.json.telegramChatId, text: $json.text, disable_web_page_preview: true}) }}",
        "options": {}
      },
      "name": "Send to Telegram",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        880,
        200
      ],
      "id": "2e70b6c8-1876-41e5-ab64-aba5f2b77533"
    }
  ],
  "connections": {
    "Schedule": {
      "main": [
        [
          {
            "node": "Config",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Config": {
      "main": [
        [
          {
            "node": "Run Apify scraper",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Run Apify scraper": {
      "main": [
        [
          {
            "node": "Format message",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Format message": {
      "main": [
        [
          {
            "node": "Send to Discord or Slack",
            "type": "main",
            "index": 0
          },
          {
            "node": "Send to Telegram",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "settings": {
    "executionOrder": "v1"
  },
  "pinData": {},
  "active": false
}