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 →
{
"name": "uptime kuma alert",
"nodes": [
{
"parameters": {
"httpMethod": "POST",
"path": "REPLACE_WITH_WEBHOOK_PATH",
"options": {}
},
"type": "n8n-nodes-base.webhook",
"typeVersion": 2.1,
"position": [
-2320,
192
],
"id": "af61957f-a7bc-48b6-9a75-ed6a9a9e3469",
"name": "Webhook"
},
{
"parameters": {
"url": "={{$json.body.monitor.url}}",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "User-Agent",
"value": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127 Safari/537.36"
}
]
},
"options": {
"response": {
"response": {
"fullResponse": true,
"neverError": true
}
}
}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
-1040,
96
],
"id": "32b53fbc-cd1c-4af1-9631-38dbe438f3c0",
"name": "HTTP Request"
},
{
"parameters": {
"modelName": "models/gemini-2.5-pro",
"options": {}
},
"id": "eb6ead1d-5512-4686-941a-e72ec72a98fe",
"name": "GeminiModel1",
"type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
"position": [
-800,
336
],
"typeVersion": 1,
"credentials": {
"googlePalmApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"promptType": "define",
"text": "=\u4f60\u662f SRE \u503c\u73ed\u52a9\u624b\u3002\u4f60\u5c07\u770b\u5230\u76e3\u63a7\u540d\u7a31\u3001URL\uff0c\u4ee5\u53ca HTTP \u8acb\u6c42\u7d50\u679c\uff08\u72c0\u614b\u78bc\u3001\u932f\u8aa4\u3001\u56de\u61c9\u6a19\u982d\u3001\u5167\u5bb9\u7247\u6bb5\uff09\u3002\n\n\u4f60\u7684\u4efb\u52d9\uff1a\u50c5\u5728\u300c\u9700\u8981\u4eba\u5de5\u8655\u7406\u7684\u751f\u7522\u6545\u969c\u300d\u6642\u56de\u8986\u4e00\u6bb5\u7e41\u9ad4\u4e2d\u6587\u8aaa\u660e\uff08\u2264180\u5b57\uff09\uff0c\n\u76f4\u63a5\u8aaa\u6e05\u695a\uff1a\u54ea\u500b\u7ad9\u9ede\u3001\u51fa\u4e86\u4ec0\u9ebc\u554f\u984c\u3001\u932f\u8aa4\u78bc\u3001\u53ef\u80fd\u539f\u56e0\uff0f\u4e0b\u4e00\u6b65\u5efa\u8b70\uff08\u7c21\u77ed\u5373\u53ef\uff09\u3002\n\u5982\u679c\u4e0d\u662f\u9700\u8981\u4eba\u5de5\u8655\u7406\u7684\u6545\u969c\uff08\u4f8b\u5982\uff1a2xx/3xx\uff1b\u53ef\u9810\u671f\u7684 4xx \u5982 401/403/404\uff1b\u77ed\u66ab\u9650\u6d41\uff1b\u5df2\u6062\u5fa9\uff09\uff0c\u8acb\u8f38\u51fa\u5b57\u4e32SILENT\uff08\u4e0d\u8981\u6709\u4efb\u4f55\u5176\u4ed6\u6587\u5b57\u548c\u7b26\u865f\u4ee5\u53ca\u7a7a\u683c\uff09\u3002\n\u82e5\u6c92\u6709\u72c0\u614b\u78bc\u4f46\u5b58\u5728\u9023\u7dda\u932f\u8aa4\uff0c\u8acb\u8aaa\u660e\u300c\u932f\u8aa4\u78bc\uff1a\u7121\uff08\u9023\u7dda\u5931\u6557\uff0f\u903e\u6642\uff09\u300d\u3002\n\n\u3010\u76e3\u63a7\u3011\n\u540d\u7a31\uff1a{{ $node[\"Webhook\"].json.monitor.name }}\nURL\uff1a{{ $node[\"Webhook\"].json.monitor.url }}\n\n\u3010HTTP\u3011\n\u72c0\u614b\u78bc\uff1a{{ $json.statusCode }}\n\u72c0\u614b\u8a9e\uff1a{{ $json.statusMessage }}\n\u932f\u8aa4\uff1a{{ $json.error }}\n\u56de\u61c9\u6a19\u982d\uff08\u5b8c\u6574 JSON\uff09\uff1a{{ JSON.stringify($json.headers || {}, null, 2) }}\n\u5167\u5bb9\u7247\u6bb5\uff08\u82e5\u70ba\u5b57\u4e32\u5247\u539f\u6a23\u8f38\u51fa\uff0c\u5426\u5247\u8f49 JSON\uff09\uff1a{{\n (typeof $json.data === \"string\"\n ? $json.data\n : JSON.stringify($json.data ?? $json.body ?? {}, null, 2))\n}}",
"batching": {}
},
"type": "@n8n/n8n-nodes-langchain.chainLlm",
"typeVersion": 1.7,
"position": [
-800,
96
],
"id": "a239c060-d652-4d7d-a12d-0dbdf30e6c07",
"name": "Basic LLM Chain"
},
{
"parameters": {
"jsCode": "// \u8b80 LLM \u539f\u6a23\u8f38\u51fa\nconst raw = String($json.text ?? $json.output ?? $json.response ?? \"\").trim();\n\n// \u56b4\u683c\u5354\u8b70\uff1a\u53ea\u6709\u7cbe\u78ba \"SILENT\"\uff08\u5927\u5c0f\u5beb\u4e0d\u654f\u611f\uff09\u624d\u4e0d\u901a\u77e5\nconst isSilent = /^SILENT$/i.test(raw);\n\nreturn {\n shouldNotify: !isSilent,\n message: isSilent ? \"\" : raw,\n};"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
-448,
96
],
"id": "5df05e6e-c63a-43c0-9cd9-9ea7f3f6ec48",
"name": "Code"
},
{
"parameters": {
"amount": 3,
"unit": "minutes"
},
"type": "n8n-nodes-base.wait",
"typeVersion": 1.1,
"position": [
-1744,
128
],
"id": "fd835730-4de6-4fb6-8475-a14c79b312de",
"name": "Wait"
},
{
"parameters": {
"jsCode": "// Code1 \u2014 \u6536\u5230 UP\uff0c\u50c5\u8a18\u9304\u300c\u6700\u5f8c\u4e00\u6b21 UP \u7684\u6642\u9593\u6233\u300d\nconst store = $getWorkflowStaticData('global');\nif (!store.alerts) store.alerts = {};\n\nconst body = $json.body ?? {};\nconst monitorId =\n body.monitorID ??\n $json.monitor?.id ??\n $json.monitorID ??\n 'unknown';\n\nconst now = Date.now();\nconst rec = store.alerts[monitorId] ?? (store.alerts[monitorId] = {\n lastUpAt: 0,\n lastDownAt: 0,\n notified: {}\n});\nrec.lastUpAt = now;\n\nreturn [{ json: { ...$json, monitorId, lastUpAt: now } }];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
-1920,
256
],
"id": "a6c0463a-e343-4215-a57a-733d9540f0b1",
"name": "Code1"
},
{
"parameters": {
"jsCode": "// Code2 \u2014 \u8a18\u9304\u4e00\u6b21\u300cDOWN \u4e8b\u4ef6\u300d\u7684\u6642\u9593\u6233\uff0c\u4e26\u7522\u751f\u4e8b\u4ef6ID\nconst store = $getWorkflowStaticData('global');\nif (!store.alerts) store.alerts = {};\n\nconst body = $json.body ?? {};\nconst monitorId =\n body.monitorID ??\n $json.monitor?.id ??\n $json.monitorID ??\n 'unknown';\n\nconst downAt = Date.now(); // \u9019\u6b21 DOWN \u7684\u6642\u9593\u6233\uff08\u6beb\u79d2\uff09\nconst incidentId = `${monitorId}:${downAt}`; // \u672c\u6b21\u4e8b\u4ef6ID\uff08\u7528\u65bc\u53bb\u91cd\uff09\n\n// \u521d\u59cb\u5316/\u66f4\u65b0\u8a72\u76e3\u63a7\u7684\u5168\u57df\u72c0\u614b\uff08\u53ea\u5b58\u6700\u5f8c\u4e00\u6b21 UP/ DOWN \u7684\u6642\u9593\u6233\uff09\nconst rec = store.alerts[monitorId] ?? (store.alerts[monitorId] = {\n lastUpAt: 0,\n lastDownAt: 0,\n notified: {} // \u7528 incidentId \u505a\u53bb\u91cd\uff0c\u907f\u514d\u91cd\u8986\u901a\u77e5\n});\nrec.lastDownAt = downAt;\n\nreturn [{\n json: {\n ...$json, // \u4fdd\u7559\u539f\u59cb webhook \u8cc7\u6599\n monitorId,\n downAt,\n incidentId,\n recovered: false, // \u9810\u8a2d\u672a\u6062\u5fa9\uff08\u50c5\u4f54\u4f4d\uff0c\u771f\u6b63\u5224\u5b9a\u5728 Code3\uff09\n alreadyNotified: false // \u9810\u8a2d\u672a\u901a\u77e5\uff08\u771f\u6b63\u5224\u5b9a\u5728 Code3\uff09\n }\n}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
-1920,
128
],
"id": "af95469c-beba-447e-82c9-f37b7e90517c",
"name": "Code2"
},
{
"parameters": {
"jsCode": "// Code3 \u2014 Wait \u4e4b\u5f8c\u624d\u5224\u65b7\u662f\u5426\u6062\u5fa9\uff1a\n// \u898f\u5247\uff1a\u82e5\u300c\u6700\u5f8c\u4e00\u6b21 UP \u7684\u6642\u9593\u6233 >= \u672c\u6b21 DOWN \u7684\u6642\u9593\u6233\u300d\u2192 recovered = true\n// \u5426\u5247 recovered = false\nconst store = $getWorkflowStaticData('global');\nif (!store.alerts) store.alerts = {};\n\nconst monitorId =\n $json.monitorId ??\n $json.body?.monitorID ??\n $json.monitor?.id ??\n 'unknown';\n\nconst downAt = Number($json.downAt ?? 0);\nconst incidentId = String($json.incidentId ?? `${monitorId}:${downAt}`);\n\nconst rec = store.alerts[monitorId] ?? { lastUpAt: 0, lastDownAt: 0, notified: {} };\nconst lastUpAt = Number(rec.lastUpAt || 0);\n\n// \u662f\u5426\u5728\u9019\u6b21 DOWN \u4e4b\u5f8c\u51fa\u73fe\u904e UP\nconst recovered = lastUpAt >= downAt;\n\n// \u4e8b\u4ef6\u7d1a\u5225\u7684\u53bb\u91cd\uff1a\u540c\u4e00 incidentId \u53ea\u901a\u77e5\u4e00\u6b21\nconst alreadyNotified = !!(rec.notified && rec.notified[incidentId]);\n\n// \u82e5\u672a\u6062\u5fa9\u4e14\u5c1a\u672a\u901a\u77e5\uff0c\u505a\u53bb\u91cd\u6a19\u8a18\uff08\u767c\u9001\u5f8c If2 \u6703\u653e\u884c\u5230\u901a\u77e5\u7bc0\u9ede\uff09\nif (!recovered && !alreadyNotified) {\n rec.notified = rec.notified || {};\n rec.notified[incidentId] = true;\n}\n\n// \u82e5\u5df2\u6062\u5fa9\uff0c\u53ef\u9078\u64c7\u6e05\u7406\u904e\u671f\u7684\u53bb\u91cd\u6a19\u8a18\uff08\u4fdd\u5b88\uff1a\u4fdd\u7559\uff0c\u4ee5\u514d race\uff09\nreturn [{\n json: {\n ...$json,\n monitorId,\n downAt,\n incidentId,\n recovered, // \u7d66 If2 \u7528\n alreadyNotified // \u7d66 If2 \u7528\uff08\u4e8b\u4ef6\u53bb\u91cd\uff09\n }\n}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
-1568,
128
],
"id": "c1f4877b-bee7-4b37-96e0-3fd153a6ba5b",
"name": "Code3"
},
{
"parameters": {
"chatId": "REPLACE_WITH_DEMO_OPERATOR_CHAT_ID",
"text": "={{ $json.message }}",
"additionalFields": {
"appendAttribution": false
}
},
"type": "n8n-nodes-base.telegram",
"typeVersion": 1.2,
"position": [
0,
192
],
"id": "d38c7e2d-4a3b-485e-a956-edbb8b800414",
"name": "Send Demo Operator",
"credentials": {
"telegramApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"chatId": "REPLACE_WITH_DEMO_TEAM_CHAT_ID",
"text": "=@demo_oncall {{ $json.message }}",
"additionalFields": {
"appendAttribution": false
}
},
"type": "n8n-nodes-base.telegram",
"typeVersion": 1.2,
"position": [
0,
0
],
"id": "87b2f32b-f4dd-4322-a2d5-23b5389283d2",
"name": "Send Demo Team",
"credentials": {
"telegramApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "c3d6a352-e9fd-4f08-aae0-94124f557444",
"leftValue": "={{ $json[\"body\"][\"heartbeat\"][\"status\"].toString() }}",
"rightValue": "=0",
"operator": {
"type": "string",
"operation": "equals",
"name": "filter.operator.equals"
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"position": [
-2160,
192
],
"id": "8ecfb5dc-e50f-43f7-8085-2c72a3f818db",
"name": "If down"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "46a209ab-9f05-4ed4-893b-0d4a2d0ffe8a",
"leftValue": "={{$json.recovered.toString()}}",
"rightValue": "=false",
"operator": {
"type": "string",
"operation": "equals",
"name": "filter.operator.equals"
}
},
{
"id": "d30ff03e-c33f-4cc2-9d7c-d263574cc832",
"leftValue": "={{$json.alreadyNotified.toString()}}",
"rightValue": "=false",
"operator": {
"type": "string",
"operation": "equals",
"name": "filter.operator.equals"
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"position": [
-1376,
128
],
"id": "dd24ac24-15bd-4e83-a3e2-ca8f81d21bf1",
"name": "If no up"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "b4bbeb53-347f-438e-b1ad-3f20e599caec",
"leftValue": "={{$json.shouldNotify.toString()}}",
"rightValue": "true",
"operator": {
"type": "string",
"operation": "equals",
"name": "filter.operator.equals"
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"position": [
-272,
96
],
"id": "1673fdfc-6348-48cb-b0cb-8b54c8e9391d",
"name": "If need alert"
}
],
"connections": {
"Webhook": {
"main": [
[
{
"node": "If down",
"type": "main",
"index": 0
}
]
]
},
"GeminiModel1": {
"ai_languageModel": [
[
{
"node": "Basic LLM Chain",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"HTTP Request": {
"main": [
[
{
"node": "Basic LLM Chain",
"type": "main",
"index": 0
}
]
]
},
"Basic LLM Chain": {
"main": [
[
{
"node": "Code",
"type": "main",
"index": 0
}
]
]
},
"Code": {
"main": [
[
{
"node": "If need alert",
"type": "main",
"index": 0
}
]
]
},
"Code2": {
"main": [
[
{
"node": "Wait",
"type": "main",
"index": 0
}
]
]
},
"Wait": {
"main": [
[
{
"node": "Code3",
"type": "main",
"index": 0
}
]
]
},
"Code3": {
"main": [
[
{
"node": "If no up",
"type": "main",
"index": 0
}
]
]
},
"If down": {
"main": [
[
{
"node": "Code2",
"type": "main",
"index": 0
}
],
[
{
"node": "Code1",
"type": "main",
"index": 0
}
]
]
},
"If no up": {
"main": [
[
{
"node": "HTTP Request",
"type": "main",
"index": 0
}
]
]
},
"If need alert": {
"main": [
[
{
"node": "Send Demo Operator",
"type": "main",
"index": 0
},
{
"node": "Send Demo Team",
"type": "main",
"index": 0
}
]
]
}
},
"active": true,
"settings": {
"executionOrder": "v1"
},
"versionId": "REPLACE_WITH_VERSION_ID",
"meta": {
"templateCredsSetupCompleted": true
},
"id": "REPLACE_WITH_WORKFLOW_ID",
"tags": []
}
Credentials you'll need
Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.
googlePalmApitelegramApi
About this workflow
uptime kuma alert. Uses httpRequest, lmChatGoogleGemini, chainLlm, telegram. Webhook trigger; 14 nodes.
Source: https://github.com/AntonioPhilip/AlertFlow/blob/main/uptime_kuma_alert.json — original creator credit. Request a take-down →