{
  "name": "SLA Breach Warning — Zendesk → Slack",
  "nodes": [
    {
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "minutes",
              "minutesInterval": 15
            }
          ]
        }
      },
      "id": "schedule-trigger",
      "name": "Every 15 Minutes",
      "type": "n8n-nodes-base.scheduleTrigger",
      "typeVersion": 1.2,
      "position": [0, 0]
    },
    {
      "parameters": {
        "method": "GET",
        "url": "https://YOUR_SUBDOMAIN.zendesk.com/api/v2/search.json?query=type:ticket status:open status:pending status:new&per_page=100",
        "authentication": "predefinedCredentialType",
        "nodeCredentialType": "zendeskApi",
        "options": {}
      },
      "id": "fetch-tickets",
      "name": "Fetch Open Tickets",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [220, 0],
      "credentials": {
        "zendeskApi": {
          "id": "credential-id",
          "name": "Zendesk API"
        }
      }
    },
    {
      "parameters": {
        "batchSize": 1,
        "options": {}
      },
      "id": "split-batches",
      "name": "Loop Tickets",
      "type": "n8n-nodes-base.splitInBatches",
      "typeVersion": 3,
      "position": [440, 0]
    },
    {
      "parameters": {
        "method": "GET",
        "url": "=https://YOUR_SUBDOMAIN.zendesk.com/api/v2/tickets/{{ $json.id }}/metrics.json",
        "authentication": "predefinedCredentialType",
        "nodeCredentialType": "zendeskApi",
        "options": {}
      },
      "id": "fetch-metrics",
      "name": "Fetch Ticket Metrics",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [660, 0],
      "credentials": {
        "zendeskApi": {
          "id": "credential-id",
          "name": "Zendesk API"
        }
      }
    },
    {
      "parameters": {
        "mode": "runOnceForAllItems",
        "jsCode": "const metrics = $input.all();\nconst warnings = [];\nconst WARN_MINUTES = 60;\n\nfor (const item of metrics) {\n  const m = item.json.ticket_metric;\n  if (!m) continue;\n\n  const ticketId = m.ticket_id;\n\n  const replyBreach = m.reply_time_in_minutes?.business;\n  if (replyBreach && !replyBreach.is_completed) {\n    const target = replyBreach.target;\n    const elapsed = replyBreach.elapsed;\n    const remaining = target - elapsed;\n    if (remaining > 0 && remaining <= WARN_MINUTES) {\n      warnings.push({\n        ticketId,\n        metric: 'First Reply Time',\n        remainingMinutes: remaining,\n        target,\n      });\n    }\n  }\n\n  const resolutionBreach = m.full_resolution_time_in_minutes?.business;\n  if (resolutionBreach && !resolutionBreach.is_completed) {\n    const target = resolutionBreach.target;\n    const elapsed = resolutionBreach.elapsed;\n    const remaining = target - elapsed;\n    if (remaining > 0 && remaining <= WARN_MINUTES) {\n      warnings.push({\n        ticketId,\n        metric: 'Resolution Time',\n        remainingMinutes: remaining,\n        target,\n      });\n    }\n  }\n}\n\nif (warnings.length === 0) return [];\nreturn warnings.map(w => ({ json: w }));"
      },
      "id": "check-sla",
      "name": "Check SLA Breach",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [880, 0]
    },
    {
      "parameters": {
        "method": "GET",
        "url": "=https://YOUR_SUBDOMAIN.zendesk.com/api/v2/tickets/{{ $json.ticketId }}.json",
        "authentication": "predefinedCredentialType",
        "nodeCredentialType": "zendeskApi",
        "options": {}
      },
      "id": "fetch-ticket-details",
      "name": "Fetch Ticket Details",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [1100, 0],
      "credentials": {
        "zendeskApi": {
          "id": "credential-id",
          "name": "Zendesk API"
        }
      }
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://slack.com/api/chat.postMessage",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={\n  \"channel\": \"SLA_CHANNEL_ID\",\n  \"blocks\": [\n    {\n      \"type\": \"header\",\n      \"text\": {\n        \"type\": \"plain_text\",\n        \"text\": \"SLA Breach Warning\"\n      }\n    },\n    {\n      \"type\": \"section\",\n      \"fields\": [\n        {\"type\": \"mrkdwn\", \"text\": \"*Ticket:* #\" + $('Check SLA Breach').item.json.ticketId},\n        {\"type\": \"mrkdwn\", \"text\": \"*Subject:* \" + ($json.ticket?.subject || 'Unknown')},\n        {\"type\": \"mrkdwn\", \"text\": \"*SLA Metric:* \" + $('Check SLA Breach').item.json.metric},\n        {\"type\": \"mrkdwn\", \"text\": \"*Time Remaining:* \" + $('Check SLA Breach').item.json.remainingMinutes + \" min\"}\n      ]\n    },\n    {\n      \"type\": \"section\",\n      \"fields\": [\n        {\"type\": \"mrkdwn\", \"text\": \"*Assignee:* \" + ($json.ticket?.assignee_id || 'Unassigned')},\n        {\"type\": \"mrkdwn\", \"text\": \"*Priority:* \" + ($json.ticket?.priority || 'normal')}\n      ]\n    },\n    {\n      \"type\": \"actions\",\n      \"elements\": [\n        {\n          \"type\": \"button\",\n          \"text\": {\"type\": \"plain_text\", \"text\": \"View Ticket\"},\n          \"url\": \"https://YOUR_SUBDOMAIN.zendesk.com/agent/tickets/\" + $('Check SLA Breach').item.json.ticketId,\n          \"style\": \"danger\"\n        }\n      ]\n    }\n  ]\n}",
        "options": {}
      },
      "id": "post-slack",
      "name": "Post Slack Alert",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [1320, 0],
      "credentials": {
        "httpHeaderAuth": {
          "id": "credential-id",
          "name": "Slack Bot Token"
        }
      }
    }
  ],
  "connections": {
    "Every 15 Minutes": {
      "main": [
        [
          {
            "node": "Fetch Open Tickets",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Open Tickets": {
      "main": [
        [
          {
            "node": "Loop Tickets",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Loop Tickets": {
      "main": [
        [
          {
            "node": "Check SLA Breach",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Fetch Ticket Metrics",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Ticket Metrics": {
      "main": [
        [
          {
            "node": "Loop Tickets",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check SLA Breach": {
      "main": [
        [
          {
            "node": "Fetch Ticket Details",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Ticket Details": {
      "main": [
        [
          {
            "node": "Post Slack Alert",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "pinData": {},
  "settings": {
    "executionOrder": "v1"
  },
  "staticData": null,
  "tags": [],
  "triggerCount": 0,
  "active": false,
  "meta": {
    "instanceId": "",
    "templateId": "revi-zendesk-sla-breach"
  }
}
