AutomationFlowsSlack & Telegram › Wazuh Alert Triage & Routing to Discord

Wazuh Alert Triage & Routing to Discord

Original n8n title: Wazuh Soar — Alert Triage & Routing

Wazuh SOAR — Alert Triage & Routing. Uses discord. Webhook trigger; 16 nodes.

Webhook trigger★★★★☆ complexity16 nodesDiscord
Slack & Telegram Trigger: Webhook Nodes: 16 Complexity: ★★★★☆ Added:

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 →

Download .json
{
  "updatedAt": "2026-03-10T02:01:45.000Z",
  "createdAt": "2026-03-08T01:43:05.603Z",
  "id": "YOUR_WORKFLOW_ID",
  "name": "Wazuh SOAR \u2014 Alert Triage & Routing",
  "description": null,
  "active": true,
  "isArchived": false,
  "nodes": [
    {
      "parameters": {
        "httpMethod": "POST",
        "path": "wazuh-alerts",
        "options": {}
      },
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 2.1,
      "position": [
        -208,
        304
      ],
      "id": "webhook-wazuh",
      "name": "Wazuh Webhook"
    },
    {
      "parameters": {
        "jsCode": "const WINDOW_MS = 90 * 1000;\nconst state = $getWorkflowStaticData('global');\nif (!state.recent) state.recent = {};\nconst now = Date.now();\n\nconst out = [];\nfor (const item of items) {\n  const body = item.json?.body || {};\n  const ruleId = String(body?.rule?.id || 'unknown');\n  const src = String(body?.srcip || body?.data?.srcip || 'unknown');\n  const key = `${ruleId}|${src}`;\n  const last = Number(state.recent[key] || 0);\n\n  if (now - last >= WINDOW_MS) {\n    state.recent[key] = now;\n    out.push(item);\n  }\n}\n\nfor (const k of Object.keys(state.recent)) {\n  if (now - Number(state.recent[k]) > (6 * WINDOW_MS)) delete state.recent[k];\n}\n\nreturn out;"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -16,
        320
      ],
      "id": "dedup-burst-window",
      "name": "Dedup Burst Window"
    },
    {
      "parameters": {
        "rules": {
          "values": [
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict"
                },
                "conditions": [
                  {
                    "id": "crit",
                    "leftValue": "={{ $json.body.rule.level }}",
                    "rightValue": 12,
                    "operator": {
                      "type": "number",
                      "operation": "gte"
                    }
                  }
                ],
                "combinator": "and"
              },
              "renameOutput": true,
              "outputKey": "Critical (12+)"
            },
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict"
                },
                "conditions": [
                  {
                    "id": "high",
                    "leftValue": "={{ $json.body.rule.level }}",
                    "rightValue": 10,
                    "operator": {
                      "type": "number",
                      "operation": "gte"
                    }
                  }
                ],
                "combinator": "and"
              },
              "renameOutput": true,
              "outputKey": "High (10-11)"
            },
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict"
                },
                "conditions": [
                  {
                    "id": "med",
                    "leftValue": "={{ $json.body.rule.level }}",
                    "rightValue": 7,
                    "operator": {
                      "type": "number",
                      "operation": "gte"
                    }
                  }
                ],
                "combinator": "and"
              },
              "renameOutput": true,
              "outputKey": "Medium (7-9)"
            }
          ]
        },
        "options": {
          "fallbackOutput": "extra"
        }
      },
      "type": "n8n-nodes-base.switch",
      "typeVersion": 3.2,
      "position": [
        288,
        304
      ],
      "id": "switch-severity",
      "name": "Severity Router"
    },
    {
      "parameters": {
        "authentication": "webhook",
        "operation": "sendLegacy",
        "content": "",
        "embeds": {
          "values": [
            {
              "title": "=\ud83d\udea8 CRITICAL \u2014 Wazuh Rule {{ $json.body.rule.id }} (Level {{ $json.body.rule.level }})",
              "description": "={{ $json.body.rule.description }}",
              "color": 15158332,
              "timestamp": "={{ new Date().toISOString() }}",
              "fields": [
                {
                  "name": "\u26a0\ufe0f Severity Level",
                  "value": "=Level **{{ $json.body.rule.level }}** \u2014 CRITICAL",
                  "inline": true
                },
                {
                  "name": "\ud83d\udcdc Rule ID",
                  "value": "=`{{ $json.body.rule.id }}`",
                  "inline": true
                },
                {
                  "name": "\ud83d\udda5\ufe0f Agent",
                  "value": "={{ $json.body.agent?.name || 'N/A' }} (`{{ $json.body.agent?.ip || 'N/A' }}`)",
                  "inline": true
                },
                {
                  "name": "\ud83c\udfaf MITRE ATT&CK",
                  "value": "=Tactic: {{ ($json.body.rule.mitre?.tactic || []).join(', ') || 'N/A' }}\nTechnique: {{ ($json.body.rule.mitre?.technique || []).join(', ') || 'N/A' }}\nID: {{ ($json.body.rule.mitre?.id || []).join(', ') || 'N/A' }}",
                  "inline": false
                },
                {
                  "name": "\ud83c\udf10 Source IP",
                  "value": "={{ $json.body.srcip || $json.body.data?.srcip || 'N/A' }}",
                  "inline": true
                },
                {
                  "name": "\ud83d\udc64 User",
                  "value": "={{ $json.body.data?.srcuser || $json.body.data?.dstuser || 'N/A' }}",
                  "inline": true
                },
                {
                  "name": "\ud83d\udce6 Groups",
                  "value": "={{ ($json.body.rule.groups || []).join(', ') || 'N/A' }}",
                  "inline": false
                },
                {
                  "name": "\ud83d\udcc1 File / Path",
                  "value": "=`{{ $json.body.syscheck?.path || 'N/A' }}`",
                  "inline": true
                },
                {
                  "name": "\ud83d\udccd Location",
                  "value": "=`{{ $json.body.location || 'N/A' }}`",
                  "inline": true
                },
                {
                  "name": "\ud83d\udccb Raw Log",
                  "value": "=```{{ ($json.body.full_log || 'N/A').slice(0, 600) }}```",
                  "inline": false
                }
              ]
            }
          ]
        }
      },
      "type": "n8n-nodes-base.discord",
      "typeVersion": 2,
      "position": [
        592,
        112
      ],
      "id": "discord-critical",
      "name": "Discord \u2014 Critical",
      "credentials": {
        "discordWebhookApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "authentication": "webhook",
        "operation": "sendLegacy",
        "content": "",
        "embeds": {
          "values": [
            {
              "title": "=\ud83d\udfe0 HIGH \u2014 Wazuh Rule {{ $json.body.rule.id }} (Level {{ $json.body.rule.level }})",
              "description": "={{ $json.body.rule.description }}",
              "color": 15105570,
              "timestamp": "={{ new Date().toISOString() }}",
              "fields": [
                {
                  "name": "\u26a0\ufe0f Severity Level",
                  "value": "=Level **{{ $json.body.rule.level }}**",
                  "inline": true
                },
                {
                  "name": "\ud83d\udcdc Rule ID",
                  "value": "=`{{ $json.body.rule.id }}`",
                  "inline": true
                },
                {
                  "name": "\ud83d\udda5\ufe0f Agent",
                  "value": "={{ $json.body.agent?.name || 'N/A' }} (`{{ $json.body.agent?.ip || 'N/A' }}`)",
                  "inline": true
                },
                {
                  "name": "\ud83c\udfaf MITRE ATT&CK",
                  "value": "=Tactic: {{ ($json.body.rule.mitre?.tactic || []).join(', ') || 'N/A' }}\nTechnique: {{ ($json.body.rule.mitre?.technique || []).join(', ') || 'N/A' }}",
                  "inline": false
                },
                {
                  "name": "\ud83c\udf10 Source IP",
                  "value": "={{ $json.body.srcip || $json.body.data?.srcip || 'N/A' }}",
                  "inline": true
                },
                {
                  "name": "\ud83d\udc64 User",
                  "value": "={{ $json.body.data?.srcuser || $json.body.data?.dstuser || 'N/A' }}",
                  "inline": true
                },
                {
                  "name": "\ud83d\udce6 Groups",
                  "value": "={{ ($json.body.rule.groups || []).join(', ') || 'N/A' }}",
                  "inline": false
                },
                {
                  "name": "\ud83d\udccd Location",
                  "value": "=`{{ $json.body.location || 'N/A' }}`",
                  "inline": true
                },
                {
                  "name": "\ud83d\udccb Raw Log",
                  "value": "=```{{ ($json.body.full_log || 'N/A').slice(0, 500) }}```",
                  "inline": false
                }
              ]
            }
          ]
        }
      },
      "type": "n8n-nodes-base.discord",
      "typeVersion": 2,
      "position": [
        864,
        400
      ],
      "id": "discord-high",
      "name": "Discord \u2014 High",
      "credentials": {
        "discordWebhookApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "ts",
              "name": "timestamp",
              "value": "={{ $json.body.timestamp }}",
              "type": "string"
            },
            {
              "id": "rid",
              "name": "rule_id",
              "value": "={{ $json.body.rule.id }}",
              "type": "string"
            },
            {
              "id": "lvl",
              "name": "level",
              "value": "={{ $json.body.rule.level }}",
              "type": "number"
            },
            {
              "id": "desc",
              "name": "description",
              "value": "={{ $json.body.rule.description }}",
              "type": "string"
            },
            {
              "id": "agent",
              "name": "agent",
              "value": "={{ $json.body.agent.name }}",
              "type": "string"
            },
            {
              "id": "src",
              "name": "srcip",
              "value": "={{ $json.body.srcip || '' }}",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        592,
        512
      ],
      "id": "set-medium",
      "name": "Log Medium"
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "ts",
              "name": "timestamp",
              "value": "={{ $json.body.timestamp }}",
              "type": "string"
            },
            {
              "id": "rid",
              "name": "rule_id",
              "value": "={{ $json.body.rule.id }}",
              "type": "string"
            },
            {
              "id": "lvl",
              "name": "level",
              "value": "={{ $json.body.rule.level }}",
              "type": "number"
            },
            {
              "id": "desc",
              "name": "description",
              "value": "={{ $json.body.rule.description }}",
              "type": "string"
            },
            {
              "id": "agent",
              "name": "agent",
              "value": "={{ $json.body.agent.name }}",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        592,
        704
      ],
      "id": "set-low",
      "name": "Log Low"
    },
    {
      "parameters": {
        "rules": {
          "values": [
            {
              "conditions": {
                "options": {
                  "caseSensitive": false,
                  "leftValue": "",
                  "typeValidation": "loose"
                },
                "conditions": [
                  {
                    "id": "brute",
                    "leftValue": "={{ ($json.body.rule.groups || []).join(',') }}",
                    "rightValue": "authentication_fail",
                    "operator": {
                      "type": "string",
                      "operation": "contains"
                    }
                  }
                ],
                "combinator": "or"
              },
              "renameOutput": true,
              "outputKey": "Brute Force"
            },
            {
              "conditions": {
                "options": {
                  "caseSensitive": false,
                  "leftValue": "",
                  "typeValidation": "loose"
                },
                "conditions": [
                  {
                    "id": "fim",
                    "leftValue": "={{ ($json.body.rule.groups || []).join(',') }}",
                    "rightValue": "syscheck",
                    "operator": {
                      "type": "string",
                      "operation": "contains"
                    }
                  }
                ],
                "combinator": "or"
              },
              "renameOutput": true,
              "outputKey": "File Integrity"
            },
            {
              "conditions": {
                "options": {
                  "caseSensitive": false,
                  "leftValue": "",
                  "typeValidation": "loose"
                },
                "conditions": [
                  {
                    "id": "vuln",
                    "leftValue": "={{ ($json.body.rule.groups || []).join(',') }}",
                    "rightValue": "vulnerability-detector",
                    "operator": {
                      "type": "string",
                      "operation": "contains"
                    }
                  }
                ],
                "combinator": "or"
              },
              "renameOutput": true,
              "outputKey": "Vulnerability"
            }
          ]
        },
        "options": {
          "fallbackOutput": "extra"
        }
      },
      "type": "n8n-nodes-base.switch",
      "typeVersion": 3.2,
      "position": [
        864,
        112
      ],
      "id": "switch-category",
      "name": "Attack Categorizer"
    },
    {
      "parameters": {
        "authentication": "webhook",
        "operation": "sendLegacy",
        "content": "",
        "embeds": {
          "values": [
            {
              "title": "=\ud83d\udd10 Brute Force Detected \u2014 {{ $json.body.agent?.name || 'unknown' }}",
              "description": "={{ $json.body.rule.description }}",
              "color": 15548997,
              "timestamp": "={{ new Date().toISOString() }}",
              "fields": [
                {
                  "name": "\u26a0\ufe0f Severity",
                  "value": "=Level **{{ $json.body.rule.level }}** \u2014 {{ $json.body.rule.level >= 12 ? 'CRITICAL' : 'HIGH' }}",
                  "inline": true
                },
                {
                  "name": "\ud83d\udcdc Rule ID",
                  "value": "=`{{ $json.body.rule.id }}`",
                  "inline": true
                },
                {
                  "name": "\ud83d\udda5\ufe0f Target Host",
                  "value": "={{ $json.body.agent?.name || 'N/A' }} (`{{ $json.body.agent?.ip || 'N/A' }}`)",
                  "inline": true
                },
                {
                  "name": "\ud83c\udf10 Attacker IP",
                  "value": "=`{{ $json.body.srcip || $json.body.data?.srcip || 'N/A' }}`",
                  "inline": true
                },
                {
                  "name": "\ud83d\udc64 Target User",
                  "value": "={{ $json.body.data?.srcuser || $json.body.data?.dstuser || 'N/A' }}",
                  "inline": true
                },
                {
                  "name": "\ud83c\udfaf MITRE ATT&CK",
                  "value": "=Tactic: {{ ($json.body.rule.mitre?.tactic || []).join(', ') || 'Credential Access' }}\nTechnique: {{ ($json.body.rule.mitre?.technique || []).join(', ') || 'Brute Force' }}\nID: {{ ($json.body.rule.mitre?.id || []).join(', ') || 'T1110' }}",
                  "inline": false
                },
                {
                  "name": "\ud83d\udce6 Groups",
                  "value": "={{ ($json.body.rule.groups || []).join(', ') || 'N/A' }}",
                  "inline": false
                },
                {
                  "name": "\ud83d\udccd Log Source",
                  "value": "=`{{ $json.body.location || 'N/A' }}`",
                  "inline": true
                },
                {
                  "name": "\ud83d\udee1\ufe0f Recommended Action",
                  "value": "=\u2022 Check auth logs for repeat attempts\n\u2022 Consider blocking source IP at firewall\n\u2022 Review account lockout policies\n\u2022 Check for successful logins from this IP",
                  "inline": false
                },
                {
                  "name": "\ud83d\udccb Raw Log",
                  "value": "=```{{ ($json.body.full_log || 'N/A').slice(0, 400) }}```",
                  "inline": false
                }
              ]
            }
          ]
        }
      },
      "type": "n8n-nodes-base.discord",
      "typeVersion": 2,
      "position": [
        1152,
        0
      ],
      "id": "discord-brute",
      "name": "Discord \u2014 Brute Force",
      "credentials": {
        "discordWebhookApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "jsCode": "const WINDOW_MS = 3 * 60 * 1000;\nconst state = $getWorkflowStaticData('global');\nif (!state.auth_recent_critical) state.auth_recent_critical = {};\nconst now = Date.now();\n\nconst out = [];\nfor (const item of items) {\n  const body = item.json?.body || {};\n  const src = String(body?.srcip || body?.data?.srcip || 'unknown');\n  const user = String(body?.data?.srcuser || body?.data?.dstuser || 'unknown');\n  const ruleId = String(body?.rule?.id || 'unknown');\n  const key = `${src}|${user}|${ruleId}`;\n  const last = Number(state.auth_recent_critical[key] || 0);\n\n  if (now - last >= WINDOW_MS) {\n    state.auth_recent_critical[key] = now;\n    out.push(item);\n  }\n}\n\nfor (const k of Object.keys(state.auth_recent_critical)) {\n  if (now - Number(state.auth_recent_critical[k]) > (6 * WINDOW_MS)) delete state.auth_recent_critical[k];\n}\n\nreturn out;"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1024,
        0
      ],
      "id": "dedup-auth-critical",
      "name": "Dedup Auth Critical"
    },
    {
      "parameters": {
        "authentication": "webhook",
        "operation": "sendLegacy",
        "content": "",
        "embeds": {
          "values": [
            {
              "title": "=\ud83d\udcc1 File Integrity Change \u2014 {{ $json.body.agent?.name || 'unknown' }}",
              "description": "={{ $json.body.rule.description }}",
              "color": 3447003,
              "timestamp": "={{ new Date().toISOString() }}",
              "fields": [
                {
                  "name": "\u26a0\ufe0f Severity",
                  "value": "=Level **{{ $json.body.rule.level }}**",
                  "inline": true
                },
                {
                  "name": "\ud83d\udcdc Rule ID",
                  "value": "=`{{ $json.body.rule.id }}`",
                  "inline": true
                },
                {
                  "name": "\ud83d\udda5\ufe0f Agent",
                  "value": "={{ $json.body.agent?.name || 'N/A' }} (`{{ $json.body.agent?.ip || 'N/A' }}`)",
                  "inline": true
                },
                {
                  "name": "\ud83d\udcc2 File Path",
                  "value": "=`{{ $json.body.syscheck?.path || 'N/A' }}`",
                  "inline": false
                },
                {
                  "name": "\ud83d\udd04 Event Type",
                  "value": "={{ $json.body.syscheck?.event || 'N/A' }}",
                  "inline": true
                },
                {
                  "name": "\ud83d\udc64 Owner (After)",
                  "value": "={{ $json.body.syscheck?.uname_after || 'N/A' }}:{{ $json.body.syscheck?.gname_after || 'N/A' }}",
                  "inline": true
                },
                {
                  "name": "\ud83d\udd12 Permissions (After)",
                  "value": "=`{{ $json.body.syscheck?.perm_after || 'N/A' }}`",
                  "inline": true
                },
                {
                  "name": "\ud83d\udd11 SHA256 Hash",
                  "value": "=`{{ ($json.body.syscheck?.sha256_after || 'N/A').slice(0, 20) }}...`",
                  "inline": true
                },
                {
                  "name": "\ud83d\udccf Size Change",
                  "value": "={{ $json.body.syscheck?.size_before || '?' }} \u2192 {{ $json.body.syscheck?.size_after || '?' }} bytes",
                  "inline": true
                },
                {
                  "name": "\ud83d\udce6 Groups",
                  "value": "={{ ($json.body.rule.groups || []).join(', ') || 'N/A' }}",
                  "inline": false
                },
                {
                  "name": "\ud83d\udccd Location",
                  "value": "=`{{ $json.body.location || 'N/A' }}`",
                  "inline": true
                },
                {
                  "name": "\ud83d\udccb Raw Log",
                  "value": "=```{{ ($json.body.full_log || 'N/A').slice(0, 400) }}```",
                  "inline": false
                }
              ]
            }
          ]
        }
      },
      "type": "n8n-nodes-base.discord",
      "typeVersion": 2,
      "position": [
        1152,
        208
      ],
      "id": "discord-fim",
      "name": "Discord \u2014 FIM Alert",
      "credentials": {
        "discordWebhookApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "authentication": "webhook",
        "operation": "sendLegacy",
        "content": "",
        "embeds": {
          "values": [
            {
              "title": "=\ud83d\udee1\ufe0f Vulnerability Found \u2014 {{ $json.body.agent?.name || 'unknown' }}",
              "description": "={{ $json.body.rule.description }}",
              "color": 10038562,
              "timestamp": "={{ new Date().toISOString() }}",
              "fields": [
                {
                  "name": "\u26a0\ufe0f Severity",
                  "value": "=Level **{{ $json.body.rule.level }}**",
                  "inline": true
                },
                {
                  "name": "\ud83d\udcdc Rule ID",
                  "value": "=`{{ $json.body.rule.id }}`",
                  "inline": true
                },
                {
                  "name": "\ud83d\udda5\ufe0f Agent",
                  "value": "={{ $json.body.agent?.name || 'N/A' }} (`{{ $json.body.agent?.ip || 'N/A' }}`)",
                  "inline": true
                },
                {
                  "name": "\ud83d\udc1b CVE",
                  "value": "={{ $json.body.data?.vulnerability?.cve || $json.body.data?.cve || 'N/A' }}",
                  "inline": true
                },
                {
                  "name": "\ud83d\udce6 Package",
                  "value": "={{ $json.body.data?.vulnerability?.package?.name || 'N/A' }} {{ $json.body.data?.vulnerability?.package?.version || '' }}",
                  "inline": true
                },
                {
                  "name": "\ud83d\udd34 CVSS Score",
                  "value": "={{ $json.body.data?.vulnerability?.severity || $json.body.data?.vulnerability?.cvss?.score || 'N/A' }}",
                  "inline": true
                },
                {
                  "name": "\ud83d\udc8a Fix Available",
                  "value": "={{ $json.body.data?.vulnerability?.package?.fix_version || $json.body.data?.vulnerability?.status || 'Check vendor advisory' }}",
                  "inline": true
                },
                {
                  "name": "\ud83c\udfaf MITRE ATT&CK",
                  "value": "=Tactic: {{ ($json.body.rule.mitre?.tactic || []).join(', ') || 'N/A' }}\nTechnique: {{ ($json.body.rule.mitre?.technique || []).join(', ') || 'N/A' }}",
                  "inline": false
                },
                {
                  "name": "\ud83d\udce6 Groups",
                  "value": "={{ ($json.body.rule.groups || []).join(', ') || 'N/A' }}",
                  "inline": false
                },
                {
                  "name": "\ud83d\udd17 Reference",
                  "value": "={{ ($json.body.data?.vulnerability?.references || []).slice(0, 2).join('\\n') || $json.body.data?.vulnerability?.reference || 'N/A' }}",
                  "inline": false
                },
                {
                  "name": "\ud83d\udccb Raw Log",
                  "value": "=```{{ ($json.body.full_log || 'N/A').slice(0, 400) }}```",
                  "inline": false
                }
              ]
            }
          ]
        }
      },
      "type": "n8n-nodes-base.discord",
      "typeVersion": 2,
      "position": [
        1152,
        400
      ],
      "id": "discord-vuln",
      "name": "Discord \u2014 Vulnerability",
      "credentials": {
        "discordWebhookApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "rules": {
          "values": [
            {
              "conditions": {
                "options": {
                  "caseSensitive": false,
                  "leftValue": "",
                  "typeValidation": "loose"
                },
                "conditions": [
                  {
                    "id": "pf-internal-group",
                    "leftValue": "={{ ($json.body.rule.groups || []).join(',') }}",
                    "rightValue": "pfsense",
                    "operator": {
                      "type": "string",
                      "operation": "contains"
                    }
                  },
                  {
                    "id": "pf-internal-ip",
                    "leftValue": "={{ (() => { const ip = $json.body.srcip || $json.body.data?.srcip || ''; return (ip.startsWith('192.168.') || ip.startsWith('10.') || ip.startsWith('172.')) ? 'private' : 'public'; })() }}",
                    "rightValue": "private",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    }
                  }
                ],
                "combinator": "and"
              },
              "renameOutput": true,
              "outputKey": "pfSense Internal (log)"
            },
            {
              "conditions": {
                "options": {
                  "caseSensitive": false,
                  "leftValue": "",
                  "typeValidation": "loose"
                },
                "conditions": [
                  {
                    "id": "pf-external",
                    "leftValue": "={{ ($json.body.rule.groups || []).join(',') }}",
                    "rightValue": "pfsense",
                    "operator": {
                      "type": "string",
                      "operation": "contains"
                    }
                  },
                  {
                    "id": "pf-not-192",
                    "leftValue": "={{ $json.body.srcip || $json.body.data?.srcip || '' }}",
                    "rightValue": "192.168.",
                    "operator": {
                      "type": "string",
                      "operation": "notContains"
                    }
                  },
                  {
                    "id": "pf-not-10",
                    "leftValue": "={{ $json.body.srcip || $json.body.data?.srcip || '' }}",
                    "rightValue": "10.",
                    "operator": {
                      "type": "string",
                      "operation": "notContains"
                    }
                  },
                  {
                    "id": "pf-not-172",
                    "leftValue": "={{ $json.body.srcip || $json.body.data?.srcip || '' }}",
                    "rightValue": "172.",
                    "operator": {
                      "type": "string",
                      "operation": "notContains"
                    }
                  }
                ],
                "combinator": "and"
              },
              "renameOutput": true,
              "outputKey": "pfSense External (discord)"
            },
            {
              "conditions": {
                "options": {
                  "caseSensitive": false,
                  "leftValue": "",
                  "typeValidation": "loose"
                },
                "conditions": [
                  {
                    "id": "fim",
                    "leftValue": "={{ ($json.body.rule.groups || []).join(',') }}",
                    "rightValue": "syscheck",
                    "operator": {
                      "type": "string",
                      "operation": "contains"
                    }
                  }
                ],
                "combinator": "or"
              },
              "renameOutput": true,
              "outputKey": "File Integrity"
            },
            {
              "conditions": {
                "options": {
                  "caseSensitive": false,
                  "leftValue": "",
                  "typeValidation": "loose"
                },
                "conditions": [
                  {
                    "id": "auth",
                    "leftValue": "={{ ($json.body.rule.groups || []).join(',') }}",
                    "rightValue": "authentication_fail",
                    "operator": {
                      "type": "string",
                      "operation": "contains"
                    }
                  }
                ],
                "combinator": "or"
              },
              "renameOutput": true,
              "outputKey": "Auth Failure"
            }
          ]
        },
        "options": {
          "fallbackOutput": "extra"
        }
      },
      "type": "n8n-nodes-base.switch",
      "typeVersion": 3.2,
      "position": [
        592,
        304
      ],
      "id": "switch-high-type",
      "name": "High Alert Router"
    },
    {
      "parameters": {
        "authentication": "webhook",
        "operation": "sendLegacy",
        "content": "",
        "embeds": {
          "values": [
            {
              "title": "=\ud83d\udd25 pfSense \u2014 {{ $json.body.data?.action || 'block' }} from {{ $json.body.srcip || $json.body.data?.srcip || 'unknown' }}",
              "description": "={{ $json.body.rule.description }}",
              "color": 15844367,
              "timestamp": "={{ new Date().toISOString() }}",
              "fields": [
                {
                  "name": "\u26a0\ufe0f Severity",
                  "value": "=Level **{{ $json.body.rule.level }}**",
                  "inline": true
                },
                {
                  "name": "\ud83d\udcdc Rule ID",
                  "value": "=`{{ $json.body.rule.id }}`",
                  "inline": true
                },
                {
                  "name": "\ud83c\udf10 Source IP",
                  "value": "=`{{ $json.body.srcip || $json.body.data?.srcip || 'N/A' }}`",
                  "inline": true
                },
                {
                  "name": "\ud83c\udfaf Dest IP",
                  "value": "=`{{ $json.body.data?.dstip || 'N/A' }}`",
                  "inline": true
                },
                {
                  "name": "\ud83d\udd0c Dest Port",
                  "value": "={{ $json.body.data?.dstport || 'N/A' }}",
                  "inline": true
                },
                {
                  "name": "\ud83d\udce1 Protocol",
                  "value": "={{ $json.body.data?.protocol || 'N/A' }}",
                  "inline": true
                },
                {
                  "name": "\ud83d\udeab Action",
                  "value": "=**{{ $json.body.data?.action || 'block' }}**",
                  "inline": true
                },
                {
                  "name": "\ud83d\udda5\ufe0f Agent",
                  "value": "={{ $json.body.agent?.name || 'N/A' }}",
                  "inline": true
                },
                {
                  "name": "\ud83d\udce6 Groups",
                  "value": "={{ ($json.body.rule.groups || []).join(', ') || 'N/A' }}",
                  "inline": false
                },
                {
                  "name": "\ud83c\udff7\ufe0f Classification",
                  "value": "=Recon/scan or policy block",
                  "inline": false
                },
                {
                  "name": "\ud83d\udccb Raw Log",
                  "value": "=```{{ ($json.body.full_log || 'N/A').slice(0, 500) }}```",
                  "inline": false
                }
              ]
            }
          ]
        }
      },
      "type": "n8n-nodes-base.discord",
      "typeVersion": 2,
      "position": [
        864,
        208
      ],
      "id": "discord-pfsense",
      "name": "Discord \u2014 pfSense",
      "credentials": {
        "discordWebhookApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "authentication": "webhook",
        "operation": "sendLegacy",
        "content": "",
        "embeds": {
          "values": [
            {
              "title": "=\ud83d\udd11 Auth Failure \u2014 {{ $json.body.agent?.name || 'unknown' }}",
              "description": "={{ $json.body.rule.description }}",
              "color": 16776960,
              "timestamp": "={{ new Date().toISOString() }}",
              "fields": [
                {
                  "name": "\u26a0\ufe0f Severity",
                  "value": "=Level **{{ $json.body.rule.level }}**",
                  "inline": true
                },
                {
                  "name": "\ud83d\udcdc Rule ID",
                  "value": "=`{{ $json.body.rule.id }}`",
                  "inline": true
                },
                {
                  "name": "\ud83d\udda5\ufe0f Target Host",
                  "value": "={{ $json.body.agent?.name || 'N/A' }} (`{{ $json.body.agent?.ip || 'N/A' }}`)",
                  "inline": true
                },
                {
                  "name": "\ud83c\udf10 Source IP",
                  "value": "=`{{ $json.body.srcip || $json.body.data?.srcip || 'N/A' }}`",
                  "inline": true
                },
                {
                  "name": "\ud83d\udc64 Username",
                  "value": "={{ $json.body.data?.srcuser || $json.body.data?.dstuser || 'N/A' }}",
                  "inline": true
                },
                {
                  "name": "\ud83c\udfaf MITRE ATT&CK",
                  "value": "=Tactic: {{ ($json.body.rule.mitre?.tactic || []).join(', ') || 'N/A' }}\nTechnique: {{ ($json.body.rule.mitre?.technique || []).join(', ') || 'N/A' }}",
                  "inline": false
                },
                {
                  "name": "\ud83d\udce6 Groups",
                  "value": "={{ ($json.body.rule.groups || []).join(', ') || 'N/A' }}",
                  "inline": false
                },
                {
                  "name": "\ud83d\udccd Log Source",
                  "value": "=`{{ $json.body.location || 'N/A' }}`",
                  "inline": true
                },
                {
                  "name": "\ud83d\udccb Raw Log",
                  "value": "=```{{ ($json.body.full_log || 'N/A').slice(0, 500) }}```",
                  "inline": false
                }
              ]
            }
          ]
        }
      },
      "type": "n8n-nodes-base.discord",
      "typeVersion": 2,
      "position": [
        1120,
        592
      ],
      "id": "discord-auth-high",
      "name": "Discord \u2014 Auth Failure",
      "credentials": {
        "discordWebhookApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "jsCode": "const WINDOW_MS = 2 * 60 * 1000;\nconst state = $getWorkflowStaticData('global');\nif (!state.auth_recent_high) state.auth_recent_high = {};\nconst now = Date.now();\n\nconst out = [];\nfor (const item of items) {\n  const body = item.json?.body || {};\n  const src = String(body?.srcip || body?.data?.srcip || 'unknown');\n  const user = String(body?.data?.srcuser || body?.data?.dstuser || 'unknown');\n  const ruleId = String(body?.rule?.id || 'unknown');\n  const key = `${src}|${user}|${ruleId}`;\n  const last = Number(state.auth_recent_high[key] || 0);\n\n  if (now - last >= WINDOW_MS) {\n    state.auth_recent_high[key] = now;\n    out.push(item);\n  }\n}\n\nfor (const k of Object.keys(state.auth_recent_high)) {\n  if (now - Number(state.auth_recent_high[k]) > (6 * WINDOW_MS)) delete state.auth_recent_high[k];\n}\n\nreturn out;"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        752,
        512
      ],
      "id": "dedup-auth-high",
      "name": "Dedup Auth High"
    }
  ],
  "connections": {
    "Wazuh Webhook": {
      "main": [
        [
          {
            "node": "Dedup Burst Window",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Dedup Burst Window": {
      "main": [
        [
          {
            "node": "Severity Router",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Severity Router": {
      "main": [
        [
          {
            "node": "Discord \u2014 Critical",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "High Alert Router",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Log Medium",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Log Low",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Discord \u2014 Critical": {
      "main": [
        [
          {
            "node": "Attack Categorizer",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Attack Categorizer": {
      "main": [
        [
          {
            "node": "Dedup Auth Critical",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Discord \u2014 FIM Alert",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Discord \u2014 Vulnerability",
            "type": "main",
            "index": 0
          }
        ],
        []
      ]
    },
    "High Alert Router": {
      "main": [
        [
          {
            "node": "Log Medium",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Discord \u2014 pfSense",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Discord \u2014 FIM Alert",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Dedup Auth High",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Discord \u2014 High",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Dedup Auth Critical": {
      "main": [
        [
          {
            "node": "Discord \u2014 Brute Force",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Dedup Auth High": {
      "main": [
        [
          {
            "node": "Discord \u2014 Auth Failure",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Log Low": {
      "main": [
        []
      ]
    }
  },
  "settings": {
    "executionOrder": "v1",
    "binaryMode": "separate",
    "availableInMCP": false,
    "callerPolicy": "workflowsFromSameOwner"
  },
  "staticData": null,
  "meta": null,
  "activeVersionId": "59e7d5d7-214b-437b-b014-09d5b185e2f1",
  "versionCounter": 43,
  "triggerCount": 1,
  "tags": [],
  "shared": [
    {
      "updatedAt": "2026-03-08T01:43:05.612Z",
      "createdAt": "2026-03-08T01:43:05.612Z",
      "role": "workflow:owner",
      "workflowId": "69ZRy9pXLiPIf5d7",
      "projectId": "kafEMdKKgLswaGCu",
      "project": {
        "updatedAt": "2026-03-05T23:55:16.170Z",
        "createdAt": "2026-03-05T23:48:50.092Z",
        "id": "kafEMdKKgLswaGCu",
        "name": "Moshe Geek <chief@chiefgyk3d.com>",
        "type": "personal",
        "icon": null,
        "description": null,
        "creatorId": "850a1525-0d7b-4ff8-ae56-76e699c15b7c"
      }
    }
  ],
  "versionMetadata": {
    "name": null,
    "description": null
  }
}

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.

Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

Wazuh SOAR — Alert Triage & Routing. Uses discord. Webhook trigger; 16 nodes.

Source: https://github.com/ChiefGyk3D/siem-docker-stack/blob/cccbc66855fbf8bd26b6cc974b1cec6c282cfdd9/n8n/wazuh-alert-triage.json — original creator credit. Request a take-down →

More Slack & Telegram workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

Slack & Telegram

MVP — ClickUp Webhook → Discord Alert. Uses discord. Webhook trigger; 12 nodes.

Discord
Slack & Telegram

Automatically convert GitHub issues into analyzed Jira tickets with AI-powered severity detection, developer assignment, and instant team alerts.

OpenAI, Jira, GitHub +2
Slack & Telegram

This workflow is a production-ready Meta Ads Webhook dispatcher for the Ad Account object. It receives webhook deliveries from Meta, returns the required acknowledgement, routes events by , logs them

Google Sheets, Slack
Slack & Telegram

This n8n workflow template is designed to provide real-time alerts on new cryptocurrency exchange listings and delistings. It caters especially to crypto traders, investors, and enthusiasts who want t

Supabase, HTTP Request, Telegram +2
Slack & Telegram

🛡️ Jamf Policy Integrity Monitor

Crypto, Data Table, HTTP Request +2