{
  "name": "CSAT Alert — Zendesk Bad Ratings → Slack",
  "nodes": [
    {
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "minutes",
              "minutesInterval": 5
            }
          ]
        }
      },
      "id": "schedule-trigger",
      "name": "Every 5 Minutes",
      "type": "n8n-nodes-base.scheduleTrigger",
      "typeVersion": 1.2,
      "position": [0, 0]
    },
    {
      "parameters": {
        "method": "GET",
        "url": "https://YOUR_SUBDOMAIN.zendesk.com/api/v2/satisfaction_ratings?score=bad&sort_order=desc&per_page=10",
        "authentication": "predefinedCredentialType",
        "nodeCredentialType": "zendeskApi",
        "options": {}
      },
      "id": "fetch-ratings",
      "name": "Fetch Bad Ratings",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [220, 0],
      "credentials": {
        "zendeskApi": {
          "id": "credential-id",
          "name": "Zendesk API"
        }
      }
    },
    {
      "parameters": {
        "mode": "runOnceForAllItems",
        "jsCode": "const ratings = $input.first().json.satisfaction_ratings || [];\nconst fiveMinAgo = new Date(Date.now() - 5 * 60 * 1000).toISOString();\n\nconst newBadRatings = ratings.filter(r => r.updated_at > fiveMinAgo);\n\nif (newBadRatings.length === 0) {\n  return [];\n}\n\nreturn newBadRatings.map(r => ({\n  json: {\n    ratingId: r.id,\n    ticketId: r.ticket_id,\n    comment: r.comment || '(no comment)',\n    createdAt: r.updated_at,\n  }\n}));"
      },
      "id": "filter-new",
      "name": "Filter New Ratings",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [440, 0]
    },
    {
      "parameters": {
        "method": "GET",
        "url": "=https://YOUR_SUBDOMAIN.zendesk.com/api/v2/tickets/{{ $json.ticketId }}.json",
        "authentication": "predefinedCredentialType",
        "nodeCredentialType": "zendeskApi",
        "options": {}
      },
      "id": "fetch-ticket",
      "name": "Fetch Ticket Details",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [660, 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\": \"CSAT_CHANNEL_ID\",\n  \"blocks\": [\n    {\n      \"type\": \"header\",\n      \"text\": {\n        \"type\": \"plain_text\",\n        \"text\": \"Bad CSAT Rating Received\",\n        \"emoji\": true\n      }\n    },\n    {\n      \"type\": \"section\",\n      \"fields\": [\n        {\"type\": \"mrkdwn\", \"text\": \"*Ticket:* #\" + $('Filter New Ratings').item.json.ticketId},\n        {\"type\": \"mrkdwn\", \"text\": \"*Subject:* \" + ($json.ticket?.subject || 'Unknown')},\n        {\"type\": \"mrkdwn\", \"text\": \"*Customer:* \" + ($json.ticket?.requester?.name || 'Unknown')},\n        {\"type\": \"mrkdwn\", \"text\": \"*Assignee:* \" + ($json.ticket?.assignee_id || 'Unassigned')}\n      ]\n    },\n    {\n      \"type\": \"section\",\n      \"text\": {\n        \"type\": \"mrkdwn\",\n        \"text\": \"*Customer comment:* \" + $('Filter New Ratings').item.json.comment\n      }\n    },\n    {\n      \"type\": \"actions\",\n      \"elements\": [\n        {\n          \"type\": \"button\",\n          \"text\": {\"type\": \"plain_text\", \"text\": \"View in Zendesk\"},\n          \"url\": \"https://YOUR_SUBDOMAIN.zendesk.com/agent/tickets/\" + $('Filter New Ratings').item.json.ticketId\n        }\n      ]\n    }\n  ]\n}",
        "options": {}
      },
      "id": "post-slack",
      "name": "Post Slack Alert",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [880, 0],
      "credentials": {
        "httpHeaderAuth": {
          "id": "credential-id",
          "name": "Slack Bot Token"
        }
      }
    }
  ],
  "connections": {
    "Every 5 Minutes": {
      "main": [
        [
          {
            "node": "Fetch Bad Ratings",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Bad Ratings": {
      "main": [
        [
          {
            "node": "Filter New Ratings",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Filter New Ratings": {
      "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-csat-alert"
  }
}
