{
  "name": "Intel Brief \u2014 Workflow C \u2014 Error Handler",
  "nodes": [
    {
      "parameters": {},
      "id": "node-error-trigger",
      "name": "Error Trigger",
      "type": "n8n-nodes-base.errorTrigger",
      "typeVersion": 1,
      "position": [
        240,
        300
      ],
      "notes": "Fires whenever any workflow that has 'Intel Brief \u2014 Workflow C \u2014 Error Handler' set as its Error Workflow encounters an unhandled error."
    },
    {
      "parameters": {
        "jsCode": "// Format error details for Telegram MarkdownV2\nconst MDV2 = /[_*[\\]()~`>#+\\-=|{}.!\\\\]/g;\nconst esc = s => String(s || '').replace(MDV2, '\\\\$&');\n\nconst data = $input.first().json;\nconst exec = data.execution || {};\nconst wf = data.workflow || {};\nconst err = exec.error || {};\n\nconst whenISO = new Date().toISOString();\nconst when = whenISO.slice(0, 19).replace('T', ' ') + ' UTC';\n\nconst workflowName = wf.name || 'unknown';\nconst lastNode = exec.lastNodeExecuted || 'unknown';\nconst execId = exec.id || 'unknown';\nconst execUrl = exec.url || '';\nconst errMsg = err.message || JSON.stringify(err).slice(0, 400);\nconst errType = err.name || '';\n\nlet msg = '*INTEL BRIEF BOT \u2014 ALERT*\\n\\n';\nmsg += `*Workflow:* ${esc(workflowName)}\\n`;\nmsg += `*Failed node:* ${esc(lastNode)}\\n`;\nmsg += `*Time:* ${esc(when)}\\n`;\nmsg += `*Execution:* ${esc(execId)}\\n\\n`;\nmsg += `*Error:* ${esc(errType)}\\n`;\nmsg += '```\\n' + esc(errMsg).slice(0, 600) + '\\n```';\nif (execUrl) {\n  msg += `\\n\\n[Open execution in n8n](${execUrl})`;\n}\n\nreturn [{ json: { alertMessage: msg } }];"
      },
      "id": "node-format-alert",
      "name": "Format Alert Message",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        460,
        300
      ]
    },
    {
      "parameters": {
        "chatId": "={{ $env.ALLOWED_USER_ID }}",
        "text": "={{ $json.alertMessage }}",
        "additionalFields": {
          "parse_mode": "MarkdownV2",
          "disable_web_page_preview": true
        }
      },
      "id": "node-tg-alert",
      "name": "Send Alert to Telegram",
      "type": "n8n-nodes-base.telegram",
      "typeVersion": 1.2,
      "position": [
        680,
        300
      ],
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "jsCode": "// Log error to disk for post-mortem (path-allowlist guarded)\nconst fs = require('fs');\nconst path = require('path');\nconst ALLOWED_DIR = '/data/briefs/errors';\n\nconst data = $input.first().json;\nconst exec = data.execution || {};\nconst wf = data.workflow || {};\nconst err = exec.error || {};\n\nconst stamp = new Date().toISOString().replace(/[:.]/g, '-');\nconst safeName = (wf.name || 'unknown').replace(/[^a-z0-9]/gi, '_').slice(0, 40);\nconst file = path.resolve(path.join(ALLOWED_DIR, `${stamp}_${safeName}.json`));\n\nif (!file.startsWith(ALLOWED_DIR + '/')) {\n  throw new Error('Path-allowlist violation: ' + file);\n}\n\nfs.mkdirSync(ALLOWED_DIR, { recursive: true });\nfs.writeFileSync(file, JSON.stringify({\n  at: new Date().toISOString(),\n  workflowName: wf.name,\n  workflowId: wf.id,\n  executionId: exec.id,\n  lastNode: exec.lastNodeExecuted,\n  error: err\n}, null, 2), 'utf8');\n\nreturn [{ json: { logged: file } }];"
      },
      "id": "node-log-error",
      "name": "Log Error to Disk",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        680,
        480
      ],
      "notes": "Writes error to /data/briefs/errors/. Helpful for post-mortem after the alert."
    }
  ],
  "connections": {
    "Error Trigger": {
      "main": [
        [
          {
            "node": "Format Alert Message",
            "type": "main",
            "index": 0
          },
          {
            "node": "Log Error to Disk",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Format Alert Message": {
      "main": [
        [
          {
            "node": "Send Alert to Telegram",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "settings": {
    "executionOrder": "v1",
    "saveExecutionProgress": true,
    "saveDataErrorExecution": "all",
    "saveDataSuccessExecution": "all",
    "timezone": "Asia/Kolkata"
  },
  "tags": [
    {
      "name": "intel-brief"
    },
    {
      "name": "phase-3"
    }
  ]
}