Back to Integrations
integrationMQTT node
integrationSlack node

MQTT and Slack integration

Save yourself the work of writing custom integrations for MQTT and Slack and use n8n instead. Build adaptable and scalable Development, Communication, and HITL workflows that work with your technology stack. All within a building experience you will love.

How to connect MQTT and Slack

  • Step 1: Create a new workflow
  • Step 2: Add and configure nodes
  • Step 3: Connect
  • Step 4: Customize and extend your integration
  • Step 5: Test and activate your workflow

Step 1: Create a new workflow and add the first step

In n8n, click the "Add workflow" button in the Workflows tab to create a new workflow. Add the starting point – a trigger on when your workflow should run: an app event, a schedule, a webhook call, another workflow, an AI chat, or a manual trigger. Sometimes, the HTTP Request node might already serve as your starting point.

MQTT and Slack integration: Create a new workflow and add the first step

Step 2: Add and configure MQTT and Slack nodes

You can find MQTT and Slack in the nodes panel. Drag them onto your workflow canvas, selecting their actions. Click each node, choose a credential, and authenticate to grant n8n access. Configure MQTT and Slack nodes one by one: input data on the left, parameters in the middle, and output data on the right.

MQTT and Slack integration: Add and configure MQTT and Slack nodes

Step 3: Connect MQTT and Slack

A connection establishes a link between MQTT and Slack (or vice versa) to route data through the workflow. Data flows from the output of one node to the input of another. You can have single or multiple connections for each node.

MQTT and Slack integration: Connect MQTT and Slack

Step 4: Customize and extend your MQTT and Slack integration

Use n8n's core nodes such as If, Split Out, Merge, and others to transform and manipulate data. Write custom JavaScript or Python in the Code node and run it as a step in your workflow. Connect MQTT and Slack with any of n8n’s 1000+ integrations, and incorporate advanced AI logic into your workflows.

MQTT and Slack integration: Customize and extend your MQTT and Slack integration

Step 5: Test and activate your MQTT and Slack workflow

Save and run the workflow to see if everything works as expected. Based on your configuration, data should flow from MQTT to Slack or vice versa. Easily debug your workflow: you can check past executions to isolate and fix the mistake. Once you've tested everything, make sure to save your workflow and activate it.

MQTT and Slack integration: Test and activate your MQTT and Slack workflow

IoT sensor monitoring with GPT-4o anomaly detection, MQTT & multi-channel alerts

