Error Alert and Summarizer
工作流概述
这是一个包含13个节点的复杂工作流,主要用于自动化处理各种任务。
工作流源代码
{
"id": "3b1q6ZJTxeONrpUV",
"meta": {
"instanceId": ""
},
"name": "Error Alert and Summarizer",
"tags": [],
"nodes": [
{
"id": "d29a5b06-1609-416f-bc74-0274d3321019",
"name": "Error Trigger",
"type": "n8n-nodes-base.errorTrigger",
"position": [
-600,
-40
],
"parameters": {},
"typeVersion": 1
},
{
"id": "a71d3052-a89b-4e8e-baee-7fe245575f42",
"name": "OpenAI Chat Model",
"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
"position": [
528,
180
],
"parameters": {
"model": {
"__rl": true,
"mode": "list",
"value": "gpt-4o",
"cachedResultName": "gpt-4o"
},
"options": {}
},
"credentials": {
"openAiApi": {
"id": "786",
"name": "OpenAi account"
}
},
"typeVersion": 1.2
},
{
"id": "e71dee7b-4dfd-49ab-8939-f3808ee112d7",
"name": "Structured Output Parser",
"type": "@n8n/n8n-nodes-langchain.outputParserStructured",
"position": [
648,
180
],
"parameters": {
"jsonSchemaExample": "{
\"diagnosis\":\"\",
\"cause\":\"\",
\"resolution\":\"\"
}"
},
"typeVersion": 1.2
},
{
"id": "3611e9e8-f677-49c4-b06c-fa6c28f43930",
"name": "SET EMAIL",
"type": "n8n-nodes-base.set",
"position": [
-380,
-40
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "45e1443a-fb44-42f8-96ad-423197c7265b",
"name": "TO",
"type": "string",
"value": "myemail@myemail.com"
},
{
"id": "968b05dc-f476-4e13-8166-e62005d0f936",
"name": "CC",
"type": "string",
"value": "theiremail@theiremail.com"
},
{
"id": "570663c5-29c0-44fb-9992-908b7cca8136",
"name": "BCC",
"type": "string",
"value": "theiremail@theiremail.com"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "3676f72e-d06d-44f8-be35-19efe09a257e",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
-450,
-260
],
"parameters": {
"color": 3,
"height": 380,
"content": "# SET YOUR EMAILS"
},
"typeVersion": 1
},
{
"id": "f0b08a20-6ecc-4487-9a0a-30be07cc0cbb",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
-40,
-260
],
"parameters": {
"color": 3,
"width": 280,
"height": 380,
"content": "# Enable/Disable Manual Executions"
},
"typeVersion": 1
},
{
"id": "b35cd2a6-5f22-4e06-9bb0-880855c423a8",
"name": "Remove Manual Exec",
"type": "n8n-nodes-base.if",
"position": [
60,
-40
],
"parameters": {
"options": {
"ignoreCase": true
},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": false,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "9b2f3ff3-db9c-406b-a97f-37620dc5fab9",
"operator": {
"type": "string",
"operation": "notContains"
},
"leftValue": "={{ $json.mode }}",
"rightValue": "manual"
}
]
}
},
"typeVersion": 2.2
},
{
"id": "2a33b02a-78f1-4243-ba7d-f217ea4d1895",
"name": "Get Failed Exec",
"type": "n8n-nodes-base.n8n",
"position": [
-160,
-40
],
"parameters": {
"options": {
"activeWorkflows": true
},
"resource": "execution",
"operation": "get",
"executionId": "={{ $('Error Trigger').item.json.execution.id }}",
"requestOptions": {}
},
"credentials": {
"n8nApi": {
"id": "786",
"name": "n8n account"
}
},
"typeVersion": 1
},
{
"id": "b36ccbf9-4e47-44fc-aed3-424b6f121329",
"name": "Extract Error Details",
"type": "n8n-nodes-base.code",
"position": [
280,
-40
],
"parameters": {
"jsCode": "// 1) Grab your full execution JSON
const exec = items[0].json;
// 2) Build execution‐level metadata
const meta = {
executionId: exec.id,
finished: exec.finished,
mode: exec.mode,
status: exec.status,
createdAt: exec.createdAt,
startedAt: exec.startedAt,
stoppedAt: exec.stoppedAt,
deletedAt: exec.deletedAt,
workflowId: exec.workflowId,
workflowName: exec.workflowData?.name,
retryOf: exec.retryOf,
retrySuccessId: exec.retrySuccessId,
};
// 3) Identify trigger node name from startData
const runNodeFilter = exec.data?.startData?.runNodeFilter || [];
const triggerNodeName = runNodeFilter[0] || null;
// 4) Grab the raw trigger runData
const runData = exec.data?.resultData?.runData || {};
const triggerRuns = triggerNodeName ? (runData[triggerNodeName] || []) : [];
// 5) Extract the JSON payload from the first run of the trigger
let triggerPayload = {};
if (triggerRuns.length && triggerRuns[0].data?.main?.[0]?.[0]?.json) {
triggerPayload = triggerRuns[0].data.main[0][0].json;
}
// 6) Merge trigger info into meta
meta.triggerNodeName = triggerNodeName;
meta.triggerPayload = triggerPayload;
// 7) Now scan for all node errors, **excluding** any nodeName that contains “SERP”
const allErrors = [];
for (const [nodeName, runs] of Object.entries(runData)) {
// Skip any of the SERP nodes
if (nodeName.includes('SERP')) continue;
runs.forEach(run => {
if (run.executionStatus === 'error') {
const err = run.error || exec.data.resultData.error || {};
const nodeDef = err.node || run.node || {};
allErrors.push({
...meta, // exec + trigger metadata
nodeName,
nodeId: nodeDef.id,
nodeType: nodeDef.type,
nodeLabel: nodeDef.name,
startTime: run.startTime,
executionTime: run.executionTime,
source: run.source,
errorName: err.name,
errorMessage: err.message,
errorDescription: err.description,
httpCode: err.httpCode,
messages: err.messages,
context: err.context,
stack: err.stack,
parameters: nodeDef.parameters,
credentials: nodeDef.credentials,
});
}
});
}
// 8) Return results
if (!allErrors.length) {
return [{ json: { message: '✅ No (non‑SERP) errors found in this execution.' } }];
}
return allErrors.map(e => ({ json: e }));
"
},
"typeVersion": 2
},
{
"id": "a26fb0c8-99eb-466d-b201-89c402fa1af4",
"name": "Error Solver Agent",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
500,
-40
],
"parameters": {
"text": "=Can you please help me with this error that occured in my n8n workflow? {{ JSON.stringify($json) }}",
"options": {
"systemMessage": "You are an seasoned n8n expert with specializations in managing n8n instances and workflows. The user will provide a detailed error json object and your goal is to review, analyze and understand the error and using your expertise diagnose the error and provide a detailed report to the user with your diagnosis, cause and resolution so the user understands and can immediately fix the issue."
},
"promptType": "define",
"hasOutputParser": true
},
"typeVersion": 1.8
},
{
"id": "8cfd7229-3ff1-4ba1-a67d-caa21be8064f",
"name": "Set Diagnosis Fields",
"type": "n8n-nodes-base.set",
"position": [
876,
-40
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "fac5fbee-d63d-4148-b047-5ed5af4f2574",
"name": "error.diagnosis",
"type": "string",
"value": "={{ $json.output.diagnosis }}"
},
{
"id": "ece9388d-f667-4984-a143-7241f622fe76",
"name": "error.cause",
"type": "string",
"value": "={{ $json.output.cause }}"
},
{
"id": "acb6b34a-a651-42fc-a44a-331b2e0d745c",
"name": "error.resolution",
"type": "string",
"value": "={{ $json.output.resolution }}"
},
{
"id": "c765754b-d6d5-4592-ac3f-99a350bc3c19",
"name": "error.workflowName",
"type": "string",
"value": "={{ $('Extract Error Details').item.json.workflowName }}"
},
{
"id": "dabebc62-3e0c-4d22-afbf-54ba66a912fb",
"name": "error.workflowId",
"type": "string",
"value": "={{ $('Extract Error Details').item.json.workflowId }}"
},
{
"id": "6ab19800-9a0f-439f-bf62-7a7afc5bf958",
"name": "workflowLink",
"type": "string",
"value": "={{ $execution.resumeUrl.split('/').slice(0, 3).join('/') }}/workflow/{{ $('Extract Error Details').item.json.workflowId }}"
},
{
"id": "29daaea5-052b-46d4-8192-141db159bff2",
"name": "error.executionId",
"type": "string",
"value": "={{ $('Extract Error Details').item.json.executionId }}"
},
{
"id": "9e4e553c-c82b-41ec-8ee2-14162cdc3bd8",
"name": "executionLink",
"type": "string",
"value": "={{ $execution.resumeUrl.split('/').slice(0, 3).join('/') }}/workflow/{{ $('Extract Error Details').item.json.workflowId }}/executions/{{ $('Extract Error Details').item.json.executionId }}"
},
{
"id": "7269ea9f-ed49-46cd-89f2-d4a467da529d",
"name": "error.finished",
"type": "boolean",
"value": "={{ $('Extract Error Details').item.json.finished }}"
},
{
"id": "29a6e6d2-5058-4dd9-b2f9-3980a6a9073a",
"name": "error.startedAt",
"type": "string",
"value": "={{ $('Extract Error Details').item.json.startedAt }}"
},
{
"id": "a0ad0e13-5a6e-48db-9a80-74c09434de7f",
"name": "error.nodeName",
"type": "string",
"value": "={{ $('Extract Error Details').item.json.nodeName }}"
},
{
"id": "6c1001d4-a581-4520-9f16-a2c7cf0e1f84",
"name": "error.previousNode",
"type": "string",
"value": "={{ $('Extract Error Details').item.json.source[0].previousNode }}"
},
{
"id": "8c3402ca-3f15-44ae-9b96-ea37c174334c",
"name": "rawJson",
"type": "string",
"value": "={{ JSON.stringify($('Extract Error Details').item.json) }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "9e95edf0-b2f1-443b-9ac4-3e3b3311cad5",
"name": "Send Gmail",
"type": "n8n-nodes-base.gmail",
"position": [
1316,
-40
],
"webhookId": "2f253c1f-36c3-4d58-ba2f-3a50bb78f188",
"parameters": {
"sendTo": "={{ $('SET EMAIL').item.json.TO }}",
"message": "={{ $json.html }}",
"options": {
"ccList": "={{ $('SET EMAIL').item.json.CC }}",
"bccList": "={{ $('SET EMAIL').item.json.BCC }}",
"appendAttribution": true
},
"subject": "={{ $json.subject }}"
},
"credentials": {
"gmailOAuth2": {
"id": "786",
"name": "Gmail account"
}
},
"typeVersion": 2.1
},
{
"id": "1705ee42-0be4-41a2-8ff9-f6963eef7382",
"name": "Generate Email",
"type": "n8n-nodes-base.code",
"position": [
1100,
-40
],
"parameters": {
"jsCode": "// 1. Pull in your error payload
const rawInput = items[0].json;
const parsed = typeof rawInput === 'string' ? JSON.parse(rawInput) : rawInput;
const errorArray = Array.isArray(parsed) ? parsed : [parsed];
// 2. Build HTML & Markdown sections
let htmlSections = '';
for (const errObj of errorArray) {
const {
error: {
workflowName,
executionId,
nodeName,
previousNode,
diagnosis,
cause,
resolution,
startedAt,
},
workflowLink,
executionLink,
} = errObj;
// HTML block
htmlSections += `
<div style=\"border:1px solid #ddd;border-radius:4px;padding:16px;margin-bottom:20px;background:#fafafa;\">
<h3 style=\"margin:0 0 10px;color:#c0392b;font-family:Arial,sans-serif;\">
🛑 ${workflowName} — Error in node: ${nodeName}
</h3>
<p style=\"margin:4px 0;font-family:Arial,sans-serif;\">
<strong>Workflow:</strong>
<a href=\"${workflowLink}\" style=\"color:#2980b9;text-decoration:none;\">
${workflowName}
</a><br/>
<strong>Execution:</strong>
<a href=\"${executionLink}\" style=\"color:#2980b9;text-decoration:none;\">
#${executionId}
</a><br/>
<strong>Previous Node:</strong> ${previousNode}<br/>
<strong>Started At:</strong> ${new Date(startedAt).toLocaleString('en-US', { timeZone: 'America/New_York' })}
</p>
<hr style=\"border:none;border-top:1px solid #ccc;margin:12px 0;\"/>
<h4 style=\"margin:0 0 6px;color:#e67e22;font-family:Arial,sans-serif;\">🔍 Diagnosis</h4>
<p style=\"margin:4px 0 12px;font-family:Arial,sans-serif;\">${diagnosis}</p>
<h4 style=\"margin:0 0 6px;color:#e67e22;font-family:Arial,sans-serif;\">⚙️ Cause</h4>
<p style=\"margin:4px 0 12px;font-family:Arial,sans-serif;\">${cause}</p>
<h4 style=\"margin:0 0 6px;color:#e67e22;font-family:Arial,sans-serif;\">✅ Resolution</h4>
<p style=\"white-space:pre-wrap;margin:4px 0;font-family:Arial,sans-serif;\">${resolution}</p>
</div>`;
// 3. Wrap up
const html = `
<div style=\"font-family:Arial,sans-serif;color:#333;background:#fff;padding:20px;\">
<h2 style=\"margin-top:0;color:#2c3e50;\">Automated Error Report</h2>
${htmlSections}
<p style=\"font-size:12px;color:#777;font-family:Arial,sans-serif;\">
This message was generated automatically by
<a href=\"https://realsimple.dev\" style=\"color:#777;text-decoration:none;\"><b>Real Simple Solutions</b></a>.
</p>
<div style=\"background:#f0f4ff;padding:8px 12px;margin-top:6px;border-radius:6px;font-size:12px;font-family:Arial,sans-serif;\">
✨ <strong>Want more n8n AI automation templates?</strong><br>
Check out our full collection on
<a href=\"https://joeper.es/4jXyRub\" style=\"color:#0066cc;text-decoration:none;\"><b>Gumroad</b></a>.
</div>
</div>
`;
// 4. Return all three
return [
{
json: {
subject: `🚨 n8n Error: ${errorArray[0].error.workflowName} (#${errorArray[0].error.executionId})`,
html
},
},
];
"
},
"typeVersion": 2
}
],
"active": true,
"pinData": {},
"settings": {
"executionOrder": "v1"
},
"versionId": "be484a20-26cd-4df4-a993-f7d01c2956e6",
"connections": {
"SET EMAIL": {
"main": [
[
{
"node": "Get Failed Exec",
"type": "main",
"index": 0
}
]
]
},
"Error Trigger": {
"main": [
[
{
"node": "SET EMAIL",
"type": "main",
"index": 0
}
]
]
},
"Generate Email": {
"main": [
[
{
"node": "Send Gmail",
"type": "main",
"index": 0
}
]
]
},
"Get Failed Exec": {
"main": [
[
{
"node": "Remove Manual Exec",
"type": "main",
"index": 0
}
]
]
},
"OpenAI Chat Model": {
"ai_languageModel": [
[
{
"node": "Error Solver Agent",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Error Solver Agent": {
"main": [
[
{
"node": "Set Diagnosis Fields",
"type": "main",
"index": 0
}
]
]
},
"Remove Manual Exec": {
"main": [
[
{
"node": "Extract Error Details",
"type": "main",
"index": 0
}
]
]
},
"Set Diagnosis Fields": {
"main": [
[
{
"node": "Generate Email",
"type": "main",
"index": 0
}
]
]
},
"Extract Error Details": {
"main": [
[
{
"node": "Error Solver Agent",
"type": "main",
"index": 0
}
]
]
},
"Structured Output Parser": {
"ai_outputParser": [
[
{
"node": "Error Solver Agent",
"type": "ai_outputParser",
"index": 0
}
]
]
}
}
}
功能特点
- 自动检测新邮件
- AI智能内容分析
- 自定义分类规则
- 批量处理能力
- 详细的处理日志
技术分析
节点类型及作用
- Errortrigger
- @N8N/N8N Nodes Langchain.Lmchatopenai
- @N8N/N8N Nodes Langchain.Outputparserstructured
- Set
- Stickynote
复杂度评估
配置难度:
维护难度:
扩展性:
实施指南
前置条件
- 有效的Gmail账户
- n8n平台访问权限
- Google API凭证
- AI分类服务订阅
配置步骤
- 在n8n中导入工作流JSON文件
- 配置Gmail节点的认证信息
- 设置AI分类器的API密钥
- 自定义分类规则和标签映射
- 测试工作流执行
- 配置定时触发器(可选)
关键参数
| 参数名称 | 默认值 | 说明 |
|---|---|---|
| maxEmails | 50 | 单次处理的最大邮件数量 |
| confidenceThreshold | 0.8 | 分类置信度阈值 |
| autoLabel | true | 是否自动添加标签 |
最佳实践
优化建议
- 定期更新AI分类模型以提高准确性
- 根据邮件量调整处理批次大小
- 设置合理的分类置信度阈值
- 定期清理过期的分类规则
安全注意事项
- 妥善保管API密钥和认证信息
- 限制工作流的访问权限
- 定期审查处理日志
- 启用双因素认证保护Gmail账户
性能优化
- 使用增量处理减少重复工作
- 缓存频繁访问的数据
- 并行处理多个邮件分类任务
- 监控系统资源使用情况
故障排除
常见问题
邮件未被正确分类
检查AI分类器的置信度阈值设置,适当降低阈值或更新训练数据。
Gmail认证失败
确认Google API凭证有效且具有正确的权限范围,重新进行OAuth授权。
调试技巧
- 启用详细日志记录查看每个步骤的执行情况
- 使用测试邮件验证分类逻辑
- 检查网络连接和API服务状态
- 逐步执行工作流定位问题节点
错误处理
工作流包含以下错误处理机制:
- 网络超时自动重试(最多3次)
- API错误记录和告警
- 处理失败邮件的隔离机制
- 异常情况下的回滚操作