This workflow corresponds to n8n.io template #17391 — we link there as the canonical source.
This workflow follows the Gmail → Google Sheets 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 →
{
"id": "f9AthtT0W1WRa0iy",
"meta": {
"templateCredsSetupCompleted": true
},
"name": "WF1 \u2013 Amazon Price Drop Alert",
"tags": [],
"nodes": [
{
"id": "d98f91fd-5437-4887-bbdb-e07bab933f02",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
2176,
416
],
"parameters": {
"width": 688,
"height": 880,
"content": "## WF1 \u2013 Amazon Price Drop Alert\n\n### How it works\n\nThis workflow monitors Amazon product prices on a recurring schedule. Every four hours it loads a product list from Google Sheets, loops through each item, scrapes the Amazon page, extracts the title and price, logs the result, and sends a Gmail alert if the price is below the product\u2019s threshold. A separate manual trigger is present on the canvas but is not connected to the active flow.\n\n### Setup steps\n\n- Configure Google Sheets credentials for both reading the tracked product list and writing price history.\n- Set up the product sheet with the expected columns, such as product URL, target price threshold, and any alert recipient or product metadata used by the nodes.\n- Configure the scraping service credentials or settings in the Scrape Amazon Product Page node so Amazon pages can be fetched reliably.\n- Configure Gmail credentials and verify the Send Price Drop Alert node has the correct recipient, subject, and message body.\n- Review the schedule trigger interval and activate the workflow when credentials and sheet mappings are confirmed.\n\n### Customization\n\nAdjust the schedule frequency, threshold logic, email template, product sheet columns, or the extraction code if Amazon page structure or required product fields change."
},
"typeVersion": 1
},
{
"id": "67fb9919-3bec-44fb-a56d-924cce43d7f2",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
2944,
448
],
"parameters": {
"color": 7,
"height": 272,
"content": "## Manual test trigger\n\n"
},
"typeVersion": 1
},
{
"id": "bdf1e1e2-6954-4ae6-b45b-539f3afa6e6c",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
2944,
768
],
"parameters": {
"color": 7,
"width": 720,
"height": 400,
"content": "## Load product list\n\nStarts the scheduled run every four hours, reads the tracked products from Google Sheets, and feeds them one at a time into the batch loop."
},
"typeVersion": 1
},
{
"id": "380525a7-d75a-47b9-8f79-e18bb2104efa",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
3696,
528
],
"parameters": {
"color": 7,
"width": 640,
"height": 640,
"content": "## Scrape product details\n\nFor each product in the loop, fetches the Amazon product page through the scraping service and uses custom code to extract the product title and current price."
},
"typeVersion": 1
},
{
"id": "049d1f6f-ba63-4d54-86d1-a15c42c2cd6d",
"name": "Sticky Note4",
"type": "n8n-nodes-base.stickyNote",
"position": [
4384,
656
],
"parameters": {
"color": 7,
"width": 832,
"height": 528,
"content": "## Log and alert\n\n"
},
"typeVersion": 1
},
{
"id": "2a3954af-5d23-4201-9b95-d6d0cb822986",
"name": "Manual Execution Trigger",
"type": "n8n-nodes-base.manualTrigger",
"position": [
2992,
576
],
"parameters": {},
"typeVersion": 1
},
{
"id": "8a870a38-543c-49ec-9038-7df3c215a92c",
"name": "Scrape Amazon Product Details",
"type": "n8n-nodes-scrapeunblocker.scrapeUnblocker",
"position": [
3808,
752
],
"parameters": {
"url": "https://www.amazon.com/Logitech-Wireless-Lightspeed-Headset-Headphone/dp/B081PP4CB6/?th=1"
},
"credentials": {},
"typeVersion": 1
},
{
"id": "80581ff2-16e2-4042-b763-ba32f1f4be9b",
"name": "Extract Product Details",
"type": "n8n-nodes-base.code",
"position": [
4128,
768
],
"parameters": {
"jsCode": "const returnItems = [];\n\nfor (const item of $input.all()) {\n // 1. Find the HTML string no matter where ScrapeUnblocker hid it\n let html = \"\";\n if (typeof item.json === 'string') {\n html = item.json;\n } else if (item.json && typeof item.json === 'object') {\n html = item.json.data || item.json.html || item.json.body || JSON.stringify(item.json);\n }\n\n // FAIL-SAFE: If the previous node actually sent nothing, stop here and report it.\n if (!html || html.trim() === \"\" || html === \"{}\") {\n returnItems.push({\n json: {\n error: \"No HTML received. Check the ScrapeUnblocker node output to ensure it is actually loading the page.\"\n }\n });\n continue;\n }\n\n // 2. Extract Title (id=\"productTitle\" is highly stable on Amazon)\n let title = \"Not found\";\n const titleMatch = html.match(/id=\"productTitle\"[^>]*>([\\s\\S]*?)<\\//i);\n if (titleMatch) {\n title = titleMatch[1].replace(/<[^>]+>/g, '').trim();\n }\n\n // 3. Extract Price (Looks for the hidden screen-reader text inside the price block)\n let price = \"Not found\";\n const priceMatch = html.match(/class=\"a-price\"[^>]*>[\\s\\S]*?class=\"a-offscreen\">([^<]+)<\\//i)\n || html.match(/id=\"corePrice[^>]*>[\\s\\S]*?class=\"a-offscreen\">([^<]+)<\\//i);\n if (priceMatch) {\n price = priceMatch[1].trim();\n }\n\n // 3b. Clean price -> pure number for comparisons (strips S$, $, \u00a3, commas, spaces, etc.)\n let price_clean = null;\n if (price !== \"Not found\") {\n const num = parseFloat(price.replace(/[^0-9.]/g, ''));\n price_clean = isNaN(num) ? null : num;\n }\n\n // 4. Create a clean text block for Gemini to read the features/description\n let safeText = html.replace(/<(script|style|svg|path)[^>]*>[\\s\\S]*?<\\/\\1>/gi, ' ');\n safeText = safeText.replace(/<[^>]+>/g, ' ');\n safeText = safeText.replace(/ | /gi, ' ');\n safeText = safeText.replace(/\\s+/g, ' ').trim();\n safeText = safeText.substring(0, 20000);\n\n // 5. Output the results\n returnItems.push({\n json: {\n scraped_title: title,\n scraped_price: price,\n price_clean: price_clean,\n clean_text_for_gemini: safeText\n }\n });\n}\n\nreturn returnItems;"
},
"typeVersion": 2
},
{
"id": "7a89d379-13aa-405e-ae4d-6a9f9e87e566",
"name": "Read Products from Sheets",
"type": "n8n-nodes-base.googleSheets",
"position": [
3232,
976
],
"parameters": {
"options": {},
"sheetName": {
"__rl": true,
"mode": "list",
"value": "gid=0",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1FosokWfr3ouHhVsERNO7yvOcB58TO2EV6un9HzDFPAs/edit#gid=0",
"cachedResultName": "Products"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1FosokWfr3ouHhVsERNO7yvOcB58TO2EV6un9HzDFPAs",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1FosokWfr3ouHhVsERNO7yvOcB58TO2EV6un9HzDFPAs/edit?usp=drivesdk",
"cachedResultName": "Amazon Price Tracker"
}
},
"typeVersion": 4.5
},
{
"id": "3a62ae6a-dd7a-4aa1-a63b-68ee158f3800",
"name": "Loop Over Product Batches",
"type": "n8n-nodes-base.splitInBatches",
"position": [
3520,
976
],
"parameters": {
"options": {}
},
"typeVersion": 3
},
{
"id": "de309ffe-34a9-4616-a7ce-dde8be432a80",
"name": "Update Price History in Sheets",
"type": "n8n-nodes-base.googleSheets",
"position": [
4464,
768
],
"parameters": {
"columns": {
"value": {
"Last Price": "={{ $('Loop Over Product Batches').item.json[\"Price Threshold\"] }}",
"row_number": "={{ $('Loop Over Product Batches').item.json.row_number }}",
"price_clean": "={{ $json.price_clean }}",
"Last Checked": "={{ $now.format('yyyy-MM-dd') }}",
"Product Title": "={{ $json.scraped_title }}",
"Price Threshold": "={{ $json.scraped_price }}"
},
"schema": [
{
"id": "Product URL",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "Product URL",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Price Threshold",
"type": "string",
"display": true,
"required": false,
"displayName": "Price Threshold",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Product Title",
"type": "string",
"display": true,
"required": false,
"displayName": "Product Title",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Last Price",
"type": "string",
"display": true,
"required": false,
"displayName": "Last Price",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "price_clean",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "price_clean",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Last Checked",
"type": "string",
"display": true,
"required": false,
"displayName": "Last Checked",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "row_number",
"type": "number",
"display": true,
"removed": false,
"readOnly": true,
"required": false,
"displayName": "row_number",
"defaultMatch": false,
"canBeUsedToMatch": true
}
],
"mappingMode": "defineBelow",
"matchingColumns": [
"row_number"
],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {},
"operation": "update",
"sheetName": {
"__rl": true,
"mode": "list",
"value": "gid=0",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1FosokWfr3ouHhVsERNO7yvOcB58TO2EV6un9HzDFPAs/edit#gid=0",
"cachedResultName": "Products"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1FosokWfr3ouHhVsERNO7yvOcB58TO2EV6un9HzDFPAs",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1FosokWfr3ouHhVsERNO7yvOcB58TO2EV6un9HzDFPAs/edit?usp=drivesdk",
"cachedResultName": "Amazon Price Tracker"
}
},
"typeVersion": 4.5
},
{
"id": "ab673cf2-293d-42e7-b488-3d83227f986c",
"name": "Check Price Threshold",
"type": "n8n-nodes-base.if",
"position": [
4704,
768
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "cond-below",
"operator": {
"type": "number",
"operation": "lt"
},
"leftValue": "={{ $('Extract Product Details').item.json.price_clean }}",
"rightValue": "={{ $('Loop Over Product Batches').item.json.price_clean }}"
}
]
}
},
"typeVersion": 2.2
},
{
"id": "80bb0ed1-062f-4b8d-ad1d-c502684bfd02",
"name": "Send Email Price Alert",
"type": "n8n-nodes-base.gmail",
"position": [
5008,
944
],
"parameters": {
"sendTo": "YOUR EMAIL",
"message": "=The price for a product you're tracking has dropped below your threshold.\n\nProduct: {{ $('Extract Product Details').item.json.scraped_title }}\nCurrent Price: {{ $('Extract Product Details').item.json.scraped_price }}\nYour Threshold: {{ $('Loop Over Product Batches').item.json['Price Threshold'] }}\n\nView / Buy: {{ $('Loop Over Product Batches').item.json['Product URL'] }}\n\nChecked at: {{ $now.format('yyyy-MM-dd HH:mm') }}",
"options": {
"appendAttribution": false
},
"subject": "=\ud83d\udd3b Price Drop Alert: {{ $('Extract Product Details').item.json.scraped_title }}",
"emailType": "text"
},
"typeVersion": 2.2
},
{
"id": "fbc6f3ae-162c-4b1c-b88f-26f8dd153c1f",
"name": "Trigger Every 4 Hours",
"type": "n8n-nodes-base.scheduleTrigger",
"position": [
3008,
976
],
"parameters": {
"rule": {
"interval": [
{
"field": "hours",
"hoursInterval": 4
}
]
}
},
"typeVersion": 1.2
}
],
"active": false,
"settings": {
"binaryMode": "separate",
"executionOrder": "v1"
},
"versionId": "322e9be5-cbf1-4c54-80af-d430c92ee2bb",
"nodeGroups": [],
"connections": {
"Check Price Threshold": {
"main": [
[
{
"node": "Loop Over Product Batches",
"type": "main",
"index": 0
}
],
[
{
"node": "Send Email Price Alert",
"type": "main",
"index": 0
}
]
]
},
"Trigger Every 4 Hours": {
"main": [
[
{
"node": "Read Products from Sheets",
"type": "main",
"index": 0
}
]
]
},
"Send Email Price Alert": {
"main": [
[
{
"node": "Loop Over Product Batches",
"type": "main",
"index": 0
}
]
]
},
"Extract Product Details": {
"main": [
[
{
"node": "Update Price History in Sheets",
"type": "main",
"index": 0
}
]
]
},
"Loop Over Product Batches": {
"main": [
[],
[
{
"node": "Scrape Amazon Product Details",
"type": "main",
"index": 0
}
]
]
},
"Read Products from Sheets": {
"main": [
[
{
"node": "Loop Over Product Batches",
"type": "main",
"index": 0
}
]
]
},
"Scrape Amazon Product Details": {
"main": [
[
{
"node": "Extract Product Details",
"type": "main",
"index": 0
}
]
]
},
"Update Price History in Sheets": {
"main": [
[
{
"node": "Check Price Threshold",
"type": "main",
"index": 0
}
]
]
}
}
}
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
This workflow checks Amazon product pages on a 4-hour schedule (or manually), extracts the current title and price via ScrapeUnblocker, logs results to Google Sheets, and sends a Gmail alert when a product’s price drops below the threshold stored in the sheet. Runs every 4 hours…
Source: https://n8n.io/workflows/17391/ — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
This workflow ingests proof-of-delivery and completion documents from Gmail or a webhook, extracts key fields with an OpenRouter vision model, reconciles them against Google Sheets dispatch data, arch
Loan eligibility workflow. Uses formTrigger, googleSheets, gmail. Event-driven trigger; 53 nodes.
Splitout Code. Uses manualTrigger, httpRequest, stickyNote, splitOut. Event-driven trigger; 46 nodes.
Automate CSV imports into HubSpot without the mess. Powered by n8n. Supercharged by Pollup AI.
Automate event registration with capacity management, a waitlist, and multi-tier PDF ticket generation using PDF Generator API. When attendees register, the workflow checks available spots, routes by