自动化安全警报分类:NixGuard AI并路由到Slack或Jira
高级
这是一个SecOps, AI Summarization领域的自动化工作流,包含 19 个节点。主要使用 If, Set, Code, Slack, Switch 等节点。 自动化安全警报分类:NixGuard AI并路由到Slack或Jira
前置要求
- •Slack Bot Token 或 Webhook URL
工作流预览
可视化展示节点连接关系,支持缩放和平移
导出工作流
复制以下 JSON 配置到 n8n 导入,即可使用此工作流
{
"meta": {
"instanceId": "558d88703fb65b2d0e44613bc35916258b0f0bf983c5d4730c00c424b77ca36a",
"templateCredsSetupCompleted": true
},
"nodes": [
{
"id": "40fb885c-9077-447c-a236-2262ff465d29",
"name": "每天上午 8 点运行",
"type": "n8n-nodes-base.scheduleTrigger",
"position": [
740,
1380
],
"parameters": {
"rule": {
"interval": [
{
"field": "hours"
}
]
}
},
"typeVersion": 1.1
},
{
"id": "e5f01889-2ae6-4563-8f34-836f1556e1f0",
"name": "解析警报数组",
"type": "n8n-nodes-base.code",
"position": [
760,
1620
],
"parameters": {
"jsCode": "// Get the raw output string from the previous node.\nconst rawOutput = $input.first().json.output;\n\n// The AI often wraps JSON in Markdown code blocks (```json ... ```).\n// We need to extract the pure JSON string from inside the fences.\n// This regex will find the content between the fences. If no fences are found,\n// it will fall back to using the entire rawOutput string.\nconst jsonStringMatch = rawOutput.match(/```json\\s*([\\s\\S]*?)\\s*```/);\nconst jsonString = jsonStringMatch ? jsonStringMatch[1] : rawOutput.trim();\n\n// Now, try to parse the *cleaned* string.\ntry {\n const alerts = JSON.parse(jsonString);\n \n // Check if the result is a non-empty array.\n if (Array.isArray(alerts) && alerts.length > 0) {\n // Success! Pass the alerts to the next node.\n return [{ json: { alerts } }];\n }\n} catch (e) {\n // This will catch errors if the cleaned string is still not valid JSON.\n console.error(\"NixGuard did not return a valid JSON array even after cleaning:\", e);\n console.error(\"String that failed to parse:\", jsonString);\n}\n\n// If parsing fails, it's not an array, or it's empty, return no items.\n// This will correctly route the workflow to the 'false' branch of the IF node.\nreturn [];"
},
"typeVersion": 2
},
{
"id": "6a3c2d13-ea2c-4a21-8063-cee59b220746",
"name": "设置摘要提示",
"type": "n8n-nodes-base.set",
"position": [
1380,
1820
],
"parameters": {
"values": {
"string": [
{
"name": "chatInput",
"value": "=Act as a senior security analyst reporting to a non-technical executive. Analyze the following JSON array of all high-severity security alerts from the last 24 hours.\n\nYour response MUST be a single, valid JSON object and nothing else. Do not include any text before or after the JSON, and do not wrap it in Markdown code fences (```json).\n\nYour output must strictly adhere to the following structure:\n{\n \"ai_priority\": \"<'Critical' | 'High' | 'Medium' | 'Low'>\",\n \"ai_summary\": \"<A single sentence summarizing the day's overall security risk.>\",\n \"total_critical_alerts\": <Total number of alerts with 'critical' severity>,\n \"key_observations\": [\n \"<Bulleted summary of the most significant activities or threat patterns, focused on business impact.>\",\n \"<Another bulleted summary point.>\",\n \"<And another, if necessary.>\"\n ],\n \"recommendation\": \"<A single, clear, actionable recommendation.>\"\n}\n\nHere is the raw alert data:\n{{ JSON.stringify($json) }}"
},
{
"name": "apiKey",
"value": ""
}
]
},
"options": {}
},
"typeVersion": 2
},
{
"id": "d27114b8-536c-4937-8af0-b6a4e0d20d9f",
"name": "设置 API 密钥和初始提示",
"type": "n8n-nodes-base.set",
"position": [
980,
1380
],
"parameters": {
"values": {
"string": [
{
"name": "apiKey",
"value": ""
},
{
"name": "chatInput",
"value": "Review all security data from the last 24 hours. List all significant security alerts found. Your response MUST be a single, valid, minified JSON array of objects. Each object in the array should represent a distinct alert. If no significant alerts are found, return an empty array []."
}
]
},
"options": {}
},
"typeVersion": 2
},
{
"id": "0adc2f21-8480-4749-9f0c-ef05b46b8b29",
"name": "执行:获取每日事件为 JSON(通过 NixGuard RAG 和 Wazuh 集成获取实时安全洞察)",
"type": "n8n-nodes-base.executeWorkflow",
"position": [
1220,
1380
],
"parameters": {
"options": {},
"workflowId": {
"__rl": true,
"mode": "list",
"value": "I0nUORqYTwDFZa51",
"cachedResultName": "Get Real-Time Security Insights with NixGuard RAG and Wazuh Integration"
},
"workflowInputs": {
"value": {},
"schema": [],
"mappingMode": "defineBelow",
"matchingColumns": [],
"attemptToConvertTypes": false,
"convertFieldsToString": true
}
},
"typeVersion": 1.2
},
{
"id": "40caac74-9e6c-4387-bc52-3bbe31e98481",
"name": "条件判断",
"type": "n8n-nodes-base.if",
"position": [
980,
1620
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "bb7ac757-8402-446e-9ee7-d0be89c769a7",
"operator": {
"type": "array",
"operation": "exists",
"singleValue": true
},
"leftValue": "={{ $json.alerts }}",
"rightValue": ""
}
]
}
},
"typeVersion": 2.2
},
{
"id": "f066f0e6-fa5d-4ab6-9d0c-0b6b5f9bb269",
"name": "工作流概述",
"type": "n8n-nodes-base.stickyNote",
"position": [
720,
1060
],
"parameters": {
"color": 7,
"width": 520,
"height": 260,
"content": "## 💡 工作流概述"
},
"typeVersion": 1
},
{
"id": "c8cac8b0-dac8-42ed-bb38-9daba321de8e",
"name": "提取 AI 优先级和摘要",
"type": "n8n-nodes-base.set",
"position": [
1160,
2040
],
"parameters": {
"values": {
"string": [
{
"name": "ai_priority",
"value": "={{ $json.ai_priority }}"
},
{
"name": "ai_summary",
"value": "={{ $json.ai_summary }}"
}
]
},
"options": {}
},
"typeVersion": 2
},
{
"id": "d047a378-b41a-4652-83e8-85ed0e87a2d9",
"name": "执行:生成 Slack 消息(通过 NixGuard RAG 和 Wazuh 集成获取实时安全洞察)",
"type": "n8n-nodes-base.executeWorkflow",
"position": [
760,
2040
],
"parameters": {
"options": {},
"workflowId": {
"__rl": true,
"mode": "list",
"value": "I0nUORqYTwDFZa51",
"cachedResultName": "Get Real-Time Security Insights with NixGuard RAG and Wazuh Integration"
},
"workflowInputs": {
"value": {},
"schema": [],
"mappingMode": "defineBelow",
"matchingColumns": [],
"attemptToConvertTypes": false,
"convertFieldsToString": true
}
},
"typeVersion": 1.2
},
{
"id": "93849a07-6c84-4abc-b5f3-0025e0625187",
"name": "编辑字段",
"type": "n8n-nodes-base.set",
"position": [
1200,
1600
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "7e0725fd-e9b4-4564-808a-708f6e8ecafa",
"name": "output",
"type": "array",
"value": "={{ $json.alerts }}"
}
]
},
"includeOtherFields": "={{ false }}"
},
"typeVersion": 3.4
},
{
"id": "4a49a959-6a27-410b-9a66-798480eb3612",
"name": "解析和拆分警报",
"type": "n8n-nodes-base.code",
"position": [
760,
1840
],
"parameters": {
"jsCode": "try {\n const alerts = $input.first().json.output;\n \n // Check if the result is a non-empty array.\n if (Array.isArray(alerts) && alerts.length > 0) {\n // Success! Return a separate item for each alert.\n // The .map() function transforms the array of alert objects\n // into an array of n8n items, which splits the execution.\n return alerts.map(alert => ({ json: alert }));\n }\n} catch (e) {\n // This will catch errors if the cleaned string is still not valid JSON.\n console.error(\"NixGuard did not return a valid JSON array even after cleaning:\", e);\n console.error(\"String that failed to parse:\", jsonString);\n}\n\n// If parsing fails, it's not an array, or it's empty, return no items.\n// This will correctly stop this branch of the workflow.\nreturn [];"
},
"typeVersion": 2
},
{
"id": "c6b28204-a3c7-4b4e-9c3d-d5bb8fb4195b",
"name": "聚合",
"type": "n8n-nodes-base.aggregate",
"position": [
1200,
1820
],
"parameters": {
"options": {},
"aggregate": "aggregateAllItemData",
"destinationFieldName": "output"
},
"typeVersion": 1
},
{
"id": "079081a2-6e54-44cc-aee9-a00a34f545ef",
"name": "筛选重要警报(级别 > 7)",
"type": "n8n-nodes-base.if",
"position": [
960,
1840
],
"parameters": {
"conditions": {
"number": [
{
"value1": "={{ $json.level }}",
"value2": 7,
"operation": "largerEqual"
}
]
}
},
"typeVersion": 1
},
{
"id": "77ac98bf-68a8-4f3a-9614-ea46096a173b",
"name": "发布关键警报到 Slack",
"type": "n8n-nodes-base.slack",
"disabled": true,
"position": [
1820,
1800
],
"webhookId": "b9db2ae0-4863-4809-82cd-0518807a21f6",
"parameters": {
"otherOptions": {}
},
"typeVersion": 2.3
},
{
"id": "af5aefb9-07e3-41a1-baa0-525ab53785b6",
"name": "发布高优先级警报到 Slack",
"type": "n8n-nodes-base.slack",
"disabled": true,
"position": [
1820,
2040
],
"webhookId": "b9db2ae0-4863-4809-82cd-0518807a21f6",
"parameters": {
"otherOptions": {}
},
"typeVersion": 2.3
},
{
"id": "5f26f03a-f715-4e0d-b99a-39df7ab2961d",
"name": "发布信息类警报到 Slack",
"type": "n8n-nodes-base.slack",
"disabled": true,
"position": [
1820,
2260
],
"webhookId": "b9db2ae0-4863-4809-82cd-0518807a21f6",
"parameters": {
"otherOptions": {}
},
"typeVersion": 2.3
},
{
"id": "f3eb57ec-4b5f-4bd8-ab2f-2e1cab76a16e",
"name": "解析 AI JSON 响应",
"type": "n8n-nodes-base.code",
"position": [
960,
2040
],
"parameters": {
"jsCode": "// Get the AI response. Your previous node used a complex path,\n// we assume the final AI string is here. Adjust if needed.\n// For example, it might be in $input.first().json.output or similar.\nconst rawOutput = $input.first().json.output;\n\nconst jsonString = rawOutput;\n\ntry {\n // Parse the cleaned JSON string\n const parsedResponse = JSON.parse(jsonString);\n // Add the parsed fields to the n8n item.\n // This merges the new data with any existing data from the input.\n return [{ \n json: {\n ...$input.first().json,\n ...parsedResponse \n }\n }];\n\n} catch (e) {\n console.error(\"Failed to parse AI JSON response:\", e);\n console.error(\"String that failed to parse:\", jsonString);\n // Return an empty item to indicate failure and stop the flow if desired.\n return [];\n}\n"
},
"typeVersion": 2
},
{
"id": "17359ba5-d1b1-42a6-bdfd-ab93be0fe857",
"name": "分支",
"type": "n8n-nodes-base.switch",
"position": [
1380,
2020
],
"parameters": {
"rules": {
"values": [
{
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"operator": {
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.ai_priority }}",
"rightValue": "Critical"
}
]
}
},
{
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "1be5b449-70dd-4bfe-91da-9ce25b523a74",
"operator": {
"name": "filter.operator.equals",
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.ai_priority }}",
"rightValue": "High"
}
]
}
},
{
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "1dd6239e-c965-4e06-85d9-4a8ad9f06287",
"operator": {
"name": "filter.operator.equals",
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.ai_priority }}",
"rightValue": "Info"
}
]
}
},
{
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "c019ac34-3196-49f1-8bdb-d399ff989103",
"operator": {
"name": "filter.operator.equals",
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.ai_priority }}",
"rightValue": "Low"
}
]
}
}
]
},
"options": {}
},
"typeVersion": 3.2
},
{
"id": "5190c963-d8b8-446d-ace5-403d93b91432",
"name": "设置指南 1",
"type": "n8n-nodes-base.stickyNote",
"position": [
1300,
880
],
"parameters": {
"color": 7,
"width": 400,
"height": 440,
"content": "## 入门指南"
},
"typeVersion": 1
}
],
"pinData": {},
"connections": {
"If": {
"main": [
[
{
"node": "Edit Fields",
"type": "main",
"index": 0
}
]
]
},
"Switch": {
"main": [
[
{
"node": "Post CRITICAL Alert to Slack",
"type": "main",
"index": 0
}
],
[
{
"node": "Post HIGH Alert to Slack",
"type": "main",
"index": 0
}
],
[
{
"node": "Post INFO Alert to Slack",
"type": "main",
"index": 0
}
],
[]
]
},
"Aggregate": {
"main": [
[
{
"node": "Set Prompt for Summary",
"type": "main",
"index": 0
}
]
]
},
"Edit Fields": {
"main": [
[
{
"node": "Parse & Split Alerts",
"type": "main",
"index": 0
}
]
]
},
"Parse Alert Array": {
"main": [
[
{
"node": "If",
"type": "main",
"index": 0
}
]
]
},
"Run Daily at 8 AM": {
"main": [
[
{
"node": "Set API Key & Initial Prompt",
"type": "main",
"index": 0
}
]
]
},
"Parse & Split Alerts": {
"main": [
[
{
"node": "Filter for Important Alerts (Level > 7)",
"type": "main",
"index": 0
}
]
]
},
"Parse AI JSON Response": {
"main": [
[
{
"node": "Extract AI Priority & Summary",
"type": "main",
"index": 0
}
]
]
},
"Set Prompt for Summary": {
"main": [
[
{
"node": "Execute: Generate Slack Message (Get Real-Time Security Insights with NixGuard RAG and Wazuh Integration)",
"type": "main",
"index": 0
}
]
]
},
"Set API Key & Initial Prompt": {
"main": [
[
{
"node": "Execute: Get Daily Events as JSON (Get Real-Time Security Insights with NixGuard RAG and Wazuh Integration)",
"type": "main",
"index": 0
}
]
]
},
"Extract AI Priority & Summary": {
"main": [
[
{
"node": "Switch",
"type": "main",
"index": 0
}
]
]
},
"Filter for Important Alerts (Level > 7)": {
"main": [
[
{
"node": "Aggregate",
"type": "main",
"index": 0
}
]
]
},
"Execute: Generate Slack Message (Get Real-Time Security Insights with NixGuard RAG and Wazuh Integration)": {
"main": [
[
{
"node": "Parse AI JSON Response",
"type": "main",
"index": 0
}
]
]
},
"Execute: Get Daily Events as JSON (Get Real-Time Security Insights with NixGuard RAG and Wazuh Integration)": {
"main": [
[
{
"node": "Parse Alert Array",
"type": "main",
"index": 0
}
]
]
}
}
}常见问题
如何使用这个工作流?
复制上方的 JSON 配置代码,在您的 n8n 实例中创建新工作流并选择「从 JSON 导入」,粘贴配置后根据需要修改凭证设置即可。
这个工作流适合什么场景?
高级 - 安全运维, AI 摘要总结
需要付费吗?
本工作流完全免费,您可以直接导入使用。但请注意,工作流中使用的第三方服务(如 OpenAI API)可能需要您自行付费。
相关工作流推荐
使用NixGuard AI和Wazuh警报创建高管安全简报
使用NixGuard AI和Wazuh警报创建高管安全简报
If
Set
Code
+4
13 节点Jonathan | NEX
安全运维
自动化免费IP分析
自动化免费IP分析:NixGuard AI摘要与Wazuh集成
Set
Slack
Webhook
+2
8 节点Jonathan | NEX
安全运维
URL钓鱼与威胁自动分析
使用NixGuard AI自动进行URL钓鱼和威胁分析
Set
Slack
Webhook
+2
8 节点Jonathan | NEX
安全运维
使用Gemini AI摘要的自动化WhatsApp群组每周团队报告
使用Gemini AI摘要的自动化WhatsApp群组每周团队报告
If
Set
Code
+13
47 节点Jamot
项目管理
灵活新闻聚合器 - 多源集成、AI分析和可设置频道
多源新闻策展系统,集成Mistral AI分析、摘要和自定义频道
If
Set
Xml
+32
120 节点Hybroht
内容创作
使用AI汇总Slack频道活动生成周报
使用AI汇总Slack频道活动生成周报
If
Set
Code
+13
47 节点Jimleuk
其他