diff --git a/workflows/E-commerce Price Tracker with ScrapeGraphAI, MongoDB, and Mailgun Alerts-11585/e-commerce_price_tracker_with_scrapegraphai_mongodb_and_mailgun_alerts.json b/workflows/E-commerce Price Tracker with ScrapeGraphAI, MongoDB, and Mailgun Alerts-11585/e-commerce_price_tracker_with_scrapegraphai_mongodb_and_mailgun_alerts.json new file mode 100644 index 000000000..ec18049e1 --- /dev/null +++ b/workflows/E-commerce Price Tracker with ScrapeGraphAI, MongoDB, and Mailgun Alerts-11585/e-commerce_price_tracker_with_scrapegraphai_mongodb_and_mailgun_alerts.json @@ -0,0 +1 @@ +{"id":"y0Yk7da21T4u9zlp","meta":{"instanceId":"99f4e9e67f2a926c174453b6675a71cc5fb71c1fb19cfc06d50531053c661324","templateCredsSetupCompleted":true},"name":"Product Price Monitor with Mailgun and MongoDB","tags":[],"nodes":[{"id":"84e5e163-3384-410e-8bf4-134227cbad8a","name":"Workflow Overview","type":"n8n-nodes-base.stickyNote","position":[-704,-192],"parameters":{"width":384,"height":704,"content":"## How it works\n\nThis workflow lets you drop a list of product URLs into a single webhook and instantly kicks off an AI-powered, multi-site price check. The Webhook trigger hands the URLs to a small code snippet that converts them into separate items. A Split-in-Batches node feeds each item to ScrapeGraphAI in parallel so every e-commerce site is scraped at the same time. Once all mini-jobs finish, a Merge node aggregates the results and a Code node compares the freshly scraped price against your chosen alert threshold. We store every observation in MongoDB for long-term trend analysis, but if any price falls far enough, an IF node fires a Mailgun email so you never miss a seasonal bargain.\n\n## Setup steps\n\n1. Add ScrapeGraphAI credentials under **Credentials → ScrapeGraphAI API**\n2. Add Mailgun credentials and verify “from” domain\n3. Add MongoDB credentials pointing to your database\n4. Open *Define Product Sources* and paste product URLs & thresholds\n5. Edit *Prepare Alert Email* to pick your recipient list\n6. Deploy publicly accessible webhook URL in your scheduler or app\n7. Activate the workflow and test with a single POST request"},"typeVersion":1},{"id":"df689696-242a-42a6-ab8a-e64cc42b7ef5","name":"Section – Trigger & URL Setup","type":"n8n-nodes-base.stickyNote","position":[-256,-160],"parameters":{"color":7,"width":512,"height":688,"content":"## Trigger & URL Setup\n\nEverything begins the moment your e-commerce monitoring tool (or a simple cURL command) hits the webhook. The **Incoming Monitor Request** node captures the raw POST payload and puts n8n into wait-for-response mode so you can acknowledge the call later. Directly after, **Define Product Sources** turns the submitted body—or a default fallback list you maintain in code—into an array of JSON items. Each item normally contains the product URL, an optional friendly name, and the percentage drop that should count as significant. Building URLs in code keeps configuration in one compact place and makes it trivial to add or remove products without touching any other part of the workflow. Once the array is ready, it flows to the Split node for parallel processing."},"typeVersion":1},{"id":"24f55bf1-f430-4a28-8ce1-c0a6af0a8a9f","name":"Section – Parallel Scraping","type":"n8n-nodes-base.stickyNote","position":[272,-160],"parameters":{"color":7,"width":384,"height":688,"content":"## Parallel Scraping\n\nThe **Split URLs** node breaks the incoming array into single-item batches so n8n can process each product independently. By setting the batch size to one, you enable true fan-out parallelism which drastically cuts overall runtime on large lists. Every item immediately lands in **Scrape Product Page**, the ScrapeGraphAI node pre-configured with a natural-language prompt that asks for the product name, price, currency, and availability flag. Because ScrapeGraphAI uses an LLM instead of brittle CSS selectors, you gain resilience when retailers change their markup or inject seasonal banners. Each scrape completes in isolation, freeing the engine to request the next URL without waiting, which is perfect for weekly, high-volume price checks."},"typeVersion":1},{"id":"053da4e1-8000-4dc3-8d67-95bd0107f67d","name":"Section – Aggregation & Analysis","type":"n8n-nodes-base.stickyNote","position":[672,-176],"parameters":{"color":7,"width":432,"height":688,"content":"## Aggregation & Analysis\n\nWhen all ScrapeGraphAI calls finish, their outputs funnel into **Combine Scraped Data** running in aggregate mode. That node stitches the individual items back into a single array, guaranteeing that downstream logic doesn’t execute until every page has been scraped. **Analyze Price Movement** then loops through each record, converts price strings to numbers, and calculates the percentage change versus the hard-coded or payload-provided alert threshold. The script flags any result whose drop meets or exceeds that threshold and appends helper fields like diffPercent and significantDrop so later nodes can branch intelligently without extra mathematics."},"typeVersion":1},{"id":"665068c8-b5dd-4672-9057-9e390c9994a6","name":"Section – Storage & Alerts","type":"n8n-nodes-base.stickyNote","position":[1120,-192],"parameters":{"color":7,"width":480,"height":688,"content":"## Storage & Alerts\n\nAll processed items go to **Store to MongoDB**, which inserts a timestamped document for every observation. Persisting raw prices provides a historical backbone for dashboards and seasonal trend analysis. Right after storage, the flow checks **Significant Price Change?**. If at least one item carries a true flag, the path continues to **Prepare Alert Email** where a Set node assembles a concise HTML summary including product names, old prices, new prices, and percentage savings. Finally, **Send Mailgun Alert** shoots the email to your merchandising or procurement team. The branch returns to the webhook response so external callers receive an immediate JSON confirmation, even when no alerts fire."},"typeVersion":1},{"id":"b0e53d4f-e891-4e11-87af-a9b62c510728","name":"Incoming Monitor Request","type":"n8n-nodes-base.webhook","position":[-240,208],"webhookId":"a106337b-5c43-47a0-982c-ad30cf68b99b","parameters":{"path":"product-price-monitor","options":{},"httpMethod":"POST","responseMode":"responseNode"},"typeVersion":1},{"id":"90e1268f-49d1-431f-815f-e52cd6f28839","name":"Define Product Sources","type":"n8n-nodes-base.code","position":[0,224],"parameters":{"jsCode":"// Accept list via webhook, otherwise use fallback array\nconst body = $json;\nlet urls = body.urls;\nif (!Array.isArray(urls) || urls.length === 0) {\n urls = [\n { url: 'https://example-ecom.com/productA', alertPercent: 10 },\n { url: 'https://example-ecom.com/productB', alertPercent: 12 }\n ];\n}\n// Return each URL as its own item\nreturn urls.map(obj => ({ json: obj }));"},"typeVersion":2},{"id":"232e97ca-8250-4638-a612-3e7eb1a59291","name":"Split URLs","type":"n8n-nodes-base.splitInBatches","position":[352,256],"parameters":{"options":{}},"typeVersion":3},{"id":"90f1ed18-82d8-4732-910f-9884daeb1e3f","name":"Scrape Product Page","type":"n8n-nodes-scrapegraphai.scrapegraphAi","position":[528,288],"parameters":{"userPrompt":"Extract the product name, current price (number), currency code, and availability (boolean). Respond strictly as JSON with keys: name, price, currency, availability.","websiteUrl":"={{ $json.url }}"},"typeVersion":1},{"id":"a1e62ba0-ca14-463b-9d0b-e331ab0ffb3f","name":"Combine Scraped Data","type":"n8n-nodes-base.merge","position":[704,288],"parameters":{"mode":"aggregate","options":{}},"typeVersion":2},{"id":"9882c5cc-549a-4b2e-b9b1-ad022bee1c75","name":"Analyze Price Movement","type":"n8n-nodes-base.code","position":[944,144],"parameters":{"jsCode":"const THRESHOLD_KEY = 'alertPercent';\nreturn $input.all().map(item => {\n const data = item.json;\n const price = Number(data.price);\n const threshold = data[THRESHOLD_KEY] || 10;\n // Dummy previous price; in real setup, query last price from DB here\n const previousPrice = data.previousPrice || price;\n const diffPercent = previousPrice > 0 ? ((previousPrice - price) / previousPrice) * 100 : 0;\n const significantDrop = diffPercent >= threshold;\n return {\n json: {\n ...data,\n previousPrice,\n diffPercent: Number(diffPercent.toFixed(2)),\n significantDrop\n }\n };\n});"},"typeVersion":2},{"id":"a6099b67-fb8f-4763-880c-48dba48dd8d2","name":"Store to MongoDB","type":"n8n-nodes-base.mongoDb","position":[1184,192],"parameters":{"fields":{"url":"={{ $json.url }}","name":"={{ $json.name }}","price":"={{ $json.price }}","currency":"={{ $json.currency }}","timestamp":"={{ new Date().toISOString() }}","diffPercent":"={{ $json.diffPercent }}","availability":"={{ $json.availability }}"},"options":{},"operation":"insert","collection":"product_prices"},"typeVersion":1},{"id":"9ae6fb79-cff5-4e2d-95bc-d559164299f7","name":"Significant Price Change?","type":"n8n-nodes-base.if","position":[944,320],"parameters":{"options":{},"conditions":{"boolean":[{"value1":"={{ $json.significantDrop }}","operation":"true"}]}},"typeVersion":2},{"id":"f9217fdc-6504-4be0-8b8a-61c8be7bd6f3","name":"Prepare Alert Email","type":"n8n-nodes-base.set","position":[1184,336],"parameters":{"options":{}},"typeVersion":3.4},{"id":"73275a7f-1bd9-405b-a2b3-0b5745f09fbb","name":"Send Mailgun Alert","type":"n8n-nodes-base.mailgun","position":[1424,240],"parameters":{"subject":"={{ $json.subject }}","toEmail":"={{ $json.toEmail }}","fromEmail":"pricebot@yourdomain.com"},"typeVersion":1},{"id":"d3be5108-8b7e-4b0f-8041-d59813e47393","name":"Send Webhook Response","type":"n8n-nodes-base.respondToWebhook","position":[1424,80],"parameters":{"options":{}},"typeVersion":1}],"active":false,"pinData":{},"settings":{"executionOrder":"v1"},"versionId":"c4218f72-a502-41f0-8a11-4ef900b4d27e","connections":{"Split URLs":{"main":[[{"node":"Scrape Product Page","type":"main","index":0}]]},"Store to MongoDB":{"main":[[{"node":"Send Webhook Response","type":"main","index":0}]]},"Send Mailgun Alert":{"main":[[{"node":"Send Webhook Response","type":"main","index":0}]]},"Prepare Alert Email":{"main":[[{"node":"Send Mailgun Alert","type":"main","index":0}]]},"Scrape Product Page":{"main":[[{"node":"Combine Scraped Data","type":"main","index":0}]]},"Combine Scraped Data":{"main":[[{"node":"Analyze Price Movement","type":"main","index":0}]]},"Analyze Price Movement":{"main":[[{"node":"Store to MongoDB","type":"main","index":0},{"node":"Significant Price Change?","type":"main","index":0}]]},"Define Product Sources":{"main":[[{"node":"Split URLs","type":"main","index":0}]]},"Incoming Monitor Request":{"main":[[{"node":"Define Product Sources","type":"main","index":0}]]},"Significant Price Change?":{"main":[[{"node":"Prepare Alert Email","type":"main","index":0}]]}}} \ No newline at end of file