Automatisation n8n : notifications de prix sur Discord
Ce workflow n8n a pour objectif d'automatiser l'envoi de notifications de prix sur Discord, permettant ainsi aux utilisateurs de rester informés des fluctuations de prix sur des produits spécifiques. Dans un contexte où les entreprises cherchent à optimiser leur stratégie de pricing, ce workflow s'avère particulièrement utile pour les e-commerçants et les équipes de vente qui souhaitent réagir rapidement aux changements de prix. Le premier déclencheur de ce workflow est un Cron qui permet d'exécuter le processus à intervalles réguliers. Ensuite, le workflow utilise un nœud HTTP pour récupérer les données de prix actuelles d'un produit via une API. Une fois les données extraites, un traitement est effectué pour vérifier si le prix a changé par rapport à un prix enregistré. Si le prix a baissé, un email est envoyé via le nœud d'envoi d'email pour notifier les utilisateurs d'une meilleure offre. En revanche, si le prix a augmenté, un autre email est envoyé pour informer les utilisateurs de cette hausse. Ce processus permet aux entreprises de garder leurs clients informés, d'augmenter l'engagement client et d'améliorer les taux de conversion. En intégrant ce workflow d'automatisation n8n, les entreprises peuvent ainsi réduire le temps passé à surveiller les prix tout en augmentant leur réactivité face aux fluctuations du marché.
Workflow n8n Discord, notifications, e-commerce : vue d'ensemble
Schéma des nœuds et connexions de ce workflow n8n, généré à partir du JSON n8n.
Workflow n8n Discord, notifications, e-commerce : détail des nœuds
Inscris-toi pour voir l'intégralité du workflow
Inscription gratuite
S'inscrire gratuitementBesoin d'aide ?{
"nodes": [
{
"name": "HTML Extract",
"type": "n8n-nodes-base.htmlExtract",
"position": [
-220,
-390
],
"parameters": {
"options": {},
"extractionValues": {
"values": [
{
"key": "price",
"cssSelector": "={{$node[\"initItem\"].json[\"selector\"]}}"
}
]
}
},
"typeVersion": 1
},
{
"name": "Cron",
"type": "n8n-nodes-base.cron",
"position": [
-1290,
-390
],
"parameters": {
"triggerTimes": {
"item": [
{
"mode": "everyX",
"unit": "minutes",
"value": 15
}
]
}
},
"typeVersion": 1
},
{
"name": "getActualPrice",
"type": "n8n-nodes-base.functionItem",
"position": [
-20,
-390
],
"parameters": {
"functionCode": "const globalData = getWorkflowStaticData('global');\n\nvar price = String(item.price).replace(\",\", \".\");\nprice = parseFloat(price);\n//price = price.replace(/\\D/g, '');\n//item.price = String(item.price).replace(\",\", \".\");\n//item.price = parseFloat(item.price);\n\nitem.priceExists = (price > 0 ? true : false)\nitem.price = price;\n\n// Update its data\nglobalData.actualPrice = item;\n\nreturn item;"
},
"typeVersion": 1
},
{
"name": "fetchWeb",
"type": "n8n-nodes-base.httpRequest",
"position": [
-410,
-390
],
"parameters": {
"url": "={{$node[\"initItem\"].json[\"link\"]}}",
"options": {},
"responseFormat": "string"
},
"typeVersion": 1
},
{
"name": "FunctionItem",
"type": "n8n-nodes-base.functionItem",
"position": [
1020,
-390
],
"parameters": {
"functionCode": "const globalData = getWorkflowStaticData('global');\n\nglobalData.iteration = 0;\n//var thiselem = $node[\"initItem\"].json;\n\n//const s1 = {'slug': thiselem.slug, \"link\": thiselem.link, \"selector\": thiselem.selector, \"price\":$node[\"getActualPrice\"].json.price, \"currency\": thiselem.currency};\n//const s2 = {'slug': thiselem.slug+'2', \"link\": thiselem.link, \"selector\": thiselem.selector, \"price\":$node[\"getActualPrice\"].json.price, \"currency\": thiselem.currency};\n//const s3 = {'slug': thiselem.slug+'3', \"link\": thiselem.link, \"selector\": thiselem.selector, \"price\":$node[\"getActualPrice\"].json.price, \"currency\": thiselem.currency};\n\nreturn $node[\"changeME\"].json.myWatchers;\n"
},
"typeVersion": 1
},
{
"name": "Write Binary File1",
"type": "n8n-nodes-base.writeBinaryFile",
"position": [
1850,
-390
],
"parameters": {
"fileName": "/data/kopacky.json",
"dataPropertyName": "=price"
},
"typeVersion": 1
},
{
"name": "Move Binary Data1",
"type": "n8n-nodes-base.moveBinaryData",
"position": [
1420,
-390
],
"parameters": {
"mode": "jsonToBinary",
"options": {},
"destinationKey": "price"
},
"typeVersion": 1
},
{
"name": "IF1",
"type": "n8n-nodes-base.if",
"position": [
550,
-370
],
"parameters": {
"conditions": {
"string": [
{
"value1": "={{$node[\"checkifexists\"].json[\"stdout\"]}}",
"value2": "Exists",
"operation": "notEqual"
}
]
}
},
"typeVersion": 1
},
{
"name": "checkifexists",
"type": "n8n-nodes-base.executeCommand",
"position": [
410,
-370
],
"parameters": {
"command": "if [ -r /data/kopacky.json ]; then echo Exists; fi"
},
"typeVersion": 1
},
{
"name": "IF3",
"type": "n8n-nodes-base.if",
"position": [
680,
110
],
"parameters": {
"conditions": {
"string": [
{
"value1": "={{$node[\"checkifexists\"].json[\"stdout\"]}}",
"value2": "Exists"
}
]
}
},
"typeVersion": 1
},
{
"name": "SaveToFile",
"type": "n8n-nodes-base.writeBinaryFile",
"position": [
1650,
110
],
"parameters": {
"fileName": "/data/kopacky.json",
"dataPropertyName": "=price"
},
"typeVersion": 1
},
{
"name": "JsonToBinary",
"type": "n8n-nodes-base.moveBinaryData",
"position": [
1500,
110
],
"parameters": {
"mode": "jsonToBinary",
"options": {},
"destinationKey": "price"
},
"typeVersion": 1
},
{
"name": "changeME",
"type": "n8n-nodes-base.functionItem",
"color": "#3BDD33",
"position": [
-830,
-390
],
"parameters": {
"functionCode": "const globalData = getWorkflowStaticData('global');\n\n//{'slug': 'kopacky', 'link': 'https://www.adsport.sk/kopacky-lisovky-adidas-x-19-3-ll-fg-ef0598/#1131861', 'currency': 'EUR'}[]\nvar myWatchers = [\n{'slug': 'kopacky', 'link': 'https://www.adsport.sk/kopacky-lisovky-adidas-x-19-3-ll-fg-ef0598/#1131861', 'selector':'.prices > strong:nth-child(1) > span:nth-child(1)', 'currency': 'EUR'},\n{'slug': 'kopacky2', 'link': 'https://www.adsport.sk/turfy-adidas-ace-tango-17-3-tf-by2203/', 'selector':'.col-xs-4 > strong:nth-child(1) > span:nth-child(1)', 'currency': 'EUR'},\n{'slug': 'mobilcek', 'link': 'https://mobil.bazos.sk/inzerat/112253662/predam-odolny-doogee-s60-52-4g-lte-nfc.php', 'selector':'.listadvlevo > table:nth-child(1) > tbody:nth-child(1) > tr:nth-child(5) > td:nth-child(2) > b:nth-child(2)', 'currency': 'EUR'},\n{'slug': 'ADIZERO RC 2', 'link': 'https://www.adsport.sk/panske-bezecke-topanky-adidas-adizero-rc-2-eg1187/', 'selector':'.col-xs-4 > strong:nth-child(1) > span:nth-child(1)', 'currency': 'EUR'}\n];\n\nitem.myWatchers = myWatchers;\nitem.watchersCount = myWatchers.length;\nglobalData.myWatchers = myWatchers;\n\nreturn item;"
},
"typeVersion": 1
},
{
"name": "initItem",
"type": "n8n-nodes-base.functionItem",
"position": [
-620,
-390
],
"parameters": {
"functionCode": "const globalData = getWorkflowStaticData('global');\n\nvar counter = globalData.iteration;\n\nitem.myWatchers[counter].watchersCount = item.watchersCount;\nitem.myWatchers[counter].canContinue = (globalData.iteration < item.watchersCount-1 ? true : false);\n//item.myWatchers[counter].canContinue = false;\n\nglobalData.iteration = counter + 1;\n\nreturn item.myWatchers[counter];"
},
"typeVersion": 1
},
{
"name": "savedItems",
"type": "n8n-nodes-base.readBinaryFile",
"position": [
850,
-20
],
"parameters": {
"filePath": "/data/kopacky.json",
"dataPropertyName": "savedItems"
},
"typeVersion": 1,
"continueOnFail": true,
"alwaysOutputData": true
},
{
"name": "itemsToJSON",
"type": "n8n-nodes-base.moveBinaryData",
"position": [
1020,
-20
],
"parameters": {
"options": {},
"sourceKey": "savedItems"
},
"typeVersion": 1
},
{
"name": "IF",
"type": "n8n-nodes-base.if",
"position": [
2190,
-90
],
"parameters": {
"conditions": {
"string": [],
"boolean": [
{
"value1": "={{$node[\"initItem\"].json[\"canContinue\"]}}",
"value2": true
}
]
}
},
"typeVersion": 1
},
{
"name": "initItem1",
"type": "n8n-nodes-base.functionItem",
"position": [
-1060,
-390
],
"parameters": {
"functionCode": "const globalData = getWorkflowStaticData('global');\n\nglobalData.iteration = 0;\n\nreturn item;"
},
"typeVersion": 1
},
{
"name": "IF2",
"type": "n8n-nodes-base.if",
"position": [
1850,
110
],
"parameters": {
"conditions": {
"number": [
{
"value1": "={{$node[\"getActualPrice\"].json[\"price\"]}}",
"value2": "={{$node[\"updateSavedItems1\"].json[\"oldPrice\"]}}"
}
],
"string": []
}
},
"typeVersion": 1
},
{
"name": "updateSavedItems",
"type": "n8n-nodes-base.functionItem",
"position": [
1350,
110
],
"parameters": {
"functionCode": "const globalData = getWorkflowStaticData('global');\n\nvar myitems = [];\nvar i;\nfor (i = 0; i < item.items.length; i++) { \n if($node[\"initItem\"].json.slug == item.items[i].slug && $node[\"getActualPrice\"].json.price < item.items[i].price) {\n item.items[i].price = $node[\"getActualPrice\"].json.price;\n }\n myitems.push(item.items[i]);\n} \n\nreturn myitems;\n"
},
"typeVersion": 1
},
{
"name": "updateSavedItems1",
"type": "n8n-nodes-base.functionItem",
"position": [
1200,
-20
],
"parameters": {
"functionCode": "const globalData = getWorkflowStaticData('global');\nvar oldPrice = null;\nvar myitems = [];\nvar i;\nfor (i = 0; i < item.length; i++) {\n if($node[\"initItem\"].json.slug == item[i].slug) {\n\n item[i].link = $node[\"initItem\"].json.link;\n item[i].selector = $node[\"initItem\"].json.selector;\n item[i].currency = $node[\"initItem\"].json.currency;\n \n if(!item[i].price){\n item[i].price = $node[\"getActualPrice\"].json.price;\n }\n \n if($node[\"getActualPrice\"].json.price < item[i].price){\n oldPrice = item[i].price;\n item[i].price = $node[\"getActualPrice\"].json.price;\n }\n \n \n }\n \n myitems.push(item[i]);\n} \n\n//item.somar = $node[\"initItem\"].json;\n//return globalData.actualPrice;\n\nvar itemm = {};\nitemm.items = myitems;\nitemm.oldPrice = oldPrice;\nreturn itemm;\n"
},
"typeVersion": 1
},
{
"name": "cleanData",
"type": "n8n-nodes-base.executeCommand",
"notes": "This will remove all storaged data.",
"position": [
-1290,
-560
],
"parameters": {
"command": "file=\"/data/kopacky.json\"\n[ -f $file ] && rm $file"
},
"typeVersion": 1
},
{
"name": "IF4",
"type": "n8n-nodes-base.if",
"position": [
150,
-390
],
"parameters": {
"conditions": {
"string": [],
"boolean": [
{
"value1": "={{$node[\"getActualPrice\"].json[\"priceExists\"]}}"
}
]
}
},
"typeVersion": 1
},
{
"name": "NotifyBetterPrice",
"type": "n8n-nodes-base.emailSend",
"position": [
1850,
-90
],
"parameters": {
"html": "=<h2>Nová cena je: {{$node[\"getActualPrice\"].json[\"price\"]}} {{$node[\"initItem\"].json[\"currency\"]}}</h2><br>\nPôvodná cena bola: {{$node[\"updateSavedItems1\"].json[\"oldPrice\"]}} {{$node[\"initItem\"].json[\"currency\"]}}<br>\nURL: {{$node[\"initItem\"].json[\"link\"]}}",
"text": "=",
"options": {},
"subject": "=Nová cena - {{$node[\"initItem\"].json[\"slug\"]}} - {{$node[\"getActualPrice\"].json[\"price\"]}} {{$node[\"initItem\"].json[\"currency\"]}}",
"toEmail": "sthosstudio@gmail.com",
"fromEmail": "hostovecky@weyou.sk"
},
"credentials": {
"smtp": "hostovecky@weyou.sk"
},
"typeVersion": 1
},
{
"name": "NotifyIncorrectPrice",
"type": "n8n-nodes-base.emailSend",
"position": [
270,
-690
],
"parameters": {
"html": "=Please check the link or selector for the item with slug <strong>{{$node[\"initItem\"].json[\"slug\"]}}</strong><br>\nURL: {{$node[\"initItem\"].json[\"link\"]}}",
"text": "=",
"options": {},
"subject": "={{$node[\"initItem\"].json[\"slug\"]}} - Getting price issue.",
"toEmail": "sthosstudio@gmail.com",
"fromEmail": "hostovecky@weyou.sk"
},
"credentials": {
"smtp": "hostovecky@weyou.sk"
},
"typeVersion": 1
}
],
"connections": {
"IF": {
"main": [
[
{
"node": "changeME",
"type": "main",
"index": 0
}
]
]
},
"IF1": {
"main": [
[
{
"node": "FunctionItem",
"type": "main",
"index": 0
}
],
[
{
"node": "IF3",
"type": "main",
"index": 0
}
]
]
},
"IF2": {
"main": [
[
{
"node": "NotifyBetterPrice",
"type": "main",
"index": 0
}
],
[
{
"node": "IF",
"type": "main",
"index": 0
}
]
]
},
"IF3": {
"main": [
[
{
"node": "savedItems",
"type": "main",
"index": 0
}
]
]
},
"IF4": {
"main": [
[
{
"node": "NotifyIncorrectPrice",
"type": "main",
"index": 0
}
],
[
{
"node": "checkifexists",
"type": "main",
"index": 0
}
]
]
},
"Cron": {
"main": [
[
{
"node": "initItem1",
"type": "main",
"index": 0
}
]
]
},
"changeME": {
"main": [
[
{
"node": "initItem",
"type": "main",
"index": 0
}
]
]
},
"fetchWeb": {
"main": [
[
{
"node": "HTML Extract",
"type": "main",
"index": 0
}
]
]
},
"initItem": {
"main": [
[
{
"node": "fetchWeb",
"type": "main",
"index": 0
}
]
]
},
"initItem1": {
"main": [
[
{
"node": "changeME",
"type": "main",
"index": 0
}
]
]
},
"SaveToFile": {
"main": [
[
{
"node": "IF2",
"type": "main",
"index": 0
}
]
]
},
"savedItems": {
"main": [
[
{
"node": "itemsToJSON",
"type": "main",
"index": 0
}
]
]
},
"itemsToJSON": {
"main": [
[
{
"node": "updateSavedItems1",
"type": "main",
"index": 0
}
]
]
},
"FunctionItem": {
"main": [
[
{
"node": "Move Binary Data1",
"type": "main",
"index": 0
}
]
]
},
"HTML Extract": {
"main": [
[
{
"node": "getActualPrice",
"type": "main",
"index": 0
}
]
]
},
"JsonToBinary": {
"main": [
[
{
"node": "SaveToFile",
"type": "main",
"index": 0
}
]
]
},
"checkifexists": {
"main": [
[
{
"node": "IF1",
"type": "main",
"index": 0
}
]
]
},
"getActualPrice": {
"main": [
[
{
"node": "IF4",
"type": "main",
"index": 0
}
]
]
},
"updateSavedItems": {
"main": [
[
{
"node": "JsonToBinary",
"type": "main",
"index": 0
}
]
]
},
"Move Binary Data1": {
"main": [
[
{
"node": "Write Binary File1",
"type": "main",
"index": 0
}
]
]
},
"NotifyBetterPrice": {
"main": [
[
{
"node": "IF",
"type": "main",
"index": 0
}
]
]
},
"updateSavedItems1": {
"main": [
[
{
"node": "updateSavedItems",
"type": "main",
"index": 0
}
]
]
},
"Write Binary File1": {
"main": [
[
{
"node": "IF",
"type": "main",
"index": 0
}
]
]
},
"NotifyIncorrectPrice": {
"main": [
[
{
"node": "checkifexists",
"type": "main",
"index": 0
}
]
]
}
}
}Workflow n8n Discord, notifications, e-commerce : pour qui est ce workflow ?
Ce workflow s'adresse principalement aux e-commerçants, aux équipes de vente et aux professionnels du marketing digital qui cherchent à optimiser leur communication avec les clients. Il est idéal pour les entreprises de taille petite à moyenne, avec un niveau technique intermédiaire requis pour sa mise en place.
Workflow n8n Discord, notifications, e-commerce : problème résolu
Ce workflow résout le problème de la surveillance manuelle des prix, qui peut être chronophage et source d'erreurs. En automatisant ce processus, les utilisateurs peuvent réduire les risques de manquer des opportunités de vente en raison de changements de prix. Les notifications en temps réel permettent également d'améliorer la satisfaction client, en offrant une transparence sur les fluctuations de prix.
Workflow n8n Discord, notifications, e-commerce : étapes du workflow
Étape 1 : Le workflow est déclenché par un Cron qui exécute le processus à intervalles réguliers.
- Étape 1 : Une requête HTTP est faite pour récupérer le prix actuel d'un produit.
- Étape 2 : Les données extraites sont traitées pour vérifier si le prix a changé.
- Étape 3 : Si le prix a baissé, un email est envoyé pour notifier les utilisateurs d'une meilleure offre.
- Étape 4 : Si le prix a augmenté, un autre email est envoyé pour informer les utilisateurs de cette hausse.
- Étape 5 : Les données sont sauvegardées pour un suivi futur.
Workflow n8n Discord, notifications, e-commerce : guide de personnalisation
Pour personnaliser ce workflow, commencez par modifier l'URL dans le nœud HTTP pour pointer vers l'API de votre choix. Vous pouvez également ajuster les paramètres du Cron pour définir la fréquence des vérifications de prix. Pour les notifications, personnalisez les adresses email dans les nœuds d'envoi d'email afin de cibler les utilisateurs souhaités. Enfin, adaptez les conditions dans les nœuds de vérification de prix pour répondre à vos critères spécifiques.