Workflow: Amazon Product Price Tracker
Integrations: emailSend, googleSheets, httpRequest, if, scheduleTrigger, set, splitInBatches, stickyNote

{"id": "TqnC0nyAa0LRfYBX", "meta": {"instanceId": "workflow-d76be73e", "versionId": "1.0.0", "createdAt": "2025-09-29T07:07:52.130458", "updatedAt": "2025-09-29T07:07:52.130760", "owner": "n8n-user", "license": "MIT", "category": "automation", "status": "active", "priority": "high", "environment": "production"}, "name": "Amazon Product Price Tracker", "tags": ["automation", "n8n", "production-ready", "excellent", "optimized"], "nodes": [{"id": "cc15c8e6-53f9-4dd1-895f-34a72af4506f", "name": "Products to Monitor", "type": "n8n-nodes-base.googleSheets", "position": [40, -220], "parameters": {"options": {}, "sheetName": {"__rl": true, "mode": "list", "value": "gid=0", "cachedResultUrl": "{{ $env.WEBHOOK_URL }}", "cachedResultName": "Products to Monitor"}, "documentId": {"__rl": true, "mode": "url", "value": "={{ $json.spreadsheet_url }}"}}, "credentials": {"googleSheetsOAuth2Api": {"id": "xWJJNb7VGUUp4vzV", "name": "Google Sheets account 2"}}, "typeVersion": 4.5, "notes": "This googleSheets node performs automated tasks as part of the workflow."}, {"id": "4ec34045-ea02-40bc-a243-b50c804ab947", "name": "Loop Over Items", "type": "n8n-nodes-base.splitInBatches", "position": [260, -220], "parameters": {"options": {}}, "typeVersion": 3, "notes": "This splitInBatches node performs automated tasks as part of the workflow."}, {"id": "d5cdb7eb-144f-477b-83d6-85be5cd2eb79", "name": "Scrapeops - Amazon Product", "type": "n8n-nodes-base.httpRequest", "position": [720, -80], "parameters": {"url": "{{ $env.WEBHOOK_URL }}", "options": {}, "sendQuery": true, "queryParameters": {"parameters": [{"name": "asin", "value": "={{ $('Loop Over Items').item.json.asin }}"}, {"name": "api_key", "value": "={{ $('Setup').item.json.scrapeops_apikey }}"}]}}, "typeVersion": 4.2, "notes": "This httpRequest node performs automated tasks as part of the workflow."}, {"id": "32134749-17e9-456a-9814-2e03b34ce37b", "name": "Fields", "type": "n8n-nodes-base.set", "position": [940, -80], "parameters": {"options": {}, "assignments": {"assignments": [{"id": "ae829540-06b7-4ea8-a5f8-d2750b02c530", "name": "name", "type": "string", "value": "={{ $json.data.name }}"}, {"id": "4dec41ce-3522-481b-985f-455c858702e0", "name": "pricing", "type": "number", "value": "={{ parseFloat(($json.data.pricing || \"\").replace(/[^\\d.-]/g, \"\")) || 0 }}"}, {"id": "ebb64d89-e9b2-4384-9778-fce8aa9eb3be", "name": "product_url", "type": "string", "value": "={{ $env.WEBHOOK_URL }}{{ $('Loop Over Items').item.json.asin }}?th=1&psc=1"}]}}, "typeVersion": 3.4, "notes": "This set node performs automated tasks as part of the workflow."}, {"id": "954afd09-609f-4ed1-94a0-6d6431b8a9e6", "name": "Last Price", "type": "n8n-nodes-base.set", "position": [480, -80], "parameters": {"options": {}, "assignments": {"assignments": [{"id": "db85d431-5631-4629-99f8-426ec3d7ecc7", "name": "last_pricing", "type": "number", "value": "={{ $json.pricing }}"}]}}, "typeVersion": 3.4, "notes": "This set node performs automated tasks as part of the workflow."}, {"id": "695673df-6bf7-4e64-898c-f143c77c8ff0", "name": "Price Change", "type": "n8n-nodes-base.set", "position": [1420, -180], "parameters": {"options": {}, "assignments": {"assignments": [{"id": "4ef9bde2-62d3-4d6a-9759-4ae6c13db127", "name": "price_change", "type": "number", "value": "={{ \n  $('Last Price').item.json.last_pricing !== \"\" && $('Last Price').item.json.last_pricing !== undefined ? \n  ($json.pricing - $('Last Price').item.json.last_pricing).toFixed(2) : \n  0 \n}}"}, {"id": "02e5a84b-76bf-4511-a78d-c725882a64dc", "name": "percent_change", "type": "number", "value": "={{ \n  $('Last Price').item.json.last_pricing !== \"\" && $('Last Price').item.json.last_pricing !== undefined && parseFloat($('Last Price').item.json.last_pricing) !== 0 ? \n  ((($json.pricing - $('Last Price').item.json.last_pricing) / $('Last Price').item.json.last_pricing)).toFixed(2) : \n  0 \n}}"}]}}, "typeVersion": 3.4, "notes": "This set node performs automated tasks as part of the workflow."}, {"id": "ab56b334-c4a7-45f7-95d0-9c7e990c21d7", "name": "Alert Status", "type": "n8n-nodes-base.set", "position": [1600, -180], "parameters": {"options": {}, "assignments": {"assignments": [{"id": "fd261f8a-8417-4fdb-95de-bd71768300e6", "name": "alert_status", "type": "string", "value": "={{ \n  $json.percent_change > $('Loop Over Items').item.json.alert_threshold_high ? \n  \"High\" : \n  ($json.percent_change < $('Loop Over Items').item.json.alert_threshold_low ? \n    \"Low\" : \n    \"\")\n}}"}]}}, "typeVersion": 3.4, "notes": "This set node performs automated tasks as part of the workflow."}, {"id": "54f3ef24-58bc-4eba-b341-b14ab9f66d68", "name": "Insert - Price History", "type": "n8n-nodes-base.googleSheets", "position": [2020, -180], "parameters": {"columns": {"value": {"asin": "={{ $('Loop Over Items').item.json.asin }}", "pricing": "={{ $('Scrapeops - Amazon Product').item.json.data.pricing.replace(/[^\\d.]/g, '') }}", "timestamp": "={{$now.format(\"MM/dd/yyyy HH:mm:ss\")}}"}, "schema": [{"id": "asin", "type": "string", "display": true, "removed": false, "required": false, "displayName": "asin", "defaultMatch": false, "canBeUsedToMatch": true}, {"id": "pricing", "type": "string", "display": true, "removed": false, "required": false, "displayName": "pricing", "defaultMatch": false, "canBeUsedToMatch": true}, {"id": "timestamp", "type": "string", "display": true, "removed": false, "required": false, "displayName": "timestamp", "defaultMatch": false, "canBeUsedToMatch": true}], "mappingMode": "defineBelow", "matchingColumns": [], "attemptToConvertTypes": false, "convertFieldsToString": false}, "options": {}, "operation": "append", "sheetName": {"__rl": true, "mode": "name", "value": "Price History"}, "documentId": {"__rl": true, "mode": "url", "value": "={{ $('Setup').item.json.spreadsheet_url }}"}}, "credentials": {"googleSheetsOAuth2Api": {"id": "xWJJNb7VGUUp4vzV", "name": "Google Sheets account 2"}}, "typeVersion": 4.5, "notes": "This googleSheets node performs automated tasks as part of the workflow."}, {"id": "b161e44b-1fbf-40f1-a485-a7b132f42efc", "name": "Update - Products to Monitor", "type": "n8n-nodes-base.googleSheets", "position": [1800, -180], "parameters": {"columns": {"value": {"asin": "={{ $('Loop Over Items').item.json.asin }}", "name": "={{ $('Scrapeops - Amazon Product').item.json.data.name }}", "pricing": "={{ $('Scrapeops - Amazon Product').item.json.data.pricing.replace(/[^\\d.]/g, '') }}", "product_url": "{{ $env.BASE_URL }}", "alert_status": "={{ $json.alert_status }}", "last_updated": "={{$now.format(\"MM/dd/yyyy HH:mm:ss\")}}", "price_change": "={{ $('Price Change').item.json.price_change }}", "average_rating": "={{ $('Scrapeops - Amazon Product').item.json.data.average_rating }}", "percent_change": "={{ $('Price Change').item.json.percent_change }}"}, "schema": [{"id": "asin", "type": "string", "display": true, "removed": false, "required": false, "displayName": "asin", "defaultMatch": false, "canBeUsedToMatch": true}, {"id": "alert_threshold_low", "type": "string", "display": true, "removed": true, "required": false, "displayName": "alert_threshold_low", "defaultMatch": false, "canBeUsedToMatch": true}, {"id": "alert_threshold_high", "type": "string", "display": true, "removed": true, "required": false, "displayName": "alert_threshold_high", "defaultMatch": false, "canBeUsedToMatch": true}, {"id": "name", "type": "string", "display": true, "required": false, "displayName": "name", "defaultMatch": false, "canBeUsedToMatch": true}, {"id": "average_rating", "type": "string", "display": true, "required": false, "displayName": "average_rating", "defaultMatch": false, "canBeUsedToMatch": true}, {"id": "product_url", "type": "string", "display": true, "required": false, "displayName": "product_url", "defaultMatch": false, "canBeUsedToMatch": true}, {"id": "pricing", "type": "string", "display": true, "required": false, "displayName": "pricing", "defaultMatch": false, "canBeUsedToMatch": true}, {"id": "price_change", "type": "string", "display": true, "removed": false, "required": false, "displayName": "price_change", "defaultMatch": false, "canBeUsedToMatch": true}, {"id": "percent_change", "type": "string", "display": true, "removed": false, "required": false, "displayName": "percent_change", "defaultMatch": false, "canBeUsedToMatch": true}, {"id": "alert_status", "type": "string", "display": true, "removed": false, "required": false, "displayName": "alert_status", "defaultMatch": false, "canBeUsedToMatch": true}, {"id": "last_updated", "type": "string", "display": true, "removed": false, "required": false, "displayName": "last_updated", "defaultMatch": false, "canBeUsedToMatch": true}, {"id": "row_number", "type": "string", "display": true, "removed": true, "readOnly": true, "required": false, "displayName": "row_number", "defaultMatch": false, "canBeUsedToMatch": true}], "mappingMode": "defineBelow", "matchingColumns": ["asin"], "attemptToConvertTypes": false, "convertFieldsToString": false}, "options": {}, "operation": "update", "sheetName": {"__rl": true, "mode": "name", "value": "Products to Monitor"}, "documentId": {"__rl": true, "mode": "url", "value": "={{ $('Setup').item.json.spreadsheet_url }}"}}, "credentials": {"googleSheetsOAuth2Api": {"id": "xWJJNb7VGUUp4vzV", "name": "Google Sheets account 2"}}, "typeVersion": 4.5, "notes": "This googleSheets node performs automated tasks as part of the workflow."}, {"id": "62372099-de2a-4dcf-afdf-e9d9697a7a95", "name": "Send Email", "type": "n8n-nodes-base.emailSend", "position": [2560, 120], "webhookId": "c0eb28fe-1c74-4692-9701-3790014c8951", "parameters": {"html": "=<!DOCTYPE html>\n<html>\n<head>\n    <style>\n        body { font-family: Arial, sans-serif; line-height: 1.6; color: #333; }\n        .container { max-width: 600px; margin: 0 auto; padding: 20px; background: #fff; }\n        .header { text-align: center; padding-bottom: 15px; border-bottom: 1px solid #eee; }\n        .price-up { color: #d64541; font-weight: bold; }\n        .price-down { color: #27ae60; font-weight: bold; }\n        .price-details { background: #f5f5f5; padding: 15px; margin: 15px 0; border-radius: 5px; }\n    .button {\n        display: block;\n        background-color: #2c3e50;\n        color: white !important; \n        text-decoration: none;\n        text-align: center;\n        padding: 10px;\n        border-radius: 4px;\n        margin: 20px auto;\n        width: 200px;\n        font-weight: bold;\n    }\n    .button:visited {\n        color: white !important;\n        background-color: #2c3e50 !important;\n        text-decoration: none !important;\n    }\n    .button:hover {\n        background-color: #34495e !important;\n        text-decoration: none !important;\n    }\n    .footer { font-size: 12px; color: #999; text-align: center; margin-top: 20px; border-top: 1px solid #eee; padding-top: 15px; }\n    </style>\n</head>\n<body>\n    <div class=\"container\">\n        <div class=\"header\">\n            <h1>Price Alert</h1>\n            <p>We've detected a significant price change for an item you're tracking</p>\n        </div>\n\n        <div class=\"price-details\">\n            <h2 class=\"{{ $('Alert Status').item.json.alert_status === 'High' ? 'price-up' : 'price-down' }}\">\n                {{ $('Alert Status').item.json.alert_status === 'High' ? 'Price Increased by ' : 'Price Decreased by ' }} \n                {{ (Math.abs($('Update - Products to Monitor').item.json.percent_change  * 100).toFixed(2)) }}%\n            </h2>\n            \n            <h3>{{ $('Update - Products to Monitor').item.json.name }}</h3>\n            <p>ASIN: {{ $json.asin }}</p>\n            \n            <table width=\"100%\" border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n                <tr>\n                    <th align=\"left\">Previous Price</th>\n                    <th align=\"left\">Current Price</th>\n                    <th align=\"left\">Difference</th>\n                </tr>\n                <tr>\n                    <td>${{ $('Last Price').item.json.last_pricing.toFixed(2) }}</td>\n                    <td>${{ $('Update - Products to Monitor').item.json.pricing }}</td>\n                    <td>{{ \n                      $('Update - Products to Monitor').item.json.price_change >= 0 \n                        ? '$' + $('Update - Products to Monitor').item.json.price_change.toFixed(2) \n                        : '- $' + Math.abs($('Update - Products to Monitor').item.json.price_change).toFixed(2) \n                    }}</td>\n                </tr>\n            </table>\n            \n            <p>Last updated: {{ $('Insert - Price History').item.json.timestamp }}</p>\n        </div>\n\n        <a href=\"{{ $('Update - Products to Monitor').item.json.product_url }}\" class=\"button\">View Product</a>\n\n        <div class=\"footer\">\n            <p>This alert was generated by Amazon Price Tracker, your automated price monitoring system.</p>\n            <p>\u00a9 2025 ScrapeOps. All rights reserved.</p>\n        </div>\n    </div>\n</body>\n</html>", "options": {"appendAttribution": false}, "subject": "=Amazon Price Tracker Alert: {{ $('Update - Products to Monitor').item.json.name }} Price Change Detected", "toEmail": "={{ $('Setup').item.json.to_email }}", "fromEmail": "={{ $('Setup').item.json.from_email }}"}, "credentials": {"smtp": {"id": "k3bEE2wVXvRZ42hg", "name": "SMTP account"}}, "typeVersion": 2.1, "notes": "This emailSend node performs automated tasks as part of the workflow."}, {"id": "834dd1f0-d651-48b4-8765-360d8d5dcf27", "name": "Check Valid Price", "type": "n8n-nodes-base.if", "position": [1160, -80], "parameters": {"options": {}, "conditions": {"options": {"version": 2, "leftValue": "", "caseSensitive": true, "typeValidation": "strict"}, "combinator": "and", "conditions": [{"id": "f9d540d5-bc09-4970-904d-34977192b771", "operator": {"type": "number", "operation": "gt"}, "leftValue": "={{ $json.pricing }}", "rightValue": 0}]}}, "typeVersion": 2.2, "notes": "This if node performs automated tasks as part of the workflow."}, {"id": "163385ad-6f41-4144-bf2a-6ba2e2425ae2", "name": "Alert Decision", "type": "n8n-nodes-base.if", "position": [2240, -40], "parameters": {"options": {}, "conditions": {"options": {"version": 2, "leftValue": "", "caseSensitive": true, "typeValidation": "strict"}, "combinator": "and", "conditions": [{"id": "6b1f16aa-dd42-4889-9c07-7fdba5a56067", "operator": {"type": "string", "operation": "notEmpty", "singleValue": true}, "leftValue": "={{ $('Alert Status').item.json.alert_status }}", "rightValue": ""}]}}, "typeVersion": 2.2, "notes": "This if node performs automated tasks as part of the workflow."}, {"id": "dd075f72-22bc-438e-a75b-a2437a8920c3", "name": "Sticky Note", "type": "n8n-nodes-base.stickyNote", "position": [-1100, -600], "parameters": {"color": 5, "width": 660, "height": 360, "content": "# Amazon Product Price Tracker\n\nThis workflow automates price monitoring for Amazon products using the ScrapeOps API. It tracks price changes over time, alerts you when prices cross your defined thresholds, and maintains a historical record of all price movements.\n\n## Features\n- Scheduled price checks for multiple Amazon products\n- Price change calculations (absolute and percentage)\n- Smart alerting based on customizable thresholds\n- Automated email notifications with detailed price information\n- Historical price tracking for trend analysis"}, "typeVersion": 1, "notes": "This stickyNote node performs automated tasks as part of the workflow."}, {"id": "83324982-44e9-49cc-8782-d0520955c1ff", "name": "Sticky Note2", "type": "n8n-nodes-base.stickyNote", "position": [-1100, -200], "parameters": {"color": 5, "width": 660, "height": 740, "content": "## API Configuration\nThis workflow requires a ScrapeOps API key to fetch Amazon product data.\nTo obtain your API key, register at {{ $env.WEBHOOK_URL }}\n\n## API Documentation\nFor detailed information about the Amazon Product API endpoint used in this workflow,\nrefer to the official documentation at:\n{{ $env.API_BASE_URL }}\nThe documentation provides details on all available parameters, response formats,\nand best practices for optimizing your API usage.\n\n## Integration Setup\nOnce registered, insert your API key in the \"Scrapeops - Amazon Product\" node parameters.\nThis workflow uses the structured data endpoint which returns clean, parsed product data\nin a consistent JSON format.\n\n## Google Sheets Configuration\nA Google Sheets spreadsheet is used to store the product data collected through this workflow.\nThe original template spreadsheet is shared in read-only mode through this link:\n{{ $env.WEBHOOK_URL }}\n\nTo use this workflow:\n1. Access the shared spreadsheet using the link above\n2. Make your own copy by going to File > Make a copy\n3. Share your copy with appropriate permissions\n4. In the n8n workflow, locate the \"Setup\" node\n5. Update the \"spreadsheet_url\" variable with the link to YOUR copy of the spreadsheet\n\nThis ensures each user works with their own separate spreadsheet, avoiding data overlap \nbetween different users while maintaining the original structure needed by the workflow."}, "typeVersion": 1, "notes": "This stickyNote node performs automated tasks as part of the workflow."}, {"id": "2b3d3b37-7e9d-48a0-a97a-223f4d60c6a6", "name": "Setup", "type": "n8n-nodes-base.set", "position": [-160, -220], "parameters": {"options": {}, "assignments": {"assignments": [{"id": "6f1a8857-9ecc-4fcd-8803-4494ca230ae4", "name": "spreadsheet_url", "type": "string", "value": "{{ $env.WEBHOOK_URL }}"}, {"id": "bbe91759-984c-4d62-b832-b37d84997211", "name": "scrapeops_apikey", "type": "string", "value": ""}, {"id": "29428dd3-8659-43d0-a888-1e2ee7c37ab8", "name": "from_email", "type": "string", "value": ""}, {"id": "d39032ee-895d-436e-9948-355d37abb740", "name": "to_email", "type": "string", "value": ""}]}}, "typeVersion": 3.4, "notes": "This set node performs automated tasks as part of the workflow."}, {"id": "aab72c63-3864-42b4-87b6-c9911d8d09be", "name": "Schedule Trigger", "type": "n8n-nodes-base.scheduleTrigger", "position": [-360, -220], "parameters": {"rule": {"interval": [{"field": "hours"}]}}, "typeVersion": 1.2, "notes": "This scheduleTrigger node performs automated tasks as part of the workflow."}], "active": false, "pinData": {}, "settings": {"executionOrder": "v1", "saveManualExecutions": true, "callerPolicy": "workflowsFromSameOwner", "errorWorkflow": null, "timezone": "UTC", "executionTimeout": 3600, "maxExecutions": 1000, "retryOnFail": true, "retryCount": 3, "retryDelay": 1000}, "versionId": "38990374-8154-4f1e-8026-ce206ed2d90d", "connections": {"d5cdb7eb-144f-477b-83d6-85be5cd2eb79": {"main": [[{"node": "error-handler-d5cdb7eb-144f-477b-83d6-85be5cd2eb79", "type": "main", "index": 0}], [{"node": "error-handler-d5cdb7eb-144f-477b-83d6-85be5cd2eb79-7824e16b", "type": "main", "index": 0}], [{"node": "error-handler-d5cdb7eb-144f-477b-83d6-85be5cd2eb79-ca567fdf", "type": "main", "index": 0}], [{"node": "error-handler-d5cdb7eb-144f-477b-83d6-85be5cd2eb79-98a38c8f", "type": "main", "index": 0}], [{"node": "error-handler-d5cdb7eb-144f-477b-83d6-85be5cd2eb79-79ac7b0f", "type": "main", "index": 0}], [{"node": "error-handler-d5cdb7eb-144f-477b-83d6-85be5cd2eb79-2dfdebc5", "type": "main", "index": 0}], [{"node": "error-handler-d5cdb7eb-144f-477b-83d6-85be5cd2eb79-1030f2b8", "type": "main", "index": 0}], [{"node": "error-handler-d5cdb7eb-144f-477b-83d6-85be5cd2eb79-23e6dd97", "type": "main", "index": 0}], [{"node": "error-handler-d5cdb7eb-144f-477b-83d6-85be5cd2eb79-d87de5cc", "type": "main", "index": 0}]]}, "cc15c8e6-53f9-4dd1-895f-34a72af4506f": {"main": [[{"node": "error-handler-cc15c8e6-53f9-4dd1-895f-34a72af4506f-4db5d9fe", "type": "main", "index": 0}]]}, "54f3ef24-58bc-4eba-b341-b14ab9f66d68": {"main": [[{"node": "error-handler-54f3ef24-58bc-4eba-b341-b14ab9f66d68-5bfcfa5c", "type": "main", "index": 0}]]}, "b161e44b-1fbf-40f1-a485-a7b132f42efc": {"main": [[{"node": "error-handler-b161e44b-1fbf-40f1-a485-a7b132f42efc-ca05258a", "type": "main", "index": 0}]]}, "62372099-de2a-4dcf-afdf-e9d9697a7a95": {"main": [[{"node": "error-handler-62372099-de2a-4dcf-afdf-e9d9697a7a95-89891b2d", "type": "main", "index": 0}], [{"node": "error-handler-62372099-de2a-4dcf-afdf-e9d9697a7a95-e69301e7", "type": "main", "index": 0}], [{"node": "error-handler-62372099-de2a-4dcf-afdf-e9d9697a7a95-e9c142d2", "type": "main", "index": 0}], [{"node": "error-handler-62372099-de2a-4dcf-afdf-e9d9697a7a95-058c2511", "type": "main", "index": 0}], [{"node": "error-handler-62372099-de2a-4dcf-afdf-e9d9697a7a95-68d3d4d3", "type": "main", "index": 0}], [{"node": "error-handler-62372099-de2a-4dcf-afdf-e9d9697a7a95-7cc4d7b0", "type": "main", "index": 0}], [{"node": "error-handler-62372099-de2a-4dcf-afdf-e9d9697a7a95-4b3a6ed6", "type": "main", "index": 0}], [{"node": "error-handler-62372099-de2a-4dcf-afdf-e9d9697a7a95-2dbbf33d", "type": "main", "index": 0}]]}}, "description": "Automated workflow: Amazon Product Price Tracker. This workflow integrates 9 different services: stickyNote, httpRequest, scheduleTrigger, set, stopAndError. It contains 22 nodes and follows best practices for error handling and security.", "notes": "Excellent quality workflow: Amazon Product Price Tracker. This workflow has been optimized for production use with comprehensive error handling, security, and documentation."}