AutomationFlowsWeb Scraping › E-commerce Price Monitor with Firecrawl, Claude-sonnet AI & Telegram Alerts

E-commerce Price Monitor with Firecrawl, Claude-sonnet AI & Telegram Alerts

ByCheng Siong Chin @cschin on n8n.io

Automate price monitoring for e-commerce competitors—ideal for retailers, analysts, and pricing teams. Scrapes competitor sites, extracts pricing/stock data via AI, detects changes, and sends instant alerts for dynamic pricing strategies.

Cron / scheduled trigger★★★★☆ complexityAI-powered19 nodes@Mendable/N8N Nodes FirecrawlPerplexityHTTP RequestGoogle SheetsAnthropicTelegram
Web Scraping Trigger: Cron / scheduled Nodes: 19 Complexity: ★★★★☆ AI nodes: yes Added:
E-commerce Price Monitor with Firecrawl, Claude-sonnet AI & Telegram Alerts — n8n workflow card showing @Mendable/N8N Nodes Firecrawl, Perplexity, HTTP Request integration

This workflow corresponds to n8n.io template #10216 — we link there as the canonical source.

This workflow follows the Google Sheets → HTTP Request 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 →

Download .json
{
  "id": "YnD0kvM9AYMjYxmj",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "Multi-Site Product Price Monitor: Claude-Sonnet , Google Sheets & Telegram Alert",
  "tags": [
    {
      "id": "7zsdOA50QGm7RNqx",
      "name": "Monitoring",
      "createdAt": "2025-10-23T16:41:17.031Z",
      "updatedAt": "2025-10-23T16:41:17.031Z"
    },
    {
      "id": "BL8TsHYj5FkNYzfi",
      "name": "E-commerce",
      "createdAt": "2025-10-23T16:41:16.985Z",
      "updatedAt": "2025-10-23T16:41:16.985Z"
    },
    {
      "id": "dlf9zFSN3j6s2jgO",
      "name": "Business Intelligence",
      "createdAt": "2025-10-23T16:41:17.008Z",
      "updatedAt": "2025-10-23T16:41:17.008Z"
    },
    {
      "id": "lpozR2Ct8reF9bCk",
      "name": "AI",
      "createdAt": "2025-10-23T16:41:17.062Z",
      "updatedAt": "2025-10-23T16:41:17.062Z"
    }
  ],
  "nodes": [
    {
      "id": "306294b3-27b8-4821-9b04-0e8d210af07e",
      "name": "\u23f0 Monitor Every 6 Hours",
      "type": "n8n-nodes-base.scheduleTrigger",
      "notes": "Triggers the workflow every 6 hours to check competitor data",
      "position": [
        -832,
        352
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "hours",
              "hoursInterval": 6
            }
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "8b934690-1e26-4810-820d-8ff785691adf",
      "name": "Scrape a url and get its content",
      "type": "@mendable/n8n-nodes-firecrawl.firecrawl",
      "position": [
        -1408,
        96
      ],
      "parameters": {
        "url": "https://www.on.com/en-sg/shop/mens/shoes",
        "operation": "scrape",
        "scrapeOptions": {
          "options": {
            "formats": {
              "format": [
                {
                  "type": "json",
                  "prompt": "price of the shoe"
                }
              ]
            },
            "headers": {}
          }
        },
        "requestOptions": {}
      },
      "credentials": {
        "firecrawlApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "90ed5eb7-6236-47e1-88c6-c5278efe24fa",
      "name": "Message a model",
      "type": "n8n-nodes-base.perplexity",
      "position": [
        -1568,
        0
      ],
      "parameters": {
        "model": "sonar",
        "options": {},
        "messages": {
          "message": [
            {
              "content": "Price of the shoe  "
            }
          ]
        },
        "requestOptions": {}
      },
      "credentials": {
        "perplexityApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "e1e006de-d363-4e5a-adbd-77ffc901f42d",
      "name": "Split Out",
      "type": "n8n-nodes-base.splitOut",
      "position": [
        -1296,
        0
      ],
      "parameters": {
        "options": {},
        "fieldToSplitOut": "citations"
      },
      "typeVersion": 1
    },
    {
      "id": "11fdf8bc-aa37-4f42-8bbe-8e16c47c8b47",
      "name": "Get Results Apify",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -1216,
        272
      ],
      "parameters": {
        "url": "https://api.apify.com/v2/acts/compass~google-maps-extractor/runs/last/dataset/items?token=YOUR_TOKEN_HERE API KEY",
        "options": {},
        "authentication": "genericCredentialType",
        "genericAuthType": "httpBearerAuth"
      },
      "credentials": {
        "httpBearerAuth": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.2,
      "alwaysOutputData": true
    },
    {
      "id": "b6a20e25-d82a-493b-b305-066e043f6ba1",
      "name": "Start Actor Apify",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -1616,
        272
      ],
      "parameters": {
        "url": "https://api.apify.com/v2/acts/compass~google-maps-extractor/runs?token=YOUR_TOKEN_HERE API KEY",
        "method": "POST",
        "options": {},
        "jsonBody": "{\n    \"language\": \"en\",\n    \"locationQuery\": \"worldwide\",\n    \"maxCrawledPlacesPerSearch\": 50,\n    \"searchStringsArray\": [\n        \"shoe stores\",\n        \"shoe shops\"\n    ],\n    \"skipClosedPlaces\": false\n}",
        "sendBody": true,
        "specifyBody": "json",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpBearerAuth"
      },
      "credentials": {
        "httpBearerAuth": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.2,
      "alwaysOutputData": true
    },
    {
      "id": "47a1e71a-6bbf-4cfe-82f1-b46744d247ee",
      "name": "Converts unstructured AI text into organized, usable data fields",
      "type": "n8n-nodes-base.code",
      "notes": "Parses and validates the AI extracted data",
      "position": [
        -576,
        192
      ],
      "parameters": {
        "jsCode": "// Parse AI response and clean data\nconst items = [];\n\nfor (const item of $input.all()) {\n  try {\n    // Parse the AI response\n    let parsed;\n    const response = item.json.choices?.[0]?.message?.content || item.json.message || '';\n    \n    // Remove markdown code blocks if present\n    const cleaned = response.replace(/```json\\n?|```\\n?/g, '').trim();\n    \n    try {\n      parsed = JSON.parse(cleaned);\n    } catch (e) {\n      // Try to extract JSON from the response\n      const jsonMatch = cleaned.match(/\\{[\\s\\S]*\\}/);\n      if (jsonMatch) {\n        parsed = JSON.parse(jsonMatch[0]);\n      } else {\n        throw new Error('Could not parse JSON from AI response');\n      }\n    }\n    \n    // Enrich with metadata\n    items.push({\n      json: {\n        ...parsed,\n        scrapedAt: new Date().toISOString(),\n        priceChange: 0, // Will be calculated in comparison\n        priceChangePercent: 0,\n        isNewLow: false,\n        alertLevel: 'none'\n      }\n    });\n  } catch (error) {\n    console.error('Failed to parse item:', error.message);\n    // Add error item for debugging\n    items.push({\n      json: {\n        error: error.message,\n        rawResponse: item.json,\n        competitorName: 'Parse Error',\n        scrapedAt: new Date().toISOString()\n      }\n    });\n  }\n}\n\nreturn items;"
      },
      "typeVersion": 2
    },
    {
      "id": "3e8d7348-ccef-4cb5-aca4-d5ed6f210199",
      "name": "\ud83d\udd00 Merge Current with Historical1",
      "type": "n8n-nodes-base.merge",
      "notes": "Combines current scrape with historical data for comparison",
      "position": [
        -384,
        224
      ],
      "parameters": {
        "mode": "combine",
        "options": {},
        "fieldsToMatchString": "rawResponse.message.content"
      },
      "typeVersion": 3
    },
    {
      "id": "7e24cbab-31e4-47ba-97f2-9a7a71335905",
      "name": "\ud83d\udd0d Detect Price & Stock Changes1",
      "type": "n8n-nodes-base.code",
      "notes": "Intelligent change detection with alert level classification",
      "position": [
        -208,
        224
      ],
      "parameters": {
        "jsCode": "// Compare current prices with historical and detect changes\nconst results = [];\n\nfor (const item of $input.all()) {\n  const current = item.json;\n  \n  // Skip error items\n  if (current.error) {\n    results.push({ json: current });\n    continue;\n  }\n  \n  // Find historical data for this competitor\n  const historical = $('\ud83d\udcca Read Historical Data').all()\n    .find(h => h.json.competitorName === current.competitorName);\n  \n  let alertLevel = 'none';\n  let changes = [];\n  \n  if (historical && historical.json.currentPrice) {\n    const oldPrice = parseFloat(historical.json.currentPrice);\n    const newPrice = parseFloat(current.currentPrice);\n    const priceChange = newPrice - oldPrice;\n    const priceChangePercent = ((priceChange / oldPrice) * 100).toFixed(2);\n    \n    current.priceChange = priceChange;\n    current.priceChangePercent = parseFloat(priceChangePercent);\n    current.previousPrice = oldPrice;\n    \n    // Determine alert level based on price changes\n    if (Math.abs(priceChangePercent) >= 20) {\n      alertLevel = 'critical';\n      changes.push(`Price ${priceChange > 0 ? 'increased' : 'decreased'} by ${Math.abs(priceChangePercent)}%`);\n    } else if (Math.abs(priceChangePercent) >= 10) {\n      alertLevel = 'warning';\n      changes.push(`Price ${priceChange > 0 ? 'increased' : 'decreased'} by ${Math.abs(priceChangePercent)}%`);\n    } else if (Math.abs(priceChangePercent) >= 5) {\n      alertLevel = 'info';\n      changes.push(`Minor price change: ${priceChangePercent}%`);\n    }\n    \n    // Check if it's a new low price\n    const historicalLow = parseFloat(historical.json.lowestPrice || oldPrice);\n    if (newPrice < historicalLow) {\n      current.isNewLow = true;\n      alertLevel = alertLevel === 'none' ? 'info' : alertLevel;\n      changes.push('\ud83c\udfaf NEW LOWEST PRICE!');\n    }\n    current.lowestPrice = Math.min(newPrice, historicalLow);\n    \n    // Stock level changes\n    if (historical.json.stockLevel !== current.stockLevel) {\n      if (current.stockLevel === 'Out of Stock') {\n        alertLevel = 'critical';\n        changes.push('\ud83d\udce6 Product went OUT OF STOCK');\n      } else if (current.stockLevel === 'Low Stock') {\n        alertLevel = alertLevel === 'none' ? 'warning' : alertLevel;\n        changes.push('\u26a0\ufe0f Stock level is LOW');\n      } else if (historical.json.stockLevel === 'Out of Stock' && current.inStock) {\n        alertLevel = alertLevel === 'none' ? 'info' : alertLevel;\n        changes.push('\u2705 Back in stock!');\n      }\n    }\n    \n    // Rating changes\n    const oldRating = parseFloat(historical.json.rating || 0);\n    const newRating = parseFloat(current.rating || 0);\n    const ratingChange = newRating - oldRating;\n    \n    if (Math.abs(ratingChange) >= 0.5) {\n      alertLevel = alertLevel === 'none' ? 'info' : alertLevel;\n      changes.push(`\u2b50 Rating ${ratingChange > 0 ? 'improved' : 'dropped'} by ${Math.abs(ratingChange).toFixed(1)} stars`);\n    }\n    \n    // Review count changes\n    const oldReviews = parseInt(historical.json.reviewCount || 0);\n    const newReviews = parseInt(current.reviewCount || 0);\n    const reviewDiff = newReviews - oldReviews;\n    \n    if (reviewDiff > 0) {\n      changes.push(`\ud83d\udcac ${reviewDiff} new review${reviewDiff > 1 ? 's' : ''}`);\n    }\n  } else {\n    // First time seeing this competitor\n    alertLevel = 'info';\n    changes.push('\ud83c\udd95 First time tracking this competitor');\n    current.lowestPrice = current.currentPrice;\n  }\n  \n  current.alertLevel = alertLevel;\n  current.changesSummary = changes.join(' | ');\n  current.hasChanges = alertLevel !== 'none';\n  \n  results.push({ json: current });\n}\n\nreturn results;"
      },
      "typeVersion": 2
    },
    {
      "id": "4b8b4578-e6aa-461a-ae0a-7289bd0bf7e3",
      "name": "\ud83d\udcbe Update Historical Data1",
      "type": "n8n-nodes-base.googleSheets",
      "notes": "Saves current data to historical tracking sheet",
      "position": [
        -32,
        320
      ],
      "parameters": {
        "columns": {
          "value": {
            "rating": "={{ $json.rating }}",
            "inStock": "={{ $json.inStock }}",
            "currency": "={{ $json.currency }}",
            "scrapedAt": "={{ $json.scrapedAt }}",
            "productUrl": "={{ $json.productUrl }}",
            "stockLevel": "={{ $json.stockLevel }}",
            "lowestPrice": "={{ $json.lowestPrice }}",
            "productName": "={{ $json.productName }}",
            "reviewCount": "={{ $json.reviewCount }}",
            "currentPrice": "={{ $json.currentPrice }}",
            "originalPrice": "={{ $json.originalPrice }}",
            "competitorName": "={{ $json.competitorName }}"
          },
          "mappingMode": "defineBelow"
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "mode": "name",
          "value": "Historical Data"
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "= {{ $env.GOOGLE_SHEET_ID }}"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "28d2de55-ef62-40cd-a22b-a13eee3c2dc8",
      "name": "When clicking \u2018Execute workflow\u2019",
      "type": "n8n-nodes-base.manualTrigger",
      "position": [
        -1760,
        144
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "62cf73d2-a328-463b-9ea5-0d3fa8e3ba56",
      "name": "\ud83e\udd16 AI Extract Product Data using Claude-Sonnet 4.5",
      "type": "@n8n/n8n-nodes-langchain.anthropic",
      "position": [
        -864,
        192
      ],
      "parameters": {
        "modelId": {
          "__rl": true,
          "mode": "list",
          "value": "claude-sonnet-4-5-20250929",
          "cachedResultName": "claude-sonnet-4-5-20250929"
        },
        "options": {},
        "messages": {
          "values": [
            {
              "content": "You are an accurate e-commerce data parser. From the provided HTML, extract shoe details and output a pure JSON object\u2014no markdown or extra text.\n\nInclude the following fields:\n\n- productName: string \n- currentPrice: number (numeric value only, no currency symbols) \n- originalPrice: number (if discounted, otherwise same as currentPrice) \n- currency: string (USD, EUR, etc.) \n- inStock: boolean \n- stockLevel: string (\"In Stock\", \"Low Stock\", \"Out of Stock\", \"Limited\", etc.) \n- rating: number (0-5 scale) \n- reviewCount: number \n- lastUpdated: string (current ISO timestamp) \n- productUrl: string (from context) \n- competitorName: string (from context)\n\nOutput only the JSON object\u2014no notes, comments, or formatting.\n"
            }
          ]
        }
      },
      "credentials": {
        "anthropicApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "e5998861-2d29-4fdb-a5c0-445cf79ac50e",
      "name": "\ud83d\udd00 Merge Current with Historical",
      "type": "n8n-nodes-base.merge",
      "notes": "Combines current scrape with historical data for comparison",
      "position": [
        -1024,
        176
      ],
      "parameters": {
        "numberInputs": 3
      },
      "typeVersion": 3
    },
    {
      "id": "6815d6c1-43c5-49a8-8f41-eafa0ee83363",
      "name": "\ud83d\udcca Read Historical Data",
      "type": "n8n-nodes-base.googleSheets",
      "notes": "Loads previous scan data for comparison",
      "position": [
        -624,
        352
      ],
      "parameters": {
        "options": {},
        "sheetName": {
          "mode": "name",
          "value": "Historical Data"
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $env.GOOGLE_SHEET_ID }}"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "0c300e39-74da-4947-ab75-1360158f48a1",
      "name": "\ud83d\udcdd Log Alert Details",
      "type": "n8n-nodes-base.googleSheets",
      "notes": "Logs all alerts to separate tracking sheet",
      "position": [
        -48,
        160
      ],
      "parameters": {
        "columns": {
          "value": {
            "rating": "={{ $json.rating }}",
            "timestamp": "={{ $json.scrapedAt }}",
            "alertLevel": "={{ $json.alertLevel }}",
            "productUrl": "={{ $json.productUrl }}",
            "stockLevel": "={{ $json.stockLevel }}",
            "priceChange": "={{ $json.priceChange || 0 }}",
            "productName": "={{ $json.productName }}",
            "currentPrice": "={{ $json.currentPrice }}",
            "previousPrice": "={{ $json.previousPrice || 'N/A' }}",
            "changesSummary": "={{ $json.changesSummary }}",
            "competitorName": "={{ $json.competitorName }}",
            "priceChangePercent": "={{ $json.priceChangePercent || 0 }}"
          },
          "mappingMode": "defineBelow"
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "mode": "name",
          "value": "Alert Log"
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $env.GOOGLE_SHEET_ID }}"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "1833ee8f-13ca-40f3-a3ce-e7c09bbff5fc",
      "name": "Send a text message",
      "type": "n8n-nodes-base.telegram",
      "position": [
        112,
        240
      ],
      "parameters": {
        "text": "The competitors\u2019 pricing has been finalized.",
        "additionalFields": {}
      },
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "1209134e-cb58-4525-bbcb-ffee2a890ddb",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2336,
        -336
      ],
      "parameters": {
        "width": 2576,
        "height": 880,
        "content": "## Introduction\nAutomate price monitoring for e-commerce competitors\u2014ideal for retailers, analysts, and pricing teams. Scrapes competitor sites, \nextracts pricing/stock data via AI, detects changes, and sends instant alerts for dynamic pricing strategies.\n## How It Works\nScrapes competitor URLs via Firecrawl and Apify, extracts data with AI, detects price/stock changes, logs to Google Sheets, and sends Telegram alerts.\n## Workflow Template\nTrigger \u2192 Scrape URL \u2192 AI Extract \u2192 Parse \u2192 Merge Historical \u2192 Detect Changes \u2192 Update Sheets + Send Telegram Alert\n## Workflow Steps\n1. **Trigger & Scrape** \u2192 Manual/scheduled trigger \u2192 Firecrawl + Apify fetch competitor data\n2. **AI Processing** \u2192 Claude extracts product details \u2192 Parses and structures data\n3. **Change Detection** \u2192 Reads historical prices \u2192 Merges with current data \u2192 Identifies updates\n4. **Output** \u2192 Logs alerts to Sheets \u2192 Updates historical data \u2192 Sends Telegram notification\n## Setup Instructions\n**1. Firecrawl API**\nGet key from dashboard \u2192 Add to n8n\n**2. Apify API**\nGet key from console \u2192 Add to n8n \u2192 Configure actors\n**3. AI Model (Claude/OpenAI)**\nGet API key \u2192 Add to n8n\n**4. Google Sheets OAuth2**\nCreate OAuth2 in Google Cloud Console \u2192 Authorize in n8n \u2192 Enable API\n**5. Telegram Bot**\nCreate via BotFather \u2192 Get token & chat ID \u2192 Add to n8n\n**6. Spreadsheet Setup**\nCreate Sheet with required columns \u2192 Copy ID \u2192 Paste in workflow\n## Prerequisites\nSelf-hosted n8n, Firecrawl account, Apify account, Claude/OpenAI API key,\nGoogle account (Sheets OAuth2),Telegram bot\n## Customization\nAdd more URLs, adjust scraping intervals, change detection thresholds, switch to Slack/email alerts,\nintegrate databases\n## Benefits\nSaves 2+ hours daily, real-time tracking, automated alerts, historical analysis, multi-source scraping\n\n"
      },
      "typeVersion": 1
    },
    {
      "id": "864886e9-21d0-402f-8f1f-46216a5e1373",
      "name": "Pause the workflow to let the Apify scraping task finish",
      "type": "n8n-nodes-base.wait",
      "position": [
        -1424,
        272
      ],
      "parameters": {
        "amount": 25
      },
      "typeVersion": 1.1
    },
    {
      "id": "5b798a21-b3e1-4fb4-816a-d32a63367933",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -608,
        -304
      ],
      "parameters": {
        "color": 5,
        "width": 352,
        "height": 256,
        "content": "## Google Sheets Structure\n**Required Columns:**\n- **Product Name** (Column A)\n- **Current Price** (Column B)\n- **Previous Price** (Column C)\n- **Stock Status** (Column D)\n- **Last Updated** (Column E)\n- **URL** (Column F)\n- **Change Detected** (Column G)"
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "7e9182a3-7a64-45a2-9632-3de5d2917fcd",
  "connections": {
    "Split Out": {
      "main": [
        [
          {
            "node": "\ud83d\udd00 Merge Current with Historical",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Message a model": {
      "main": [
        [
          {
            "node": "Split Out",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Results Apify": {
      "main": [
        [
          {
            "node": "\ud83d\udd00 Merge Current with Historical",
            "type": "main",
            "index": 2
          }
        ]
      ]
    },
    "Start Actor Apify": {
      "main": [
        [
          {
            "node": "Pause the workflow to let the Apify scraping task finish",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\ud83d\udcdd Log Alert Details": {
      "main": [
        [
          {
            "node": "Send a text message",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\u23f0 Monitor Every 6 Hours": {
      "main": [
        [
          {
            "node": "\ud83d\udcca Read Historical Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\ud83d\udcca Read Historical Data": {
      "main": [
        [
          {
            "node": "\ud83d\udd00 Merge Current with Historical1",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "\ud83d\udcbe Update Historical Data1": {
      "main": [
        [
          {
            "node": "Send a text message",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Scrape a url and get its content": {
      "main": [
        [
          {
            "node": "\ud83d\udd00 Merge Current with Historical",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "\ud83d\udd00 Merge Current with Historical": {
      "main": [
        [
          {
            "node": "\ud83e\udd16 AI Extract Product Data using Claude-Sonnet 4.5",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\ud83d\udd0d Detect Price & Stock Changes1": {
      "main": [
        [
          {
            "node": "\ud83d\udcbe Update Historical Data1",
            "type": "main",
            "index": 0
          },
          {
            "node": "\ud83d\udcdd Log Alert Details",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\ud83d\udd00 Merge Current with Historical1": {
      "main": [
        [
          {
            "node": "\ud83d\udd0d Detect Price & Stock Changes1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "When clicking \u2018Execute workflow\u2019": {
      "main": [
        [
          {
            "node": "Message a model",
            "type": "main",
            "index": 0
          },
          {
            "node": "Scrape a url and get its content",
            "type": "main",
            "index": 0
          },
          {
            "node": "Start Actor Apify",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\ud83e\udd16 AI Extract Product Data using Claude-Sonnet 4.5": {
      "main": [
        [
          {
            "node": "Converts unstructured AI text into organized, usable data fields",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Pause the workflow to let the Apify scraping task finish": {
      "main": [
        [
          {
            "node": "Get Results Apify",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Converts unstructured AI text into organized, usable data fields": {
      "main": [
        [
          {
            "node": "\ud83d\udd00 Merge Current with Historical1",
            "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.

Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

Automate price monitoring for e-commerce competitors—ideal for retailers, analysts, and pricing teams. Scrapes competitor sites, extracts pricing/stock data via AI, detects changes, and sends instant alerts for dynamic pricing strategies.

Source: https://n8n.io/workflows/10216/ — original creator credit. Request a take-down →

More Web Scraping workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

Web Scraping

Turn any Amazon India product URL into a fully-edited 10-second lifestyle video and auto-publish it to Instagram, Facebook, X (Twitter), LinkedIn, YouTube, and Threads — with platform-optimized captio

HTTP Request, @Apify/N8N Nodes Apify, OpenRouter Chat +3
Web Scraping

Schedule Trigger runs every 6 hours (customizable) Apify Scraper fetches Upwork jobs matching your criteria Deduplication filters out jobs you've already seen AI Scoring (GPT-4) evaluates fit, client

HTTP Request, Google Sheets, OpenAI +2
Web Scraping

Women creators, homemakers-turned-entrepreneurs, and feminine lifestyle brands who want a graceful, low-lift way to keep an eye on competitor content and spark weekly ideas.

HTTP Request, Google Sheets, Email Send +1
Web Scraping

This workflow is Part 2 of the HR Client Acquisition system and builds on the lead discovery pipeline from the previous workflow:

Google Sheets, HTTP Request, OpenAI +2
Web Scraping

Visual Regression Testing With Apify And Ai Vision Model. Uses googleDrive, lmChatGoogleGemini, outputParserStructured, stickyNote. Scheduled trigger; 34 nodes.

Google Drive, Google Gemini Chat, Output Parser Structured +4