{
  "name": "Uptime Kuma Alert Router",
  "nodes": [
    {
      "parameters": {
        "httpMethod": "POST",
        "path": "uptime-kuma",
        "responseMode": "onReceived",
        "options": {}
      },
      "id": "webhook-1",
      "name": "Webhook - Uptime Kuma",
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 1,
      "position": [250, 300],
      "webhookId": "uptime-kuma-alerts"
    },
    {
      "parameters": {
        "conditions": {
          "string": [
            {
              "value1": "={{ $json.body.monitor.name }}",
              "operation": "contains",
              "value2": "CRITICAL"
            }
          ]
        }
      },
      "id": "filter-critical",
      "name": "Is CRITICAL?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 1,
      "position": [450, 200]
    },
    {
      "parameters": {
        "conditions": {
          "string": [
            {
              "value1": "={{ $json.body.monitor.name }}",
              "operation": "contains",
              "value2": "PUBLIC"
            }
          ]
        }
      },
      "id": "filter-public",
      "name": "Is PUBLIC?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 1,
      "position": [450, 400]
    },
    {
      "parameters": {
        "functionCode": "// Parse Uptime Kuma webhook data\nconst data = $input.item.json.body;\nconst monitor = data.monitor;\nconst heartbeat = data.heartbeat;\n\n// Determine status emoji and color\nlet statusEmoji = '❓';\nlet statusText = 'UNKNOWN';\nlet color = '#808080';\n\nif (heartbeat.status === 1) {\n  statusEmoji = '✅';\n  statusText = 'UP';\n  color = '#00ff00';\n} else if (heartbeat.status === 0) {\n  statusEmoji = '❌';\n  statusText = 'DOWN';\n  color = '#ff0000';\n} else if (heartbeat.status === 2) {\n  statusEmoji = '⏸️';\n  statusText = 'PENDING';\n  color = '#ffaa00';\n}\n\n// Extract priority from monitor name\nconst priorityMatch = monitor.name.match(/\\[(CRITICAL|PUBLIC|INTERNAL|METRICS|UTILITY)\\]/);\nconst priority = priorityMatch ? priorityMatch[1] : 'UNKNOWN';\n\n// Build formatted message\nconst message = {\n  priority: priority,\n  monitorName: monitor.name.replace(/\\[(CRITICAL|PUBLIC|INTERNAL|METRICS|UTILITY)\\]\\s*/, ''),\n  fullName: monitor.name,\n  status: statusText,\n  statusEmoji: statusEmoji,\n  statusColor: color,\n  url: monitor.url || monitor.hostname || 'N/A',\n  errorMessage: heartbeat.msg || 'No error message',\n  timestamp: new Date(heartbeat.time).toLocaleString(),\n  \n  // Formatted messages for different channels\n  slackMessage: `${statusEmoji} *${monitor.name}* is ${statusText}\\n` +\n                `URL: ${monitor.url || monitor.hostname || 'N/A'}\\n` +\n                `Error: ${heartbeat.msg || 'None'}\\n` +\n                `Time: ${new Date(heartbeat.time).toLocaleString()}`,\n  \n  emailSubject: `[${priority}] ${monitor.name} is ${statusText}`,\n  \n  emailBody: `<h2>${statusEmoji} Monitor Alert: ${statusText}</h2>` +\n             `<p><strong>Monitor:</strong> ${monitor.name}</p>` +\n             `<p><strong>Status:</strong> ${statusText}</p>` +\n             `<p><strong>URL:</strong> ${monitor.url || monitor.hostname || 'N/A'}</p>` +\n             `<p><strong>Error:</strong> ${heartbeat.msg || 'None'}</p>` +\n             `<p><strong>Time:</strong> ${new Date(heartbeat.time).toLocaleString()}</p>` +\n             `<hr>` +\n             `<p><em>Uptime Kuma Dashboard: http://10.0.10.26:3001</em></p>`\n};\n\nreturn { json: message };"
      },
      "id": "format-data",
      "name": "Format Alert Data",
      "type": "n8n-nodes-base.function",
      "typeVersion": 1,
      "position": [650, 300]
    },
    {
      "parameters": {
        "resource": "message",
        "text": "={{ $json.slackMessage }}",
        "additionalFields": {
          "attachments": [
            {
              "color": "={{ $json.statusColor }}",
              "title": "{{ $json.fullName }}",
              "text": "{{ $json.errorMessage }}"
            }
          ]
        }
      },
      "id": "slack-critical",
      "name": "Slack - CRITICAL Alert",
      "type": "n8n-nodes-base.slack",
      "typeVersion": 1,
      "position": [850, 100],
      "disabled": true,
      "credentials": {
        "slackApi": {
          "id": "1",
          "name": "Slack API"
        }
      },
      "notes": "Enable and configure Slack credentials"
    },
    {
      "parameters": {
        "text": "={{ $json.slackMessage }}",
        "additionalFields": {}
      },
      "id": "discord-critical",
      "name": "Discord - CRITICAL Alert",
      "type": "n8n-nodes-base.discord",
      "typeVersion": 1,
      "position": [850, 200],
      "disabled": true,
      "notes": "Enable and configure Discord webhook"
    },
    {
      "parameters": {
        "fromEmail": "uptime@nianticbooks.com",
        "toEmail": "fred@youremail.com",
        "subject": "={{ $json.emailSubject }}",
        "emailFormat": "html",
        "text": "={{ $json.emailBody }}",
        "options": {}
      },
      "id": "email-critical",
      "name": "Email - CRITICAL Alert",
      "type": "n8n-nodes-base.emailSend",
      "typeVersion": 2,
      "position": [850, 300],
      "disabled": true,
      "notes": "Enable and configure SMTP settings"
    },
    {
      "parameters": {
        "text": "={{ $json.slackMessage }}",
        "additionalFields": {}
      },
      "id": "discord-public",
      "name": "Discord - PUBLIC Alert",
      "type": "n8n-nodes-base.discord",
      "typeVersion": 1,
      "position": [850, 400],
      "disabled": true,
      "notes": "Enable for public service alerts"
    },
    {
      "parameters": {
        "functionCode": "// Log the alert for debugging\nconsole.log('Uptime Kuma Alert:', JSON.stringify($input.item.json, null, 2));\n\n// Store in database or just log\nreturn $input.all();"
      },
      "id": "log-alert",
      "name": "Log Alert",
      "type": "n8n-nodes-base.function",
      "typeVersion": 1,
      "position": [850, 500],
      "notes": "Logs all alerts for debugging"
    }
  ],
  "connections": {
    "Webhook - Uptime Kuma": {
      "main": [
        [
          {
            "node": "Format Alert Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Format Alert Data": {
      "main": [
        [
          {
            "node": "Is CRITICAL?",
            "type": "main",
            "index": 0
          },
          {
            "node": "Is PUBLIC?",
            "type": "main",
            "index": 0
          },
          {
            "node": "Log Alert",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Is CRITICAL?": {
      "main": [
        [
          {
            "node": "Slack - CRITICAL Alert",
            "type": "main",
            "index": 0
          },
          {
            "node": "Discord - CRITICAL Alert",
            "type": "main",
            "index": 0
          },
          {
            "node": "Email - CRITICAL Alert",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Is PUBLIC?": {
      "main": [
        [
          {
            "node": "Discord - PUBLIC Alert",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "settings": {
    "executionOrder": "v1"
  },
  "staticData": null,
  "tags": [],
  "triggerCount": 0,
  "updatedAt": "2025-12-29T00:00:00.000Z",
  "versionId": "1"
}