{
"name": "IoT Sensor Data Aggregation with AI-Powered Anomaly Detection",
"nodes": [
{
"parameters": {
"content": "## How it works\nThis workflow monitors IoT sensors in real-time. It ingests data via MQTT or a schedule, normalizes the format, and removes duplicates using data fingerprinting. An AI Agent then analyzes readings against defined thresholds to detect anomalies. Finally, it routes alerts to Slack or Email based on severity and logs everything to Google Sheets.\n\n## Setup steps\n1. Configure the MQTT Trigger with your broker details.\n2. Set your specific limits in the Define Sensor Thresholds node.\n3. Connect your OpenAI credential to the Chat Model node.\n4. Authenticate the Gmail, Slack, and Google Sheets nodes.\n5. Create a Google Sheet with headers: timestamp, sensorId, location, readings, analysis.",
"height": 484,
"width": 360
},
"id": "298da7ff-0e47-4b6c-85f5-2ce77275cdf3",
"name": "Main Overview",
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"position": [
-2352,
-480
]
},
{
"parameters": {
"content": "## 1. Data Ingestion\nCaptures sensor data via MQTT for real-time streams or runs on a schedule for batch processing. Both streams are merged for unified handling.",
"height": 488,
"width": 412,
"color": 7
},
"id": "4794b396-cd71-429c-bcef-61780a55d707",
"name": "Section: Ingestion",
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"position": [
-1822,
-48
]
},
{
"parameters": {
"content": "## 2. Normalization & Deduplication\nSets monitoring thresholds, standardizes the JSON structure, creates a content hash, and filters out duplicate readings to prevent redundant API calls.",
"height": 316,
"width": 884,
"color": 7
},
"id": "339e7cb7-491e-44c9-b561-983e147237d8",
"name": "Section: Processing",
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"position": [
-1376,
32
]
},
{
"parameters": {
"content": "## 3. AI Anomaly Detection\nAn AI Agent evaluates sensor data against thresholds to identify anomalies, assigning severity levels and providing actionable recommendations.",
"height": 528,
"width": 460,
"color": 7
},
"id": "ebcb7ca3-f70c-4a90-8a2a-f489e7be4c73",
"name": "Section: AI Analysis",
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"position": [
-422,
24
]
},
{
"parameters": {
"content": "## 4. Routing & Archiving\nRoutes alerts based on severity (Critical = Email+Slack, Warning = Slack) and archives all data points to Google Sheets for historical analysis.",
"height": 756,
"width": 900,
"color": 7
},
"id": "7f2b32a5-d3b2-4fea-844f-4b39b8e8a239",
"name": "Section: Alerting",
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"position": [
94,
-196
]
},
{
"parameters": {
"topics": "sensors/+/data",
"options": {}
},
"id": "bc86720b-9de9-4693-b090-343d3ebad3a3",
"name": "MQTT Sensor Trigger",
"type": "n8n-nodes-base.mqttTrigger",
"typeVersion": 1,
"position": [
-1760,
88
]
},
{
"parameters": {
"rule": {
"interval": [
{
"field": "minutes",
"minutesInterval": 15
}
]
}
},
"id": "1c38f2d0-aa00-447e-bdae-bffd08c38461",
"name": "Batch Process Schedule",
"type": "n8n-nodes-base.scheduleTrigger",
"typeVersion": 1.2,
"position": [
-1760,
280
]
},
{
"parameters": {
"mode": "chooseBranch"
},
"id": "f9b41822-ee61-448b-b324-38483036e0e1",
"name": "Merge Triggers",
"type": "n8n-nodes-base.merge",
"typeVersion": 3,
"position": [
-1536,
184
]
},
{
"parameters": {
"mode": "raw",
"jsonOutput": "{\n "thresholds": {\n "temperature": {"min": -10, "max": 50, "unit": "C"},\n "humidity": {"min": 20, "max": 90, "unit": "%"},\n "pressure": {"min": 950, "max": 1050, "unit": "hPa"},\n "co2": {"min": 400, "max": 2000, "unit": "ppm"}\n },\n "alertConfig": {\n "criticalChannel": "#iot-critical",\n "warningChannel": "#iot-alerts",\n "emailRecipients": "[email protected]"\n }\n}",
"options": {}
},
"id": "308705a8-edc7-4435-9250-487aa528e033",
"name": "Define Sensor Thresholds",
"type": "n8n-nodes-base.set",
"typeVersion": 3.4,
"position": [
-1312,
184
]
},
{
"parameters": {
"jsCode": "const items = $input.all();\nconst thresholds = $('Define Sensor Thresholds').first().json.thresholds;\nconst results = [];\n\nfor (const item of items) {\n let sensorData;\n try {\n sensorData = typeof item.json.message === 'string' \n ? JSON.parse(item.json.message) \n : item.json;\n } catch (e) {\n sensorData = item.json;\n }\n \n const now = new Date();\n const reading = {\n sensorId: sensorData.sensorId || sensorData.topic?.split('/')[1] || 'unknown',\n location: sensorData.location || 'Main Facility',\n timestamp: now.toISOString(),\n readings: {\n temperature: sensorData.temperature ?? null,\n humidity: sensorData.humidity ?? null,\n pressure: sensorData.pressure ?? null,\n co2: sensorData.co2 ?? null\n },\n metadata: {\n receivedAt: now.toISOString(),\n source: item.json.topic || 'batch',\n thresholds: thresholds\n }\n };\n \n results.push({ json: reading });\n}\n\nreturn results;"
},
"id": "a2008189-5ace-418b-b0db-d51d63dcf2d8",
"name": "Parse Sensor Payload",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
-1088,
184
]
},
{
"parameters": {
"type": "SHA256",
"value": "={{ $json.sensorId + '-' + $json.timestamp + '-' + JSON.stringify($json.readings) }}",
"dataPropertyName": "dataHash"
},
"id": "bf8db555-a10e-4468-a44a-cdc4c97e5b80",
"name": "Generate Data Fingerprint",
"type": "n8n-nodes-base.crypto",
"typeVersion": 1,
"position": [
-864,
184
]
},
{
"parameters": {
"compare": "selectedFields",
"fieldsToCompare": "dataHash",
"options": {}
},
"id": "a45405e2-d211-449d-84d7-4538eaf56fcd",
"name": "Remove Duplicate Readings",
"type": "n8n-nodes-base.removeDuplicates",
"typeVersion": 1,
"position": [
-640,
184
]
},
{
"parameters": {
"text": "=Analyze this IoT sensor reading and determine if there are any anomalies:\n\nSensor ID: {{ $json.sensorId }}\nLocation: {{ $json.location }}\nTimestamp: {{ $json.timestamp }}\n\nReadings:\n- Temperature: {{ $json.readings.temperature }}°C (Normal: {{ $json.metadata.thresholds.temperature.min }} to {{ $json.metadata.thresholds.temperature.max }})\n- Humidity: {{ $json.readings.humidity }}% (Normal: {{ $json.metadata.thresholds.humidity.min }} to {{ $json.metadata.thresholds.humidity.max }})\n- CO2: {{ $json.readings.co2 }} ppm (Normal: {{ $json.metadata.thresholds.co2.min }} to {{ $json.metadata.thresholds.co2.max }})\n\nProvide your analysis in this exact JSON format:\n{\n "hasAnomaly": true/false,\n "severity": "critical"/"warning"/"normal",\n "anomalies": ["list of detected issues"],\n "reasoning": "explanation of your analysis",\n "recommendation": "suggested action"\n}",
"options": {
"systemMessage": "You are an IoT monitoring expert. Analyze sensor data and detect anomalies based on the provided thresholds. Be precise and provide actionable recommendations. Always respond in valid JSON format."
}
},
"id": "b60194ba-7b99-44e0-b0d7-9f1632dce4d4",
"name": "AI Anomaly Detector",
"type": "@n8n/n8n-nodes-langchain.agent",
"typeVersion": 1.7,
"position": [
-416,
184
]
},
{
"parameters": {
"jsCode": "const item = $input.first();\nconst originalData = $('Remove Duplicate Readings').first().json;\n\nlet aiAnalysis;\ntry {\n const responseText = item.json.output || item.json.text || '';\n const jsonMatch = responseText.match(/\{[\s\S]*\}/);\n aiAnalysis = jsonMatch ? JSON.parse(jsonMatch[0]) : {\n hasAnomaly: false,\n severity: 'normal',\n anomalies: [],\n reasoning: 'Unable to parse AI response',\n recommendation: 'Manual review required'\n };\n} catch (e) {\n aiAnalysis = {\n hasAnomaly: false,\n severity: 'normal',\n anomalies: [],\n reasoning: 'Parse error: ' + e.message,\n recommendation: 'Manual review required'\n };\n}\n\nreturn [{\n json: {\n ...originalData,\n analysis: aiAnalysis,\n alertLevel: aiAnalysis.severity,\n requiresAlert: aiAnalysis.hasAnomaly && aiAnalysis.severity !== 'normal'\n }\n}];"
},
"id": "a145a8c7-538c-411a-95c6-9485acdcb969",
"name": "Parse AI Analysis",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
-64,
184
]
},
{
"parameters": {
"rules": {
"values": [
{
"conditions": {
"options": {
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "critical",
"operator": {
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.alertLevel }}",
"rightValue": "critical"
}
]
},
"renameOutput": true,
"outputKey": "Critical"
},
{
"conditions": {
"options": {
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "warning",
"operator": {
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.alertLevel }}",
"rightValue": "warning"
}
]
},
"renameOutput": true,
"outputKey": "Warning"
}
]
},
"options": {
"fallbackOutput": "extra"
}
},
"id": "1ab9785d-9f7f-4840-b1e9-0afc62b00b12",
"name": "Route by Severity",
"type": "n8n-nodes-base.switch",
"typeVersion": 3.2,
"position": [
160,
168
]
},
{
"parameters": {
"sendTo": "={{ $('Define Sensor Thresholds').first().json.alertConfig.emailRecipients }}",
"subject": "=CRITICAL IoT Alert: {{ $json.sensorId }} - {{ $json.analysis.anomalies[0] || 'Anomaly Detected' }}",
"message": "=CRITICAL IoT SENSOR ALERT\n\nSensor: {{ $json.sensorId }}\nLocation: {{ $json.location }}\nTime: {{ $json.timestamp }}\n\nReadings:\n- Temperature: {{ $json.readings.temperature }}°C\n- Humidity: {{ $json.readings.humidity }}%\n- CO2: {{ $json.readings.co2 }} ppm\n\nAI Analysis:\n{{ $json.analysis.reasoning }}\n\nDetected Issues:\n{{ $json.analysis.anomalies.join('\n- ') }}\n\nRecommendation:\n{{ $json.analysis.recommendation }}",
"options": {}
},
"id": "28201a6c-10b5-4387-be89-10a57c634622",
"name": "Send Critical Email",
"type": "n8n-nodes-base.gmail",
"typeVersion": 2.1,
"position": [
384,
-80
],
"webhookId": "35b9f8fa-4a50-456e-b552-9fd20a25ccc5"
},
{
"parameters": {
"select": "channel",
"channelId": {
"__rl": true,
"mode": "name",
"value": "#iot-critical"
},
"text": "=🚨 CRITICAL IoT ALERT\n\nSensor: {{ $json.sensorId }}\nLocation: {{ $json.location }}\n\nReadings:\n• Temperature: {{ $json.readings.temperature }}°C\n• Humidity: {{ $json.readings.humidity }}%\n• CO2: {{ $json.readings.co2 }} ppm\n\nAI Analysis: {{ $json.analysis.reasoning }}\nRecommendation: {{ $json.analysis.recommendation }}",
"otherOptions": {}
},
"id": "c5a297be-ccef-40ba-9178-65805262efba",
"name": "Slack Critical Alert",
"type": "n8n-nodes-base.slack",
"typeVersion": 2.2,
"position": [
384,
112
],
"webhookId": "19113595-0208-4b37-b68c-c9788c19f618"
},
{
"parameters": {
"select": "channel",
"channelId": {
"__rl": true,
"mode": "name",
"value": "#iot-alerts"
},
"text": "=⚠️ IoT Warning\n\nSensor: {{ $json.sensorId }} | Location: {{ $json.location }}\nIssue: {{ $json.analysis.anomalies[0] || 'Threshold approaching' }}\nRecommendation: {{ $json.analysis.recommendation }}",
"otherOptions": {}
},
"id": "5c3d7acf-0211-44dd-9f4b-a43d3796abb1",
"name": "Slack Warning Alert",
"type": "n8n-nodes-base.slack",
"typeVersion": 2.2,
"position": [
384,
400
],
"webhookId": "37abfb19-f82f-4449-bd69-a65635b99606"
},
{
"parameters": {},
"id": "6bcbb42f-ec14-4f00-a091-babcc2d2d5c4",
"name": "Merge Alert Outputs",
"type": "n8n-nodes-base.merge",
"typeVersion": 3,
"position": [
608,
184
]
},
{
"parameters": {
"operation": "append",
"documentId": {
"__rl": true,
"mode": "list",
"value": ""
},
"sheetName": {
"__rl": true,
"mode": "list",
"value": ""
}
},
"id": "6243aa23-408d-4928-a512-811eeb3b5f9e",
"name": "Archive to Google Sheets",
"type": "n8n-nodes-base.googleSheets",
"typeVersion": 4.5,
"position": [
832,
184
]
},
{
"parameters": {
"model": "gpt-4o-mini",
"options": {
"temperature": 0.3
}
},
"id": "61081e8a-ebc9-465f-8beb-88af225e59f2",
"name": "OpenAI Chat Model",
"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
"typeVersion": 1.2,
"position": [
-344,
408
]
}
],
"pinData": {},
"connections": {
"MQTT Sensor Trigger": {
"main": [
[
{
"node": "Merge Triggers",
"type": "main",
"index": 0
}
]
]
},
"Batch Process Schedule": {
"main": [
[
{
"node": "Merge Triggers",
"type": "main",
"index": 1
}
]
]
},
"Merge Triggers": {
"main": [
[
{
"node": "Define Sensor Thresholds",
"type": "main",
"index": 0
}
]
]
},
"Define Sensor Thresholds": {
"main": [
[
{
"node": "Parse Sensor Payload",
"type": "main",
"index": 0
}
]
]
},
"Parse Sensor Payload": {
"main": [
[
{
"node": "Generate Data Fingerprint",
"type": "main",
"index": 0
}
]
]
},
"Generate Data Fingerprint": {
"main": [
[
{
"node": "Remove Duplicate Readings",
"type": "main",
"index": 0
}
]
]
},
"Remove Duplicate Readings": {
"main": [
[
{
"node": "AI Anomaly Detector",
"type": "main",
"index": 0
}
]
]
},
"AI Anomaly Detector": {
"main": [
[
{
"node": "Parse AI Analysis",
"type": "main",
"index": 0
}
]
]
},
"Parse AI Analysis": {
"main": [
[
{
"node": "Route by Severity",
"type": "main",
"index": 0
}
]
]
},
"Route by Severity": {
"main": [
[
{
"node": "Send Critical Email",
"type": "main",
"index": 0
},
{
"node": "Slack Critical Alert",
"type": "main",
"index": 0
}
],
[
{
"node": "Slack Warning Alert",
"type": "main",
"index": 0
}
],
[
{
"node": "Merge Alert Outputs",
"type": "main",
"index": 0
}
]
]
},
"Send Critical Email": {
"main": [
[
{
"node": "Merge Alert Outputs",
"type": "main",
"index": 0
}
]
]
},
"Slack Critical Alert": {
"main": [
[
{
"node": "Merge Alert Outputs",
"type": "main",
"index": 0
}
]
]
},
"Slack Warning Alert": {
"main": [
[
{
"node": "Merge Alert Outputs",
"type": "main",
"index": 0
}
]
]
},
"Merge Alert Outputs": {
"main": [
[
{
"node": "Archive to Google Sheets",
"type": "main",
"index": 0
}
]
]
},
"OpenAI Chat Model": {
"ai_languageModel": [
[
{
"node": "AI Anomaly Detector",
"type": "ai_languageModel",
"index": 0
}
]
]
}
},
"active": false,
"settings": {
"executionOrder": "v1"
},
"versionId": "",
"meta": {
"instanceId": "15d6057a37b8367f33882dd60593ee5f6cc0c59310ff1dc66b626d726083b48d"
},
"tags": []
}

