{ "updatedAt": "2026-05-14T00:18:01.110Z", "createdAt": "2026-05-12T16:59:40.394Z", "id": "G9ylNbHbnJ6fWX2C", "name": "n8n Failure Digest", "description": null, "active": true, "isArchived": false, "nodes": [ { "parameters": {}, "type": "n8n-nodes-base.manualTrigger", "typeVersion": 1, "position": [ -920, -120 ], "id": "a673b342-0e9e-44ae-a470-0a7ba93d135e", "name": "Manual Trigger" }, { "parameters": { "rule": { "interval": [ { "field": "cronExpression", "expression": "0 10 * * * *" } ] } }, "type": "n8n-nodes-base.scheduleTrigger", "typeVersion": 1.3, "position": [ -920, 80 ], "id": "6b8a395f-eadd-479d-980d-6f744f411c7d", "name": "Hourly Schedule" }, { "parameters": { "url": "http://127.0.0.1:5678/api/v1/executions?status=error&limit=100", "authentication": "genericCredentialType", "genericAuthType": "httpHeaderAuth", "options": {} }, "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.2, "position": [ -660, 0 ], "id": "afbf364e-4aca-4c7f-a43a-62a5e0b05d3b", "name": "List Failed Executions", "credentials": { "httpHeaderAuth": { "id": "UPAHgUJVRqZQceL4", "name": "n8n Public API (Failure Digest)" } } }, { "parameters": { "mode": "runOnceForAllItems", "jsCode": "const data = Array.isArray($json.data) ? $json.data : [];\nconst windowMinutes = 65;\nconst cutoff = Date.now() - windowMinutes * 60 * 1000;\nconst selfName = 'n8n Failure Digest';\nconst seen = new Set();\nconst out = [];\nfor (const ex of data) {\n const status = String(ex.status || '').toLowerCase();\n if (!['error', 'crashed'].includes(status)) continue;\n const t = Date.parse(ex.stoppedAt || ex.startedAt || ex.createdAt || '');\n if (Number.isFinite(t) && t < cutoff) continue;\n const id = String(ex.id || '');\n if (!id || seen.has(id)) continue;\n seen.add(id);\n out.push({ json: { id, status, startedAt: ex.startedAt, stoppedAt: ex.stoppedAt, workflowId: ex.workflowId, windowMinutes } });\n}\nreturn out;" }, "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ -420, 0 ], "id": "00f4d7aa-3890-4eb4-bcb4-64afd7675767", "name": "Recent Failure IDs" }, { "parameters": { "url": "=http://127.0.0.1:5678/api/v1/executions/{{$json.id}}?includeData=true", "authentication": "genericCredentialType", "genericAuthType": "httpHeaderAuth", "options": {} }, "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.2, "position": [ -180, 0 ], "id": "4de4125e-75d6-4896-93d1-1ce20dce2db8", "name": "Fetch Failure Details", "credentials": { "httpHeaderAuth": { "id": "UPAHgUJVRqZQceL4", "name": "n8n Public API (Failure Digest)" } } }, { "parameters": { "mode": "runOnceForAllItems", "jsCode": "const items = $input.all();\nconst windowMinutes = 65;\nconst now = Date.now();\nconst selfName = 'n8n Failure Digest';\nfunction arr(v) { return Array.isArray(v) ? v : (v == null ? [] : [v]); }\nfunction msg(err) {\n if (!err) return 'Unknown error';\n return String(err.message || err.description || err.name || err.code || JSON.stringify(err)).trim() || 'Unknown error';\n}\nfunction errType(err) { return String(err?.name || err?.type || err?.code || err?.httpCode || 'Error'); }\nfunction sig(s) {\n return String(s).split('\\n')[0]\n .replace(/https?:\\/\\/\\S+/g, '')\n .replace(/[0-9a-f]{8,}/gi, '')\n .replace(/\\b\\d{4,}\\b/g, '')\n .slice(0, 180);\n}\nfunction findErr(ex) {\n const rd = ex.data?.resultData || {};\n if (rd.error) return { node: rd.error.node?.name || rd.error.node || rd.lastNodeExecuted || 'unknown', error: rd.error };\n const runData = rd.runData || {};\n for (const [nodeName, attempts] of Object.entries(runData)) {\n for (const attempt of arr(attempts).slice().reverse()) {\n if (attempt?.error) return { node: nodeName, error: attempt.error };\n }\n }\n return { node: rd.lastNodeExecuted || 'unknown', error: ex.error || {} };\n}\nconst failures = [];\nfor (const item of items) {\n const ex = item.json || {};\n const workflowName = ex.workflowData?.name || ex.workflow?.name || `Workflow ${ex.workflowId || 'unknown'}`;\n if (workflowName === selfName) continue;\n const found = findErr(ex);\n const message = msg(found.error);\n const when = ex.stoppedAt || ex.startedAt || ex.createdAt || new Date(now).toISOString();\n failures.push({\n id: ex.id,\n workflowId: ex.workflowId || ex.workflowData?.id || 'unknown',\n workflowName,\n node: found.node || 'unknown',\n errorType: errType(found.error),\n message,\n signature: sig(message),\n when,\n status: ex.status || 'unknown',\n });\n}\nconst groups = new Map();\nfor (const f of failures) {\n const key = `${f.workflowId}\\u0000${f.node}\\u0000${f.errorType}\\u0000${f.signature}`;\n if (!groups.has(key)) groups.set(key, { workflowName: f.workflowName, workflowId: f.workflowId, node: f.node, errorType: f.errorType, signature: f.signature, count: 0, ids: [], latest: f.when });\n const g = groups.get(key);\n g.count++;\n if (g.ids.length < 8) g.ids.push(f.id);\n if (String(f.when) > String(g.latest)) g.latest = f.when;\n}\nconst sorted = [...groups.values()].sort((a,b) => b.count - a.count || String(b.latest).localeCompare(String(a.latest))).slice(0, 12);\nif (!sorted.length) return [];\nfunction telegramSafe(s) { return String(s || '').replace(/[\\u0000-\\u001f\\u007f]/g, ' ').slice(0, 3500); }\nconst lines = [];\nlines.push(`🚨 n8n Failure Digest: ${failures.length} failed execution(s) in the last ${windowMinutes} min`);\nlines.push('');\nsorted.forEach((g, i) => {\n lines.push(`${i+1}. ${g.workflowName}`);\n lines.push(` Node: ${g.node}`);\n lines.push(` ${g.count}x ${g.errorType}: ${g.signature}`);\n lines.push(` Execs: ${g.ids.join(', ')} | latest ${g.latest}`);\n});\nlines.push('');\nlines.push('Open n8n: http://127.0.0.1:18808');\n// Telegram node defaults to legacy Markdown, so escape characters that\n// commonly occur in workflow/node/error names (notably underscores).\nfunction telegramMarkdownSafe(s) { return String(s).replace(/([_*`\\[])/g, '\\\\$1'); }\nconst text = telegramMarkdownSafe(lines.join('\\n'));\nreturn [{ json: { text, totalFailures: failures.length, groups: sorted, generatedAt: new Date(now).toISOString() } }];" }, "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ 80, 0 ], "id": "f6b4eab8-7017-43e6-97c8-dce63873e097", "name": "Build Digest" }, { "parameters": { "chatId": "8367012007", "text": "={{ $json.text }}", "additionalFields": { "parse_mode": "", "disable_web_page_preview": true } }, "type": "n8n-nodes-base.telegram", "typeVersion": 1, "position": [ 340, 0 ], "id": "cf49d05d-5d81-404b-a751-ce56794985a9", "name": "Send Telegram Digest", "credentials": { "telegramApi": { "id": "aox4dyIWVSRdcH5z", "name": "Telegram Bot (OpenClaw)" } } }, { "parameters": { "method": "POST", "url": "https://discord.com/api/v10/channels/1494453542243532932/messages", "authentication": "genericCredentialType", "genericAuthType": "httpHeaderAuth", "sendBody": true, "specifyBody": "json", "jsonBody": "={{ JSON.stringify({ content: $json.text.substring(0, 2000) }) }}", "options": { "response": { "response": { "responseFormat": "text" } } } }, "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.2, "position": [ 340, 200 ], "id": "6c3086e4-0869-4003-94c3-66b4975f94e9", "name": "Send Discord Digest", "credentials": { "httpHeaderAuth": { "id": "UgPqYcoCNNIgr55m", "name": "Discord Bot Auth" } } } ], "connections": { "Manual Trigger": { "main": [ [ { "node": "List Failed Executions", "type": "main", "index": 0 } ] ] }, "Hourly Schedule": { "main": [ [ { "node": "List Failed Executions", "type": "main", "index": 0 } ] ] }, "List Failed Executions": { "main": [ [ { "node": "Recent Failure IDs", "type": "main", "index": 0 } ] ] }, "Recent Failure IDs": { "main": [ [ { "node": "Fetch Failure Details", "type": "main", "index": 0 } ] ] }, "Fetch Failure Details": { "main": [ [ { "node": "Build Digest", "type": "main", "index": 0 } ] ] }, "Build Digest": { "main": [ [ { "node": "Send Telegram Digest", "type": "main", "index": 0 }, { "node": "Send Discord Digest", "type": "main", "index": 0 } ] ] } }, "settings": { "executionOrder": "v1", "timezone": "America/Los_Angeles", "saveDataErrorExecution": "all", "saveDataSuccessExecution": "none", "callerPolicy": "workflowsFromSameOwner", "availableInMCP": false }, "staticData": { "node:Hourly Schedule": { "recurrenceRules": [] } }, "meta": null, "versionId": "2d85e3bf-d8cf-4274-bf61-5377241897da", "activeVersionId": "2d85e3bf-d8cf-4274-bf61-5377241897da", "versionCounter": 36, "triggerCount": 1, "shared": [ { "updatedAt": "2026-05-12T16:59:40.395Z", "createdAt": "2026-05-12T16:59:40.395Z", "role": "workflow:owner", "workflowId": "G9ylNbHbnJ6fWX2C", "projectId": "WGdp8QunI1tHpjXa", "project": { "updatedAt": "2026-03-11T21:08:10.005Z", "createdAt": "2026-03-11T21:05:11.541Z", "id": "WGdp8QunI1tHpjXa", "name": "will will ", "type": "personal", "icon": null, "description": null, "creatorId": "5ad50ead-6e6a-4d12-ab5b-e5db15835bb5" } } ], "tags": [], "activeVersion": { "updatedAt": "2026-05-14T00:18:01.111Z", "createdAt": "2026-05-14T00:18:01.111Z", "versionId": "2d85e3bf-d8cf-4274-bf61-5377241897da", "workflowId": "G9ylNbHbnJ6fWX2C", "nodes": [ { "parameters": {}, "type": "n8n-nodes-base.manualTrigger", "typeVersion": 1, "position": [ -920, -120 ], "id": "a673b342-0e9e-44ae-a470-0a7ba93d135e", "name": "Manual Trigger" }, { "parameters": { "rule": { "interval": [ { "field": "cronExpression", "expression": "0 10 * * * *" } ] } }, "type": "n8n-nodes-base.scheduleTrigger", "typeVersion": 1.3, "position": [ -920, 80 ], "id": "6b8a395f-eadd-479d-980d-6f744f411c7d", "name": "Hourly Schedule" }, { "parameters": { "url": "http://127.0.0.1:5678/api/v1/executions?status=error&limit=100", "authentication": "genericCredentialType", "genericAuthType": "httpHeaderAuth", "options": {} }, "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.2, "position": [ -660, 0 ], "id": "afbf364e-4aca-4c7f-a43a-62a5e0b05d3b", "name": "List Failed Executions", "credentials": { "httpHeaderAuth": { "id": "UPAHgUJVRqZQceL4", "name": "n8n Public API (Failure Digest)" } } }, { "parameters": { "mode": "runOnceForAllItems", "jsCode": "const data = Array.isArray($json.data) ? $json.data : [];\nconst windowMinutes = 65;\nconst cutoff = Date.now() - windowMinutes * 60 * 1000;\nconst selfName = 'n8n Failure Digest';\nconst seen = new Set();\nconst out = [];\nfor (const ex of data) {\n const status = String(ex.status || '').toLowerCase();\n if (!['error', 'crashed'].includes(status)) continue;\n const t = Date.parse(ex.stoppedAt || ex.startedAt || ex.createdAt || '');\n if (Number.isFinite(t) && t < cutoff) continue;\n const id = String(ex.id || '');\n if (!id || seen.has(id)) continue;\n seen.add(id);\n out.push({ json: { id, status, startedAt: ex.startedAt, stoppedAt: ex.stoppedAt, workflowId: ex.workflowId, windowMinutes } });\n}\nreturn out;" }, "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ -420, 0 ], "id": "00f4d7aa-3890-4eb4-bcb4-64afd7675767", "name": "Recent Failure IDs" }, { "parameters": { "url": "=http://127.0.0.1:5678/api/v1/executions/{{$json.id}}?includeData=true", "authentication": "genericCredentialType", "genericAuthType": "httpHeaderAuth", "options": {} }, "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.2, "position": [ -180, 0 ], "id": "4de4125e-75d6-4896-93d1-1ce20dce2db8", "name": "Fetch Failure Details", "credentials": { "httpHeaderAuth": { "id": "UPAHgUJVRqZQceL4", "name": "n8n Public API (Failure Digest)" } } }, { "parameters": { "mode": "runOnceForAllItems", "jsCode": "const items = $input.all();\nconst windowMinutes = 65;\nconst now = Date.now();\nconst selfName = 'n8n Failure Digest';\nfunction arr(v) { return Array.isArray(v) ? v : (v == null ? [] : [v]); }\nfunction msg(err) {\n if (!err) return 'Unknown error';\n return String(err.message || err.description || err.name || err.code || JSON.stringify(err)).trim() || 'Unknown error';\n}\nfunction errType(err) { return String(err?.name || err?.type || err?.code || err?.httpCode || 'Error'); }\nfunction sig(s) {\n return String(s).split('\\n')[0]\n .replace(/https?:\\/\\/\\S+/g, '')\n .replace(/[0-9a-f]{8,}/gi, '')\n .replace(/\\b\\d{4,}\\b/g, '')\n .slice(0, 180);\n}\nfunction findErr(ex) {\n const rd = ex.data?.resultData || {};\n if (rd.error) return { node: rd.error.node?.name || rd.error.node || rd.lastNodeExecuted || 'unknown', error: rd.error };\n const runData = rd.runData || {};\n for (const [nodeName, attempts] of Object.entries(runData)) {\n for (const attempt of arr(attempts).slice().reverse()) {\n if (attempt?.error) return { node: nodeName, error: attempt.error };\n }\n }\n return { node: rd.lastNodeExecuted || 'unknown', error: ex.error || {} };\n}\nconst failures = [];\nfor (const item of items) {\n const ex = item.json || {};\n const workflowName = ex.workflowData?.name || ex.workflow?.name || `Workflow ${ex.workflowId || 'unknown'}`;\n if (workflowName === selfName) continue;\n const found = findErr(ex);\n const message = msg(found.error);\n const when = ex.stoppedAt || ex.startedAt || ex.createdAt || new Date(now).toISOString();\n failures.push({\n id: ex.id,\n workflowId: ex.workflowId || ex.workflowData?.id || 'unknown',\n workflowName,\n node: found.node || 'unknown',\n errorType: errType(found.error),\n message,\n signature: sig(message),\n when,\n status: ex.status || 'unknown',\n });\n}\nconst groups = new Map();\nfor (const f of failures) {\n const key = `${f.workflowId}\\u0000${f.node}\\u0000${f.errorType}\\u0000${f.signature}`;\n if (!groups.has(key)) groups.set(key, { workflowName: f.workflowName, workflowId: f.workflowId, node: f.node, errorType: f.errorType, signature: f.signature, count: 0, ids: [], latest: f.when });\n const g = groups.get(key);\n g.count++;\n if (g.ids.length < 8) g.ids.push(f.id);\n if (String(f.when) > String(g.latest)) g.latest = f.when;\n}\nconst sorted = [...groups.values()].sort((a,b) => b.count - a.count || String(b.latest).localeCompare(String(a.latest))).slice(0, 12);\nif (!sorted.length) return [];\nfunction telegramSafe(s) { return String(s || '').replace(/[\\u0000-\\u001f\\u007f]/g, ' ').slice(0, 3500); }\nconst lines = [];\nlines.push(`🚨 n8n Failure Digest: ${failures.length} failed execution(s) in the last ${windowMinutes} min`);\nlines.push('');\nsorted.forEach((g, i) => {\n lines.push(`${i+1}. ${g.workflowName}`);\n lines.push(` Node: ${g.node}`);\n lines.push(` ${g.count}x ${g.errorType}: ${g.signature}`);\n lines.push(` Execs: ${g.ids.join(', ')} | latest ${g.latest}`);\n});\nlines.push('');\nlines.push('Open n8n: http://127.0.0.1:18808');\n// Telegram node defaults to legacy Markdown, so escape characters that\n// commonly occur in workflow/node/error names (notably underscores).\nfunction telegramMarkdownSafe(s) { return String(s).replace(/([_*`\\[])/g, '\\\\$1'); }\nconst text = telegramMarkdownSafe(lines.join('\\n'));\nreturn [{ json: { text, totalFailures: failures.length, groups: sorted, generatedAt: new Date(now).toISOString() } }];" }, "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ 80, 0 ], "id": "f6b4eab8-7017-43e6-97c8-dce63873e097", "name": "Build Digest" }, { "parameters": { "chatId": "8367012007", "text": "={{ $json.text }}", "additionalFields": { "parse_mode": "", "disable_web_page_preview": true } }, "type": "n8n-nodes-base.telegram", "typeVersion": 1, "position": [ 340, 0 ], "id": "cf49d05d-5d81-404b-a751-ce56794985a9", "name": "Send Telegram Digest", "credentials": { "telegramApi": { "id": "aox4dyIWVSRdcH5z", "name": "Telegram Bot (OpenClaw)" } } }, { "parameters": { "method": "POST", "url": "https://discord.com/api/v10/channels/1494453542243532932/messages", "authentication": "genericCredentialType", "genericAuthType": "httpHeaderAuth", "sendBody": true, "specifyBody": "json", "jsonBody": "={{ JSON.stringify({ content: $json.text.substring(0, 2000) }) }}", "options": { "response": { "response": { "responseFormat": "text" } } } }, "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.2, "position": [ 340, 200 ], "id": "6c3086e4-0869-4003-94c3-66b4975f94e9", "name": "Send Discord Digest", "credentials": { "httpHeaderAuth": { "id": "UgPqYcoCNNIgr55m", "name": "Discord Bot Auth" } } } ], "connections": { "Manual Trigger": { "main": [ [ { "node": "List Failed Executions", "type": "main", "index": 0 } ] ] }, "Hourly Schedule": { "main": [ [ { "node": "List Failed Executions", "type": "main", "index": 0 } ] ] }, "List Failed Executions": { "main": [ [ { "node": "Recent Failure IDs", "type": "main", "index": 0 } ] ] }, "Recent Failure IDs": { "main": [ [ { "node": "Fetch Failure Details", "type": "main", "index": 0 } ] ] }, "Fetch Failure Details": { "main": [ [ { "node": "Build Digest", "type": "main", "index": 0 } ] ] }, "Build Digest": { "main": [ [ { "node": "Send Telegram Digest", "type": "main", "index": 0 }, { "node": "Send Discord Digest", "type": "main", "index": 0 } ] ] } }, "authors": "will will", "name": null, "description": null, "autosaved": false, "workflowPublishHistory": [ { "createdAt": "2026-05-14T00:18:01.158Z", "id": 1491, "workflowId": "G9ylNbHbnJ6fWX2C", "versionId": "2d85e3bf-d8cf-4274-bf61-5377241897da", "event": "activated", "userId": "5ad50ead-6e6a-4d12-ab5b-e5db15835bb5" } ] } }