AutomationFlowsSlack & Telegram › Anomaly Detection Alerts via Slack & PagerDuty

Anomaly Detection Alerts via Slack & PagerDuty

Original n8n title: Anomaly Detection Alert System

Anomaly Detection Alert System. Uses postgres, openAi, slack, httpRequest. Scheduled trigger; 8 nodes.

Cron / scheduled trigger★★★★☆ complexityAI-powered8 nodesPostgresOpenAISlackHTTP Request
Slack & Telegram Trigger: Cron / scheduled Nodes: 8 Complexity: ★★★★☆ AI nodes: yes Added:

This workflow follows the HTTP Request → OpenAI recipe pattern — see all workflows that pair these two integrations.

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
{
  "name": "Anomaly Detection Alert System",
  "nodes": [
    {
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "minutes",
              "minutesInterval": 15
            }
          ]
        }
      },
      "id": "e5f6a7b8-5555-4000-8000-000000000001",
      "name": "Schedule - Every 15 Minutes",
      "type": "n8n-nodes-base.scheduleTrigger",
      "typeVersion": 1.2,
      "position": [
        240,
        300
      ]
    },
    {
      "parameters": {
        "operation": "executeQuery",
        "query": "SELECT metric_name, metric_value, recorded_at, service_name, ROUND(AVG(metric_value) OVER (PARTITION BY metric_name ORDER BY recorded_at ROWS BETWEEN 96 PRECEDING AND 1 PRECEDING), 2) as rolling_avg, ROUND(STDDEV(metric_value) OVER (PARTITION BY metric_name ORDER BY recorded_at ROWS BETWEEN 96 PRECEDING AND 1 PRECEDING), 2) as rolling_stddev FROM system_metrics WHERE recorded_at >= NOW() - INTERVAL '24 hours' ORDER BY recorded_at DESC LIMIT 50",
        "options": {}
      },
      "id": "e5f6a7b8-5555-4000-8000-000000000002",
      "name": "PostgreSQL - Get Metrics",
      "type": "n8n-nodes-base.postgres",
      "typeVersion": 2.5,
      "position": [
        480,
        300
      ],
      "credentials": {
        "postgres": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "jsCode": "const metrics = $input.all().map(item => item.json);\nconst metricsText = metrics.map(m => \n  `[${m.service_name}] ${m.metric_name}: current=${m.metric_value}, avg=${m.rolling_avg}, stddev=${m.rolling_stddev}, at=${m.recorded_at}`\n).join('\\n');\nreturn [{ json: { metricsText, metricCount: metrics.length, checkTime: new Date().toISOString() } }];"
      },
      "id": "e5f6a7b8-5555-4000-8000-000000000003",
      "name": "Code - Prepare Metrics",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        720,
        300
      ]
    },
    {
      "parameters": {
        "resource": "chat",
        "model": "gpt-4o",
        "messages": {
          "values": [
            {
              "content": "=You are a system monitoring expert specializing in anomaly detection. Analyze the following system metrics and identify any anomalies.\n\nFor each metric, consider:\n1. Values more than 2 standard deviations from the rolling average\n2. Sudden spikes or drops compared to recent trends\n3. Unusual patterns (e.g., metrics that should correlate but diverge)\n4. Service-specific thresholds (CPU > 85%, memory > 90%, error rate > 5%, latency > 2000ms)\n\nReturn JSON with:\n- anomalyDetected: boolean\n- anomalies: array of { service, metric, currentValue, expectedRange, severity (critical/warning/info), description }\n- summary: brief overall assessment\n- recommendedActions: array of strings\n\nMetrics Data:\n{{ $json.metricsText }}"
            }
          ]
        },
        "options": {
          "temperature": 0.2,
          "maxTokens": 2048,
          "responseFormat": "json_object"
        }
      },
      "id": "e5f6a7b8-5555-4000-8000-000000000004",
      "name": "OpenAI - Detect Anomalies",
      "type": "@n8n/n8n-nodes-langchain.openAi",
      "typeVersion": 1.4,
      "position": [
        960,
        300
      ],
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "jsCode": "const aiResponse = $input.first().json.message.content;\nlet analysis;\ntry {\n  analysis = JSON.parse(aiResponse);\n} catch (e) {\n  analysis = { anomalyDetected: false, anomalies: [], summary: 'Parse error', recommendedActions: [] };\n}\nconst checkTime = $('Code - Prepare Metrics').first().json.checkTime;\nreturn [{ json: { ...analysis, checkTime } }];"
      },
      "id": "e5f6a7b8-5555-4000-8000-000000000005",
      "name": "Code - Parse Analysis",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1200,
        300
      ]
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict"
          },
          "conditions": [
            {
              "id": "condition-1",
              "leftValue": "={{ $json.anomalyDetected }}",
              "rightValue": true,
              "operator": {
                "type": "boolean",
                "operation": "equals"
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "id": "e5f6a7b8-5555-4000-8000-000000000006",
      "name": "IF - Anomaly Found",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        1440,
        300
      ]
    },
    {
      "parameters": {
        "channel": "#alerts-production",
        "text": "=:rotating_light: *ANOMALY DETECTED* :rotating_light:\n\n*Time:* {{ $('Code - Parse Analysis').first().json.checkTime }}\n*Summary:* {{ $('Code - Parse Analysis').first().json.summary }}\n\n*Anomalies:*\n{{ $('Code - Parse Analysis').first().json.anomalies.map(a => `\u2022 [${a.severity.toUpperCase()}] ${a.service} - ${a.metric}: ${a.currentValue} (expected: ${a.expectedRange})\\n  _${a.description}_`).join('\\n') }}\n\n*Recommended Actions:*\n{{ $('Code - Parse Analysis').first().json.recommendedActions.map((a, i) => `${i+1}. ${a}`).join('\\n') }}",
        "otherOptions": {}
      },
      "id": "e5f6a7b8-5555-4000-8000-000000000007",
      "name": "Slack - Alert Channel",
      "type": "n8n-nodes-base.slack",
      "typeVersion": 2.2,
      "position": [
        1680,
        200
      ],
      "credentials": {
        "slackOAuth2Api": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "url": "https://events.pagerduty.com/v2/enqueue",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        },
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={\n  \"routing_key\": \"YOUR_PAGERDUTY_INTEGRATION_KEY\",\n  \"event_action\": \"trigger\",\n  \"payload\": {\n    \"summary\": \"Anomaly Detected: {{ $('Code - Parse Analysis').first().json.summary }}\",\n    \"severity\": \"{{ $('Code - Parse Analysis').first().json.anomalies[0] ? $('Code - Parse Analysis').first().json.anomalies[0].severity : 'warning' }}\",\n    \"source\": \"n8n-anomaly-detection\",\n    \"component\": \"{{ $('Code - Parse Analysis').first().json.anomalies[0] ? $('Code - Parse Analysis').first().json.anomalies[0].service : 'unknown' }}\",\n    \"timestamp\": \"{{ $('Code - Parse Analysis').first().json.checkTime }}\"\n  }\n}",
        "options": {}
      },
      "id": "e5f6a7b8-5555-4000-8000-000000000008",
      "name": "PagerDuty - Trigger Incident",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        1680,
        400
      ]
    }
  ],
  "connections": {
    "Schedule - Every 15 Minutes": {
      "main": [
        [
          {
            "node": "PostgreSQL - Get Metrics",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "PostgreSQL - Get Metrics": {
      "main": [
        [
          {
            "node": "Code - Prepare Metrics",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Code - Prepare Metrics": {
      "main": [
        [
          {
            "node": "OpenAI - Detect Anomalies",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI - Detect Anomalies": {
      "main": [
        [
          {
            "node": "Code - Parse Analysis",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Code - Parse Analysis": {
      "main": [
        [
          {
            "node": "IF - Anomaly Found",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "IF - Anomaly Found": {
      "main": [
        [
          {
            "node": "Slack - Alert Channel",
            "type": "main",
            "index": 0
          },
          {
            "node": "PagerDuty - Trigger Incident",
            "type": "main",
            "index": 0
          }
        ],
        []
      ]
    }
  },
  "settings": {
    "executionOrder": "v1"
  },
  "staticData": null,
  "tags": [
    {
      "name": "ai-data"
    }
  ]
}

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

Anomaly Detection Alert System. Uses postgres, openAi, slack, httpRequest. Scheduled trigger; 8 nodes.

Source: https://github.com/mlnjsh/n8n-workflows-mega/blob/main/workflows/ai-data/05-anomaly-detection-alert.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

This n8n workflow proactively scans and aggregates threat intelligence, network logs, and vulnerability data every 15 minutes to detect emerging risks across the infrastructure. It analyzes anomalies,

HTTP Request, Slack, Email Send +1
Slack & Telegram

WF-4: Price Alert Monitor. Uses httpRequest, slack, postgres. Scheduled trigger; 6 nodes.

HTTP Request, Slack, Postgres
Slack & Telegram

This workflow is designed for space enthusiasts, science educators, journalists, fact-checkers, and researchers who want to stay informed about near-Earth asteroid threats while filtering out media se

Nasa, @Apify/N8N Nodes Apify, OpenAI +4
Slack & Telegram

This workflow is designed for engineering teams, project managers, and IT operations who need consistent visibility into team availability across multiple projects. It’s perfect for organizations that

HTTP Request, Execute Workflow Trigger, Slack
Slack & Telegram

This workflow is an automated system that tracks End-of-Life (EOL) dates for software and technologies used across your projects. It eliminates the need to manually monitor EOL dates in spreadsheets o

HTTP Request, Noco Db, Slack