Nodes used in this workflow

Popular MQTT and Slack workflows

+2

IoT Sensor Monitoring with GPT-4o Anomaly Detection, MQTT & Multi-Channel Alerts

{ "name": "IoT Sensor Data Aggregation with AI-Powered Anomaly Detection", "nodes": [ { "parameters": { "content": "## How it works\nThis workflow monitors IoT sensors in real-time. It ingests data via MQTT or a schedule, normalizes the format, and removes duplicates using data fingerprinting. An AI Agent then analyzes readings against defined thresholds to detect anomalies. Finally, it routes alerts to Slack or Email based on severity and logs everything to Google Sheets.\n\n## Setup steps\n1. Configure the MQTT Trigger with your broker details.\n2. Set your specific limits in the Define Sensor Thresholds node.\n3. Connect your OpenAI credential to the Chat Model node.\n4. Authenticate the Gmail, Slack, and Google Sheets nodes.\n5. Create a Google Sheet with headers: timestamp, sensorId, location, readings, analysis.", "height": 484, "width": 360 }, "id": "298da7ff-0e47-4b6c-85f5-2ce77275cdf3", "name": "Main Overview", "type": "n8n-nodes-base.stickyNote", "typeVersion": 1, "position": [ -2352, -480 ] }, { "parameters": { "content": "## 1. Data Ingestion\nCaptures sensor data via MQTT for real-time streams or runs on a schedule for batch processing. Both streams are merged for unified handling.", "height": 488, "width": 412, "color": 7 }, "id": "4794b396-cd71-429c-bcef-61780a55d707", "name": "Section: Ingestion", "type": "n8n-nodes-base.stickyNote", "typeVersion": 1, "position": [ -1822, -48 ] }, { "parameters": { "content": "## 2. Normalization & Deduplication\nSets monitoring thresholds, standardizes the JSON structure, creates a content hash, and filters out duplicate readings to prevent redundant API calls.", "height": 316, "width": 884, "color": 7 }, "id": "339e7cb7-491e-44c9-b561-983e147237d8", "name": "Section: Processing", "type": "n8n-nodes-base.stickyNote", "typeVersion": 1, "position": [ -1376, 32 ] }, { "parameters": { "content": "## 3. AI Anomaly Detection\nAn AI Agent evaluates sensor data against thresholds to identify anomalies, assigning severity levels and providing actionable recommendations.", "height": 528, "width": 460, "color": 7 }, "id": "ebcb7ca3-f70c-4a90-8a2a-f489e7be4c73", "name": "Section: AI Analysis", "type": "n8n-nodes-base.stickyNote", "typeVersion": 1, "position": [ -422, 24 ] }, { "parameters": { "content": "## 4. Routing & Archiving\nRoutes alerts based on severity (Critical = Email+Slack, Warning = Slack) and archives all data points to Google Sheets for historical analysis.", "height": 756, "width": 900, "color": 7 }, "id": "7f2b32a5-d3b2-4fea-844f-4b39b8e8a239", "name": "Section: Alerting", "type": "n8n-nodes-base.stickyNote", "typeVersion": 1, "position": [ 94, -196 ] }, { "parameters": { "topics": "sensors/+/data", "options": {} }, "id": "bc86720b-9de9-4693-b090-343d3ebad3a3", "name": "MQTT Sensor Trigger", "type": "n8n-nodes-base.mqttTrigger", "typeVersion": 1, "position": [ -1760, 88 ] }, { "parameters": { "rule": { "interval": [ { "field": "minutes", "minutesInterval": 15 } ] } }, "id": "1c38f2d0-aa00-447e-bdae-bffd08c38461", "name": "Batch Process Schedule", "type": "n8n-nodes-base.scheduleTrigger", "typeVersion": 1.2, "position": [ -1760, 280 ] }, { "parameters": { "mode": "chooseBranch" }, "id": "f9b41822-ee61-448b-b324-38483036e0e1", "name": "Merge Triggers", "type": "n8n-nodes-base.merge", "typeVersion": 3, "position": [ -1536, 184 ] }, { "parameters": { "mode": "raw", "jsonOutput": "{\n \"thresholds\": {\n \"temperature\": {\"min\": -10, \"max\": 50, \"unit\": \"C\"},\n \"humidity\": {\"min\": 20, \"max\": 90, \"unit\": \"%\"},\n \"pressure\": {\"min\": 950, \"max\": 1050, \"unit\": \"hPa\"},\n \"co2\": {\"min\": 400, \"max\": 2000, \"unit\": \"ppm\"}\n },\n \"alertConfig\": {\n \"criticalChannel\": \"#iot-critical\",\n \"warningChannel\": \"#iot-alerts\",\n \"emailRecipients\": \"[email protected]\"\n }\n}", "options": {} }, "id": "308705a8-edc7-4435-9250-487aa528e033", "name": "Define Sensor Thresholds", "type": "n8n-nodes-base.set", "typeVersion": 3.4, "position": [ -1312, 184 ] }, { "parameters": { "jsCode": "const items = $input.all();\nconst thresholds = $('Define Sensor Thresholds').first().json.thresholds;\nconst results = [];\n\nfor (const item of items) {\n let sensorData;\n try {\n sensorData = typeof item.json.message === 'string' \n ? JSON.parse(item.json.message) \n : item.json;\n } catch (e) {\n sensorData = item.json;\n }\n \n const now = new Date();\n const reading = {\n sensorId: sensorData.sensorId || sensorData.topic?.split('/')[1] || 'unknown',\n location: sensorData.location || 'Main Facility',\n timestamp: now.toISOString(),\n readings: {\n temperature: sensorData.temperature ?? null,\n humidity: sensorData.humidity ?? null,\n pressure: sensorData.pressure ?? null,\n co2: sensorData.co2 ?? null\n },\n metadata: {\n receivedAt: now.toISOString(),\n source: item.json.topic || 'batch',\n thresholds: thresholds\n }\n };\n \n results.push({ json: reading });\n}\n\nreturn results;" }, "id": "a2008189-5ace-418b-b0db-d51d63dcf2d8", "name": "Parse Sensor Payload", "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ -1088, 184 ] }, { "parameters": { "type": "SHA256", "value": "={{ $json.sensorId + '-' + $json.timestamp + '-' + JSON.stringify($json.readings) }}", "dataPropertyName": "dataHash" }, "id": "bf8db555-a10e-4468-a44a-cdc4c97e5b80", "name": "Generate Data Fingerprint", "type": "n8n-nodes-base.crypto", "typeVersion": 1, "position": [ -864, 184 ] }, { "parameters": { "compare": "selectedFields", "fieldsToCompare": "dataHash", "options": {} }, "id": "a45405e2-d211-449d-84d7-4538eaf56fcd", "name": "Remove Duplicate Readings", "type": "n8n-nodes-base.removeDuplicates", "typeVersion": 1, "position": [ -640, 184 ] }, { "parameters": { "text": "=Analyze this IoT sensor reading and determine if there are any anomalies:\n\nSensor ID: {{ $json.sensorId }}\nLocation: {{ $json.location }}\nTimestamp: {{ $json.timestamp }}\n\nReadings:\n- Temperature: {{ $json.readings.temperature }}°C (Normal: {{ $json.metadata.thresholds.temperature.min }} to {{ $json.metadata.thresholds.temperature.max }})\n- Humidity: {{ $json.readings.humidity }}% (Normal: {{ $json.metadata.thresholds.humidity.min }} to {{ $json.metadata.thresholds.humidity.max }})\n- CO2: {{ $json.readings.co2 }} ppm (Normal: {{ $json.metadata.thresholds.co2.min }} to {{ $json.metadata.thresholds.co2.max }})\n\nProvide your analysis in this exact JSON format:\n{\n \"hasAnomaly\": true/false,\n \"severity\": \"critical\"/\"warning\"/\"normal\",\n \"anomalies\": [\"list of detected issues\"],\n \"reasoning\": \"explanation of your analysis\",\n \"recommendation\": \"suggested action\"\n}", "options": { "systemMessage": "You are an IoT monitoring expert. Analyze sensor data and detect anomalies based on the provided thresholds. Be precise and provide actionable recommendations. Always respond in valid JSON format." } }, "id": "b60194ba-7b99-44e0-b0d7-9f1632dce4d4", "name": "AI Anomaly Detector", "type": "@n8n/n8n-nodes-langchain.agent", "typeVersion": 1.7, "position": [ -416, 184 ] }, { "parameters": { "jsCode": "const item = $input.first();\nconst originalData = $('Remove Duplicate Readings').first().json;\n\nlet aiAnalysis;\ntry {\n const responseText = item.json.output || item.json.text || '';\n const jsonMatch = responseText.match(/\\{[\\s\\S]*\\}/);\n aiAnalysis = jsonMatch ? JSON.parse(jsonMatch[0]) : {\n hasAnomaly: false,\n severity: 'normal',\n anomalies: [],\n reasoning: 'Unable to parse AI response',\n recommendation: 'Manual review required'\n };\n} catch (e) {\n aiAnalysis = {\n hasAnomaly: false,\n severity: 'normal',\n anomalies: [],\n reasoning: 'Parse error: ' + e.message,\n recommendation: 'Manual review required'\n };\n}\n\nreturn [{\n json: {\n ...originalData,\n analysis: aiAnalysis,\n alertLevel: aiAnalysis.severity,\n requiresAlert: aiAnalysis.hasAnomaly && aiAnalysis.severity !== 'normal'\n }\n}];" }, "id": "a145a8c7-538c-411a-95c6-9485acdcb969", "name": "Parse AI Analysis", "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ -64, 184 ] }, { "parameters": { "rules": { "values": [ { "conditions": { "options": { "caseSensitive": true, "typeValidation": "strict" }, "combinator": "and", "conditions": [ { "id": "critical", "operator": { "type": "string", "operation": "equals" }, "leftValue": "={{ $json.alertLevel }}", "rightValue": "critical" } ] }, "renameOutput": true, "outputKey": "Critical" }, { "conditions": { "options": { "caseSensitive": true, "typeValidation": "strict" }, "combinator": "and", "conditions": [ { "id": "warning", "operator": { "type": "string", "operation": "equals" }, "leftValue": "={{ $json.alertLevel }}", "rightValue": "warning" } ] }, "renameOutput": true, "outputKey": "Warning" } ] }, "options": { "fallbackOutput": "extra" } }, "id": "1ab9785d-9f7f-4840-b1e9-0afc62b00b12", "name": "Route by Severity", "type": "n8n-nodes-base.switch", "typeVersion": 3.2, "position": [ 160, 168 ] }, { "parameters": { "sendTo": "={{ $('Define Sensor Thresholds').first().json.alertConfig.emailRecipients }}", "subject": "=CRITICAL IoT Alert: {{ $json.sensorId }} - {{ $json.analysis.anomalies[0] || 'Anomaly Detected' }}", "message": "=CRITICAL IoT SENSOR ALERT\n\nSensor: {{ $json.sensorId }}\nLocation: {{ $json.location }}\nTime: {{ $json.timestamp }}\n\nReadings:\n- Temperature: {{ $json.readings.temperature }}°C\n- Humidity: {{ $json.readings.humidity }}%\n- CO2: {{ $json.readings.co2 }} ppm\n\nAI Analysis:\n{{ $json.analysis.reasoning }}\n\nDetected Issues:\n{{ $json.analysis.anomalies.join('\\n- ') }}\n\nRecommendation:\n{{ $json.analysis.recommendation }}", "options": {} }, "id": "28201a6c-10b5-4387-be89-10a57c634622", "name": "Send Critical Email", "type": "n8n-nodes-base.gmail", "typeVersion": 2.1, "position": [ 384, -80 ], "webhookId": "35b9f8fa-4a50-456e-b552-9fd20a25ccc5" }, { "parameters": { "select": "channel", "channelId": { "__rl": true, "mode": "name", "value": "#iot-critical" }, "text": "=🚨 CRITICAL IoT ALERT\n\nSensor: {{ $json.sensorId }}\nLocation: {{ $json.location }}\n\nReadings:\n• Temperature: {{ $json.readings.temperature }}°C\n• Humidity: {{ $json.readings.humidity }}%\n• CO2: {{ $json.readings.co2 }} ppm\n\nAI Analysis: {{ $json.analysis.reasoning }}\nRecommendation: {{ $json.analysis.recommendation }}", "otherOptions": {} }, "id": "c5a297be-ccef-40ba-9178-65805262efba", "name": "Slack Critical Alert", "type": "n8n-nodes-base.slack", "typeVersion": 2.2, "position": [ 384, 112 ], "webhookId": "19113595-0208-4b37-b68c-c9788c19f618" }, { "parameters": { "select": "channel", "channelId": { "__rl": true, "mode": "name", "value": "#iot-alerts" }, "text": "=⚠️ IoT Warning\n\nSensor: {{ $json.sensorId }} | Location: {{ $json.location }}\nIssue: {{ $json.analysis.anomalies[0] || 'Threshold approaching' }}\nRecommendation: {{ $json.analysis.recommendation }}", "otherOptions": {} }, "id": "5c3d7acf-0211-44dd-9f4b-a43d3796abb1", "name": "Slack Warning Alert", "type": "n8n-nodes-base.slack", "typeVersion": 2.2, "position": [ 384, 400 ], "webhookId": "37abfb19-f82f-4449-bd69-a65635b99606" }, { "parameters": {}, "id": "6bcbb42f-ec14-4f00-a091-babcc2d2d5c4", "name": "Merge Alert Outputs", "type": "n8n-nodes-base.merge", "typeVersion": 3, "position": [ 608, 184 ] }, { "parameters": { "operation": "append", "documentId": { "__rl": true, "mode": "list", "value": "" }, "sheetName": { "__rl": true, "mode": "list", "value": "" } }, "id": "6243aa23-408d-4928-a512-811eeb3b5f9e", "name": "Archive to Google Sheets", "type": "n8n-nodes-base.googleSheets", "typeVersion": 4.5, "position": [ 832, 184 ] }, { "parameters": { "model": "gpt-4o-mini", "options": { "temperature": 0.3 } }, "id": "61081e8a-ebc9-465f-8beb-88af225e59f2", "name": "OpenAI Chat Model", "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi", "typeVersion": 1.2, "position": [ -344, 408 ] } ], "pinData": {}, "connections": { "MQTT Sensor Trigger": { "main": [ [ { "node": "Merge Triggers", "type": "main", "index": 0 } ] ] }, "Batch Process Schedule": { "main": [ [ { "node": "Merge Triggers", "type": "main", "index": 1 } ] ] }, "Merge Triggers": { "main": [ [ { "node": "Define Sensor Thresholds", "type": "main", "index": 0 } ] ] }, "Define Sensor Thresholds": { "main": [ [ { "node": "Parse Sensor Payload", "type": "main", "index": 0 } ] ] }, "Parse Sensor Payload": { "main": [ [ { "node": "Generate Data Fingerprint", "type": "main", "index": 0 } ] ] }, "Generate Data Fingerprint": { "main": [ [ { "node": "Remove Duplicate Readings", "type": "main", "index": 0 } ] ] }, "Remove Duplicate Readings": { "main": [ [ { "node": "AI Anomaly Detector", "type": "main", "index": 0 } ] ] }, "AI Anomaly Detector": { "main": [ [ { "node": "Parse AI Analysis", "type": "main", "index": 0 } ] ] }, "Parse AI Analysis": { "main": [ [ { "node": "Route by Severity", "type": "main", "index": 0 } ] ] }, "Route by Severity": { "main": [ [ { "node": "Send Critical Email", "type": "main", "index": 0 }, { "node": "Slack Critical Alert", "type": "main", "index": 0 } ], [ { "node": "Slack Warning Alert", "type": "main", "index": 0 } ], [ { "node": "Merge Alert Outputs", "type": "main", "index": 0 } ] ] }, "Send Critical Email": { "main": [ [ { "node": "Merge Alert Outputs", "type": "main", "index": 0 } ] ] }, "Slack Critical Alert": { "main": [ [ { "node": "Merge Alert Outputs", "type": "main", "index": 0 } ] ] }, "Slack Warning Alert": { "main": [ [ { "node": "Merge Alert Outputs", "type": "main", "index": 0 } ] ] }, "Merge Alert Outputs": { "main": [ [ { "node": "Archive to Google Sheets", "type": "main", "index": 0 } ] ] }, "OpenAI Chat Model": { "ai_languageModel": [ [ { "node": "AI Anomaly Detector", "type": "ai_languageModel", "index": 0 } ] ] } }, "active": false, "settings": { "executionOrder": "v1" }, "versionId": "", "meta": { "instanceId": "15d6057a37b8367f33882dd60593ee5f6cc0c59310ff1dc66b626d726083b48d" }, "tags": [] }
+2

Real-time IoT Anomaly Detection with MQTT, GPT-4o-mini AI, and Multi-channel Alerts

How It Works MQTT ingests real-time sensor data from connected devices. The workflow normalizes the values and trains or retrains machine learning models on a defined schedule. An AI agent detects anomalies, validates the results for accuracy, and ensures reliable alerts. Detected issues are then routed to dashboards for visualization and sent via email notifications to relevant stakeholders, enabling timely monitoring and response. Setup Steps MQTT: Configure broker connection, set topic subscriptions, and verify data flow. ML Model: Define retraining schedule and specify historical data sources for model updates. AI Agent: Connect Claude or OpenAI APIs and configure anomaly validation prompts. Alerts: Set dashboard URL and email recipients to receive real-time notifications. Prerequisites MQTT broker credentials; historical training data; OpenAI/Claude API key; dashboard access; email service Use Cases IoT sensor monitoring; server performance tracking; network traffic anomalies; application log analysis; predictive maintenance alerts Customization Adjust sensitivity thresholds; swap ML models; modify notification channels; add Slack/Teams integration; customize validation rules Benefits Reduces detection latency 95%; eliminates manual monitoring; prevents false alerts; enables rapid incident response; improves system reliability

Build your own MQTT and Slack integration

Create custom MQTT and Slack workflows by choosing triggers and actions. Nodes come with global operations and settings, as well as app-specific parameters that can be configured. You can also use the HTTP Request node to query data from any app or service with a REST API.

Slack supported actions

Archive
Archives a conversation
Close
Closes a direct message or multi-person direct message
Create
Initiates a public or private channel-based conversation
Get
Get information about a channel
Get Many
Get many channels in a Slack team
History
Get a conversation's history of messages and events
Invite
Invite a user to a channel
Join
Joins an existing conversation
Kick
Removes a user from a channel
Leave
Leaves a conversation
Member
List members of a conversation
Open
Opens or resumes a direct message or multi-person direct message
Rename
Renames a conversation
Replies
Get a thread of messages posted to a channel
Set Purpose
Sets the purpose for a conversation
Set Topic
Sets the topic for a conversation
Unarchive
Unarchives a conversation
Get
Get Many
Get & filters team files
Upload
Create or upload an existing file
Delete
Get Permalink
Search
Send
Send and Wait for Response
Update
Add
Adds a reaction to a message
Get
Get the reactions of a message
Remove
Remove a reaction of a message
Add
Add a star to an item
Delete
Delete a star from an item
Get Many
Get many stars of autenticated user
Get
Get information about a user
Get Many
Get a list of many users
Get User's Profile
Get a user's profile
Get User's Status
Get online status of a user
Update User's Profile
Update a user's profile
Add Users
Create
Disable
Enable
Get Many
Get Users
Update

FAQs

  • Can MQTT connect with Slack?

  • Can I use MQTT’s API with n8n?

  • Can I use Slack’s API with n8n?

  • Is n8n secure for integrating MQTT and Slack?

  • How to get started with MQTT and Slack integration in n8n.io?

Need help setting up your MQTT and Slack integration?

Discover our latest community's recommendations and join the discussions about MQTT and Slack integration.
Nicolas N
Muhammed Iqbal P B
Nicolas N

Looking to integrate MQTT and Slack in your company?

Over 3000 companies switch to n8n every single week

Why use n8n to integrate MQTT with Slack

Build complex workflows, really fast

Build complex workflows, really fast

Handle branching, merging and iteration easily.
Pause your workflow to wait for external events.

Code when you need it, UI when you don't

Simple debugging

Your data is displayed alongside your settings, making edge cases easy to track down.

Use templates to get started fast

Use 1000+ workflow templates available from our core team and our community.

Reuse your work

Copy and paste, easily import and export workflows.

Implement complex processes faster with n8n

red iconyellow iconred iconyellow icon