{
  "name": "Appointment Scheduling Error Handler - Gotify",
  "nodes": [
    {
      "id": "80234583-52c6-42ee-a15d-f93be67a8f28",
      "name": "Workflow Failure Error Trigger",
      "type": "n8n-nodes-base.errorTrigger",
      "position": [
        -520,
        0
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "cadf7e4c-a924-441c-9785-61d6865cb659",
      "name": "Build Gotify Failure Notification",
      "type": "n8n-nodes-base.code",
      "position": [
        -260,
        0
      ],
      "parameters": {
        "jsCode": "const env = (typeof $env !== 'undefined') ? $env : ((typeof process !== 'undefined' && process.env) ? process.env : {});\n\nconst clientConfig = {\n  gotifyBaseUrl: (env.GOTIFY_BASE_URL || 'http://localhost:PORT').replace(/\\/$/, ''),\n  gotifyAppToken: env.GOTIFY_APP_TOKEN || '',\n  priority: Number(env.GOTIFY_PRIORITY || 8),\n  n8nPublicUrl: env.N8N_PUBLIC_URL || '',\n};\n\n// This Code node formats n8n Error Trigger payloads into Gotify's REST message shape.\nif (!clientConfig.gotifyAppToken) {\n  throw new Error('GOTIFY_APP_TOKEN is required for Gotify error notifications');\n}\n\nreturn $input.all().map((item, index) => {\n  const error = item.json.error || {};\n  const workflow = item.json.workflow || {};\n  const execution = item.json.execution || {};\n\n  const message = [\n    'Workflow: ' + (workflow.name || workflow.id || 'unknown'),\n    'Execution: ' + (execution.id || 'unknown'),\n    'Node: ' + (error.node?.name || error.nodeName || 'unknown'),\n    'Error: ' + (error.message || 'unknown error'),\n    clientConfig.n8nPublicUrl && execution.id ? 'Open: ' + clientConfig.n8nPublicUrl.replace(/\\/$/, '') + '/execution/' + execution.id : '',\n  ].filter(Boolean).join('\\n');\n\n  return {\n    json: {\n      gotifyUrl: clientConfig.gotifyBaseUrl,\n      gotifyToken: clientConfig.gotifyAppToken,\n      gotifyPayload: {\n        title: 'n8n workflow failed: ' + (workflow.name || 'unknown workflow'),\n        message,\n        priority: clientConfig.priority,\n      },\n    },\n    pairedItem: { item: index },\n  };\n});"
      },
      "typeVersion": 2
    },
    {
      "id": "7b2e7f34-d0ce-4d23-a6a9-4d8a638ba707",
      "name": "POST Failure to Gotify",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        0,
        0
      ],
      "parameters": {
        "method": "POST",
        "url": "={{ $json.gotifyUrl + \"/message\" }}",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Content-Type",
              "value": "application/json"
            },
            {
              "name": "X-Gotify-Key",
              "value": "={{ $json.gotifyToken }}"
            }
          ]
        },
        "sendBody": true,
        "contentType": "json",
        "specifyBody": "json",
        "jsonBody": "={{ JSON.stringify($json.gotifyPayload) }}",
        "options": {}
      },
      "typeVersion": 4.2
    }
  ],
  "connections": {
    "Workflow Failure Error Trigger": {
      "main": [
        [
          {
            "node": "Build Gotify Failure Notification",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Build Gotify Failure Notification": {
      "main": [
        [
          {
            "node": "POST Failure to Gotify",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "settings": {
    "executionOrder": "v1",
    "timezone": "Europe/Tirane"
  }
}
