Suivi des prix concurrentiels et alertes (Bright Data, Sheets et Slack)
Ceci est unMarket Researchworkflow d'automatisation du domainecontenant 29 nœuds.Utilise principalement des nœuds comme If, Set, Code, Wait, Slack. Utiliser Bright Data, Sheets et Slack pour la surveillance concurrentielle des prix et les alertes
- •Token Bot Slack ou URL Webhook
- •Peut nécessiter les informations d'identification d'authentification de l'API cible
- •Informations d'identification Google Sheets API
Nœuds utilisés (29)
Catégorie
{
"meta": {
"instanceId": "db30e8ae4100235addbd4638770997b7ef11878d049073c888ba440ca84c55fc",
"templateCredsSetupCompleted": true
},
"nodes": [
{
"id": "e25e8bb0-052e-439a-9e79-a2b8bc1b68e3",
"name": "Charger les URLs des concurrents",
"type": "n8n-nodes-base.set",
"notes": "Configure your competitor URLs and your current price here",
"position": [
112,
160
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "competitor1",
"name": "competitors",
"type": "array",
"value": "=[\n {\n \"name\": \"Competitor A\",\n \"url\": \"https://example.com/product-1\",\n \"productName\": \"Wireless Headphones Pro\"\n },\n {\n \"name\": \"Competitor B\",\n \"url\": \"https://competitor-b.com/audio/headphones\",\n \"productName\": \"Wireless Headphones Pro\"\n },\n {\n \"name\": \"Competitor C\",\n \"url\": \"https://competitor-c.com/electronics/headphones-pro\",\n \"productName\": \"Wireless Headphones Pro\"\n }\n]"
},
{
"id": "our-price",
"name": "ourPrice",
"type": "number",
"value": "149.99"
},
{
"id": "alert-threshold",
"name": "alertThreshold",
"type": "number",
"value": "10"
}
]
}
},
"typeVersion": 3.3
},
{
"id": "09ee23e0-057f-4fda-bdb0-191d85f6b9a2",
"name": "Boucle à travers les concurrents",
"type": "n8n-nodes-base.splitInBatches",
"position": [
304,
160
],
"parameters": {
"options": {}
},
"typeVersion": 3
},
{
"id": "962d1bc2-96b2-4fbb-8a7c-2b1b3a467a9e",
"name": "Scraper avec Bright Data",
"type": "n8n-nodes-base.httpRequest",
"notes": "Triggers Bright Data web scraper to extract product data",
"position": [
512,
160
],
"parameters": {
"url": "https://api.brightdata.com/datasets/v3/trigger",
"options": {},
"jsonBody": "={\n \"dataset_id\": \"gd_l7q7dkf244hwjntr0\",\n \"endpoint\": \"https://api.brightdata.com/datasets/v3/snapshot/gd_l7q7dkf244hwjntr0?format=json\",\n \"url\": \"{{ $json.competitors[$itemIndex].url }}\",\n \"discover_new_sites\": false\n}",
"sendBody": true,
"sendHeaders": true,
"specifyBody": "json",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth",
"headerParameters": {
"parameters": [
{
"name": "Content-Type",
"value": "application/json"
}
]
}
},
"typeVersion": 4.2
},
{
"id": "a25d2c0a-a757-40c4-a3ac-b69028c4eab4",
"name": "Attendre le scraping",
"type": "n8n-nodes-base.wait",
"position": [
704,
160
],
"webhookId": "wait-webhook-id",
"parameters": {
"amount": 10
},
"typeVersion": 1.1
},
{
"id": "dfd8a43c-a62f-4e2d-89cd-54a89bb7e10f",
"name": "Récupérer les données scrapées",
"type": "n8n-nodes-base.httpRequest",
"notes": "Retrieves the scraped product data from Bright Data",
"position": [
912,
160
],
"parameters": {
"url": "={{ $json.snapshot_id ? 'https://api.brightdata.com/datasets/v3/snapshot/' + $json.snapshot_id + '?format=json' : 'https://api.brightdata.com/datasets/v3/progress/' + $json.snapshot_id }}",
"options": {},
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth"
},
"typeVersion": 4.2
},
{
"id": "b1f47493-ae09-4d67-9a6c-3e272bb6247b",
"name": "Analyser les données de prix",
"type": "n8n-nodes-base.code",
"notes": "Extracts price and calculates differences",
"position": [
1104,
160
],
"parameters": {
"jsCode": "// Parse and extract price from scraped data\nconst items = $input.all();\nconst processedItems = [];\n\nfor (const item of items) {\n const scrapedData = item.json;\n const competitorInfo = $('Loop Through Competitors').item.json.competitors[$itemIndex];\n \n // Extract price from various possible formats\n let price = null;\n let priceText = '';\n \n // Try to find price in common patterns\n if (scrapedData.price) {\n priceText = scrapedData.price;\n } else if (scrapedData.data && scrapedData.data[0]) {\n priceText = scrapedData.data[0].price || scrapedData.data[0].final_price || '';\n }\n \n // Clean and parse price\n if (priceText) {\n // Remove currency symbols and commas\n const cleanPrice = priceText.toString().replace(/[$£€,]/g, '').trim();\n price = parseFloat(cleanPrice);\n }\n \n // Calculate price difference\n const ourPrice = $('Load Competitor URLs').item.json.ourPrice;\n const priceDifference = price ? (((price - ourPrice) / ourPrice) * 100).toFixed(2) : null;\n const isUnderpriced = price && price < ourPrice;\n const percentageDiff = Math.abs(parseFloat(priceDifference));\n \n processedItems.push({\n json: {\n competitorName: competitorInfo.name,\n competitorUrl: competitorInfo.url,\n productName: competitorInfo.productName,\n competitorPrice: price,\n ourPrice: ourPrice,\n priceDifference: priceDifference,\n percentageDiff: percentageDiff,\n isUnderpriced: isUnderpriced,\n scrapedAt: new Date().toISOString(),\n rawData: scrapedData\n }\n });\n}\n\nreturn processedItems;"
},
"typeVersion": 2
},
{
"id": "8c321bc9-d075-475a-9e8e-eeb11a7a72a2",
"name": "Enregistrer dans Google Sheets",
"type": "n8n-nodes-base.googleSheets",
"position": [
1312,
48
],
"parameters": {
"columns": {
"value": {
"URL": "={{ $json.competitorUrl }}",
"Date": "={{ $json.scrapedAt }}",
"Product": "={{ $json.productName }}",
"Our Price": "={{ $json.ourPrice }}",
"Competitor": "={{ $json.competitorName }}",
"Their Price": "={{ $json.competitorPrice }}",
"Underpriced": "={{ $json.isUnderpriced }}",
"Difference %": "={{ $json.priceDifference }}"
},
"mappingMode": "defineBelow"
},
"options": {},
"operation": "appendOrUpdate",
"sheetName": {
"__rl": true,
"mode": "list",
"value": "gid=0",
"cachedResultName": "Price History"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "your-spreadsheet-id",
"cachedResultName": "Price Tracker"
}
},
"typeVersion": 4.4
},
{
"id": "cfc8a52b-8ece-4f60-809d-eb90c624448a",
"name": "Vérifier si une alerte est nécessaire",
"type": "n8n-nodes-base.if",
"notes": "Only alert if competitor is significantly cheaper",
"position": [
1312,
256
],
"parameters": {
"options": {},
"conditions": {
"options": {
"leftValue": "",
"caseSensitive": false,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "underpriced",
"operator": {
"type": "boolean",
"operation": "true"
},
"leftValue": "={{ $json.isUnderpriced }}",
"rightValue": true
},
{
"id": "threshold",
"operator": {
"type": "number",
"operation": "gt"
},
"leftValue": "={{ $json.percentageDiff }}",
"rightValue": "={{ $('Load Competitor URLs').item.json.alertThreshold }}"
}
]
}
},
"typeVersion": 2
},
{
"id": "7ef5a699-ee90-4059-b4df-6f3ca1706f00",
"name": "Envoyer une alerte Slack",
"type": "n8n-nodes-base.slack",
"position": [
1520,
160
],
"webhookId": "fe1a9637-6e89-4684-9604-040bbe89340f",
"parameters": {
"text": "=🚨 *PRICE ALERT!*\n\n*{{ $json.competitorName }}* is undercutting us significantly!\n\n📦 Product: {{ $json.productName }}\n💰 Their Price: ${{ $json.competitorPrice }}\n💵 Our Price: ${{ $json.ourPrice }}\n📉 Difference: {{ $json.priceDifference }}%\n\n🔗 <{{ $json.competitorUrl }}|View Competitor Listing>\n\n_Consider adjusting pricing strategy or reviewing product positioning._",
"otherOptions": {}
},
"typeVersion": 2.1
},
{
"id": "c3ac376c-a9af-4853-8f98-2bd392fdbccf",
"name": "Envoyer une alerte par email",
"type": "n8n-nodes-base.emailSend",
"position": [
1520,
304
],
"webhookId": "322a60bd-90dd-4f5e-9b02-a733fa549978",
"parameters": {
"options": {},
"subject": "=Price Alert: {{ $json.competitorName }} - {{ $json.productName }}",
"toEmail": "pricing-team@yourcompany.com",
"fromEmail": "alerts@yourcompany.com"
},
"typeVersion": 2.1
},
{
"id": "09324ac9-3bc2-4e37-947b-6b972705589d",
"name": "Agréger tous les résultats",
"type": "n8n-nodes-base.aggregate",
"notes": "Combines all competitor data for summary report",
"position": [
1712,
160
],
"parameters": {
"options": {},
"fieldsToAggregate": {
"fieldToAggregate": [
{}
]
}
},
"typeVersion": 1
},
{
"id": "627e426d-d7fc-49ee-9e21-51ee3c84ead1",
"name": "Créer un résumé quotidien",
"type": "n8n-nodes-base.code",
"notes": "Generates comprehensive summary report",
"position": [
1920,
160
],
"parameters": {
"jsCode": "// Create daily summary report\nconst allItems = $input.all();\n\nif (allItems.length === 0) {\n return [{\n json: {\n summary: 'No competitor data processed today',\n totalCompetitors: 0\n }\n }];\n}\n\nconst totalCompetitors = allItems.length;\nconst underpriced = allItems.filter(item => item.json.isUnderpriced).length;\nconst avgPriceDiff = (allItems.reduce((sum, item) => sum + parseFloat(item.json.priceDifference || 0), 0) / totalCompetitors).toFixed(2);\nconst lowestCompetitor = allItems.reduce((min, item) => \n item.json.competitorPrice < (min.json.competitorPrice || Infinity) ? item : min\n, allItems[0]);\nconst highestCompetitor = allItems.reduce((max, item) => \n item.json.competitorPrice > (max.json.competitorPrice || 0) ? item : max\n, allItems[0]);\n\nreturn [{\n json: {\n reportDate: new Date().toISOString(),\n summary: {\n totalCompetitors: totalCompetitors,\n competitorsUnderpriced: underpriced,\n avgPriceDifference: avgPriceDiff,\n lowestPrice: {\n competitor: lowestCompetitor.json.competitorName,\n price: lowestCompetitor.json.competitorPrice\n },\n highestPrice: {\n competitor: highestCompetitor.json.competitorName,\n price: highestCompetitor.json.competitorPrice\n },\n ourPrice: allItems[0].json.ourPrice\n },\n competitorDetails: allItems.map(item => ({\n name: item.json.competitorName,\n price: item.json.competitorPrice,\n difference: item.json.priceDifference + '%',\n url: item.json.competitorUrl\n }))\n }\n}];"
},
"typeVersion": 2
},
{
"id": "a227268b-22e0-43a4-8bf9-d3bd8fbe0fb7",
"name": "Envoyer le rapport quotidien à Slack",
"type": "n8n-nodes-base.slack",
"position": [
2112,
160
],
"webhookId": "4b39b79f-3cd8-4654-a7c2-710efdf7763e",
"parameters": {
"text": "=📊 *Daily Price Monitoring Report*\n\n*{{ $json.reportDate.split('T')[0] }}*\n\n📈 *Summary*\n• Total Competitors Monitored: {{ $json.summary.totalCompetitors }}\n• Competitors Underpricing Us: {{ $json.summary.competitorsUnderpriced }}\n• Average Price Difference: {{ $json.summary.avgPriceDifference }}%\n• Our Current Price: ${{ $json.summary.ourPrice }}\n\n💰 *Price Range*\n• Lowest: {{ $json.summary.lowestPrice.competitor }} - ${{ $json.summary.lowestPrice.price }}\n• Highest: {{ $json.summary.highestPrice.competitor }} - ${{ $json.summary.highestPrice.price }}\n\n_Full details logged to Google Sheets_",
"otherOptions": {}
},
"typeVersion": 2.1
},
{
"id": "7afc6c9c-63b7-46ae-8781-969301667dfe",
"name": "Déclencheur planifié",
"type": "n8n-nodes-base.scheduleTrigger",
"position": [
-80,
160
],
"parameters": {
"rule": {
"interval": [
{}
]
}
},
"typeVersion": 1.2
},
{
"id": "c8a2e2a8-15ca-4543-8d98-bf601f37826b",
"name": "Note adhésive",
"type": "n8n-nodes-base.stickyNote",
"position": [
-704,
-32
],
"parameters": {
"width": 500,
"height": 540,
"content": "# 📊 Competitive Price Monitoring & Alert System\n\nAutomates daily competitor price checks using Bright Data Web Scraper API. Compares prices, logs data to Google Sheets, and alerts your team via Slack and email when competitors undercut you. Generates daily summary reports for all products.\n\n**Who is it for?**\nE-commerce businesses and teams needing automatic, real-time price monitoring.\n\n**Setup:** \n- Connect Bright Data, Google Sheets, Slack, email \n- Add competitor URLs and alert thresholds \n- Customize scheduling and alert preferences\n\n**Customize:** \n- Edit URLs, thresholds, schedule, notification channels, and parsing logic as needed\n\n*Built by Daniel Shashko* \n[Connect on LinkedIn](https://www.linkedin.com/in/daniel-shashko/)"
},
"typeVersion": 1
},
{
"id": "69de6d19-552a-43c7-9347-852598b3c7ab",
"name": "Note adhésive1",
"type": "n8n-nodes-base.stickyNote",
"position": [
-96,
48
],
"parameters": {
"width": 150,
"height": 96,
"content": "Runs workflow automatically on schedule (daily/hourly)"
},
"typeVersion": 1
},
{
"id": "4f222dc5-89b0-4e46-863f-28a2e965550c",
"name": "Note adhésive2",
"type": "n8n-nodes-base.stickyNote",
"position": [
80,
48
],
"parameters": {
"width": 160,
"height": 96,
"content": "Configure competitor URLs, product names, and alert thresholds\n"
},
"typeVersion": 1
},
{
"id": "089ea0d9-e2c9-4b81-986a-82aa2ec91139",
"name": "Note adhésive3",
"type": "n8n-nodes-base.stickyNote",
"position": [
272,
48
],
"parameters": {
"width": 160,
"height": 96,
"content": "Process each competitor URL one at a time"
},
"typeVersion": 1
},
{
"id": "ebd8281b-919b-4554-9f07-9c53918fea35",
"name": "Note adhésive4",
"type": "n8n-nodes-base.stickyNote",
"position": [
480,
48
],
"parameters": {
"width": 160,
"height": 96,
"content": "Trigger web scraper to extract competitor pricing data"
},
"typeVersion": 1
},
{
"id": "aad282be-0820-4a59-9485-22faf4b380f2",
"name": "Note adhésive5",
"type": "n8n-nodes-base.stickyNote",
"position": [
672,
48
],
"parameters": {
"width": 160,
"height": 96,
"content": "Pause 10 seconds while scraper collects data\n"
},
"typeVersion": 1
},
{
"id": "41ccebcb-229c-47ee-bae8-f0e86fce585b",
"name": "Note adhésive6",
"type": "n8n-nodes-base.stickyNote",
"position": [
880,
48
],
"parameters": {
"width": 160,
"height": 96,
"content": "Retrieve completed scraping results from Bright Data API"
},
"typeVersion": 1
},
{
"id": "fc77a365-5c25-4c5f-9bd7-65297e179077",
"name": "Note adhésive7",
"type": "n8n-nodes-base.stickyNote",
"position": [
1072,
32
],
"parameters": {
"width": 160,
"height": 112,
"content": "Extract prices and calculate percentage differences vs yours"
},
"typeVersion": 1
},
{
"id": "6a34d163-e1b7-4c3d-a2c0-427515b44e37",
"name": "Note adhésive8",
"type": "n8n-nodes-base.stickyNote",
"position": [
1280,
-64
],
"parameters": {
"width": 160,
"height": 96,
"content": "Record all price checks to spreadsheet for tracking"
},
"typeVersion": 1
},
{
"id": "df90fe3b-d074-4bd5-a268-fcbca113bf23",
"name": "Note adhésive9",
"type": "n8n-nodes-base.stickyNote",
"position": [
1280,
400
],
"parameters": {
"width": 160,
"height": 96,
"content": "Determine if competitor price difference exceeds threshold"
},
"typeVersion": 1
},
{
"id": "cf0f39b0-0a8b-455c-b0d1-085393e32859",
"name": "Note adhésive10",
"type": "n8n-nodes-base.stickyNote",
"position": [
1488,
48
],
"parameters": {
"width": 160,
"height": 96,
"content": "Notify team via Slack when competitor undercuts pricing"
},
"typeVersion": 1
},
{
"id": "106a8a16-84d7-496b-a64c-e309e19e5f6c",
"name": "Note adhésive11",
"type": "n8n-nodes-base.stickyNote",
"position": [
1488,
464
],
"parameters": {
"width": 160,
"height": 96,
"content": "Email team when significant competitor price drops detected"
},
"typeVersion": 1
},
{
"id": "581cad81-d967-4174-900e-df00b25cb6d8",
"name": "Note adhésive12",
"type": "n8n-nodes-base.stickyNote",
"position": [
1680,
48
],
"parameters": {
"width": 160,
"height": 96,
"content": "Collect all competitor data for summary report generation"
},
"typeVersion": 1
},
{
"id": "79b14cca-a143-4248-83ec-a27f84d2c07c",
"name": "Note adhésive13",
"type": "n8n-nodes-base.stickyNote",
"position": [
1888,
48
],
"parameters": {
"width": 160,
"height": 96,
"content": "Calculate statistics: lowest, highest, average competitor prices"
},
"typeVersion": 1
},
{
"id": "8455dce9-89cf-4e8e-83ae-698a2aa03bfb",
"name": "Note adhésive14",
"type": "n8n-nodes-base.stickyNote",
"position": [
2080,
48
],
"parameters": {
"width": 160,
"height": 96,
"content": "Deliver comprehensive daily summary to Slack channel"
},
"typeVersion": 1
}
],
"pinData": {},
"connections": {
"b1f47493-ae09-4d67-9a6c-3e272bb6247b": {
"main": [
[
{
"node": "8c321bc9-d075-475a-9e8e-eeb11a7a72a2",
"type": "main",
"index": 0
},
{
"node": "cfc8a52b-8ece-4f60-809d-eb90c624448a",
"type": "main",
"index": 0
},
{
"node": "09ee23e0-057f-4fda-bdb0-191d85f6b9a2",
"type": "main",
"index": 0
}
]
]
},
"7afc6c9c-63b7-46ae-8781-969301667dfe": {
"main": [
[
{
"node": "e25e8bb0-052e-439a-9e79-a2b8bc1b68e3",
"type": "main",
"index": 0
}
]
]
},
"c3ac376c-a9af-4853-8f98-2bd392fdbccf": {
"main": [
[
{
"node": "09324ac9-3bc2-4e37-947b-6b972705589d",
"type": "main",
"index": 0
}
]
]
},
"7ef5a699-ee90-4059-b4df-6f3ca1706f00": {
"main": [
[
{
"node": "09324ac9-3bc2-4e37-947b-6b972705589d",
"type": "main",
"index": 0
}
]
]
},
"a25d2c0a-a757-40c4-a3ac-b69028c4eab4": {
"main": [
[
{
"node": "dfd8a43c-a62f-4e2d-89cd-54a89bb7e10f",
"type": "main",
"index": 0
}
]
]
},
"dfd8a43c-a62f-4e2d-89cd-54a89bb7e10f": {
"main": [
[
{
"node": "b1f47493-ae09-4d67-9a6c-3e272bb6247b",
"type": "main",
"index": 0
}
]
]
},
"627e426d-d7fc-49ee-9e21-51ee3c84ead1": {
"main": [
[
{
"node": "a227268b-22e0-43a4-8bf9-d3bd8fbe0fb7",
"type": "main",
"index": 0
}
]
]
},
"e25e8bb0-052e-439a-9e79-a2b8bc1b68e3": {
"main": [
[
{
"node": "09ee23e0-057f-4fda-bdb0-191d85f6b9a2",
"type": "main",
"index": 0
}
]
]
},
"09324ac9-3bc2-4e37-947b-6b972705589d": {
"main": [
[
{
"node": "627e426d-d7fc-49ee-9e21-51ee3c84ead1",
"type": "main",
"index": 0
}
]
]
},
"cfc8a52b-8ece-4f60-809d-eb90c624448a": {
"main": [
[
{
"node": "7ef5a699-ee90-4059-b4df-6f3ca1706f00",
"type": "main",
"index": 0
},
{
"node": "c3ac376c-a9af-4853-8f98-2bd392fdbccf",
"type": "main",
"index": 0
}
]
]
},
"962d1bc2-96b2-4fbb-8a7c-2b1b3a467a9e": {
"main": [
[
{
"node": "a25d2c0a-a757-40c4-a3ac-b69028c4eab4",
"type": "main",
"index": 0
}
]
]
},
"09ee23e0-057f-4fda-bdb0-191d85f6b9a2": {
"main": [
[
{
"node": "962d1bc2-96b2-4fbb-8a7c-2b1b3a467a9e",
"type": "main",
"index": 0
}
],
[
{
"node": "09324ac9-3bc2-4e37-947b-6b972705589d",
"type": "main",
"index": 0
}
]
]
}
}
}Comment utiliser ce workflow ?
Copiez le code de configuration JSON ci-dessus, créez un nouveau workflow dans votre instance n8n et sélectionnez "Importer depuis le JSON", collez la configuration et modifiez les paramètres d'authentification selon vos besoins.
Dans quelles scénarios ce workflow est-il adapté ?
Avancé - Étude de marché
Est-ce payant ?
Ce workflow est entièrement gratuit et peut être utilisé directement. Veuillez noter que les services tiers utilisés dans le workflow (comme l'API OpenAI) peuvent nécessiter un paiement de votre part.
Workflows recommandés
Daniel Shashko
@tomaxAI automation specialist and a marketing enthusiast. More than 6 years of experience in SEO/GEO. Senior SEO at Bright Data.
Partager ce workflow