Alert your support lead in Slack when Gorgias tickets approach SLA deadline using a Claude Code skill

low complexityCost: Usage-based

Prerequisites

Compatible agents

This skill works with any agent that supports the Claude Code skills standard, including Claude Code, Claude Cowork, OpenAI Codex, and Google Antigravity.

Prerequisites
  • One of the agents listed above
  • Gorgias account with API access
  • Slack bot with chat:write permission added to the target channel
  • Your SLA targets documented (first-response time per channel)
Environment Variables
# Your Gorgias subdomain (e.g. yourstore)
GORGIAS_DOMAIN=your_value_here
# Gorgias account email for API authentication
GORGIAS_EMAIL=your_value_here
# Gorgias API key from Settings > REST API
GORGIAS_API_KEY=your_value_here
# Slack bot token with chat:write permission
SLACK_BOT_TOKEN=your_value_here
# Target Slack channel ID for SLA warning alerts
SLACK_CHANNEL_ID=your_value_here

Why a Claude Code skill?

The other approaches in this guide are deterministic: they run the same logic every time, the same way. An Claude Code skill is different. You tell Claude what you want in plain language, and the skill gives it enough context to do it reliably.

That means you can say:

  • "Check for tickets approaching SLA and alert Slack"
  • "Which tickets are closest to breaching right now?"
  • "Post a summary of all SLA-at-risk tickets instead of individual alerts"
  • "Check SLA for chat tickets only — skip email"

The skill contains workflow guidelines, API reference materials, and a Slack message template that the agent reads on demand. When you invoke the skill, Claude reads these files, writes a script on the fly, runs it, and reports results. If you ask for something different next time — tighter thresholds, different channels, a batch summary — the agent adapts without you touching any code.

How it works

The skill directory has three parts:

  1. SKILL.md — workflow guidelines telling the agent what steps to follow, which env vars to use, and what pitfalls to avoid
  2. references/ — Gorgias API patterns (ticket listing, SLA calculation logic) so the agent calls the right APIs
  3. templates/ — a Slack Block Kit template for SLA warning alerts

When invoked, the agent reads SKILL.md, consults the reference and template files as needed, writes a Python script, executes it, and reports what it posted. The reference files include the SLA calculation logic so the agent correctly determines time remaining.

What is a Claude Code skill?

An Claude Code skill is a reusable command you add to your project that Claude Code can run on demand. Skills live in a .claude/skills/ directory and are defined by a SKILL.md file that tells the agent what the skill does, when to run it, and what tools it's allowed to use.

In this skill, the agent doesn't run a pre-written script. Instead, SKILL.md provides workflow guidelines and points to reference files — API documentation, message templates — that the agent reads to generate and execute code itself.

Once installed, you can invoke a skill as a slash command (e.g., /sla-alert), or the agent will use it automatically when you give it a task where the skill is relevant.

Step 1: Create the skill directory

mkdir -p .claude/skills/sla-alert/{templates,references}

This creates the layout:

.claude/skills/sla-alert/
├── SKILL.md                          # workflow guidelines + config
├── templates/
│   └── slack-alert.md                # Block Kit template for SLA warnings
└── references/
    └── gorgias-tickets-api.md        # Gorgias API + SLA calculation

Step 2: Write the SKILL.md

Create .claude/skills/sla-alert/SKILL.md:

---
name: sla-alert
description: Check open Gorgias tickets for approaching SLA deadlines and post warnings to Slack so the team lead can reassign or escalate before a breach occurs.
disable-model-invocation: true
allowed-tools: Bash, Read
---
 
## Goal
 
Poll open Gorgias tickets that haven't received a first agent response, calculate how much SLA time remains for each, and post a Slack alert for any ticket approaching its deadline (default: 75% of SLA window elapsed).
 
## Configuration
 
Read these environment variables:
 
- `GORGIAS_DOMAIN` — your Gorgias subdomain (required)
- `GORGIAS_EMAIL` — Gorgias account email for API auth (required)
- `GORGIAS_API_KEY` — Gorgias API key (required)
- `SLACK_BOT_TOKEN` — Slack bot token with chat:write (required)
- `SLACK_CHANNEL_ID` — Slack channel ID starting with C (required)
 
Default SLA targets (in minutes): email=240, chat=15, contact-form=240. Default warn threshold: 75% elapsed. The user may request different values.
 
## Workflow
 
1. Validate that all required env vars are set. If any are missing, print which ones and exit.
2. Fetch open tickets from Gorgias. See `references/gorgias-tickets-api.md` for the endpoint and SLA calculation logic.
3. Filter to tickets with no agent reply (no message with `source.type == "helpdesk"` or `sender.type == "agent"`).
4. For each unanswered ticket, calculate elapsed time since creation, look up the SLA target for the ticket's channel, and determine if the warn threshold has been crossed.
5. Track already-alerted ticket IDs in a local JSON file to avoid duplicate warnings.
6. Post a Slack alert for at-risk tickets using the template in `templates/slack-alert.md`.
7. Print a summary of alerts sent.
 
## Important notes
 
- This calculates SLA using wall-clock time, not business hours. If your SLA counts only business hours, mention this to the user and suggest they define business hours in the SLA targets.
- `SLACK_CHANNEL_ID` must be the channel ID (starts with `C`), not the channel name. The `chat.postMessage` API requires the ID.
- The Slack bot must be invited to the target channel or posting will fail with `not_in_channel`.
- Clean up the alerted tickets file periodically (remove entries older than 24 hours) to prevent unbounded growth.
- Use the `requests` library for Gorgias and `slack_sdk` for Slack. Install with pip if needed.

Step 3: Add reference files

templates/slack-alert.md

Create .claude/skills/sla-alert/templates/slack-alert.md:

# SLA Warning Slack Template
 
Use this Block Kit structure for each SLA warning alert.
 
## Block Kit JSON
 
```json
{
  "channel": "<SLACK_CHANNEL_ID>",
  "text": "SLA warning: <ticket_subject> — <status>",
  "blocks": [
    {
      "type": "header",
      "text": {
        "type": "plain_text",
        "text": "SLA Warning — Ticket Approaching Deadline"
      }
    },
    {
      "type": "section",
      "fields": [
        { "type": "mrkdwn", "text": "*Customer*\n<customer_name>" },
        { "type": "mrkdwn", "text": "*Channel*\n<channel>" },
        { "type": "mrkdwn", "text": "*Time Remaining*\n<remaining_or_breached>" },
        { "type": "mrkdwn", "text": "*SLA Target*\n<sla_minutes> min" },
        { "type": "mrkdwn", "text": "*Subject*\n<subject>" }
      ]
    },
    {
      "type": "actions",
      "elements": [
        {
          "type": "button",
          "text": { "type": "plain_text", "text": "Open in Gorgias" },
          "url": "https://<GORGIAS_DOMAIN>.gorgias.com/app/ticket/<ticket_id>",
          "style": "danger"
        }
      ]
    }
  ]
}
```
 
## Notes
 
- Use `danger` style on the button for visual urgency.
- For `<remaining_or_breached>`: show "BREACHED" if time remaining <= 0, otherwise show "X min remaining".
- Send via `slack_sdk` `chat.postMessage` with the `SLACK_BOT_TOKEN`.

references/gorgias-tickets-api.md

Create .claude/skills/sla-alert/references/gorgias-tickets-api.md:

# Gorgias Tickets API + SLA Calculation
 
## Authentication
 
All requests use HTTP Basic Auth:
- Username: `GORGIAS_EMAIL`
- Password: `GORGIAS_API_KEY`
- Base URL: `https://{GORGIAS_DOMAIN}.gorgias.com/api`
 
## List open tickets
 
**Request:**
 
```
GET /api/tickets?status=open&limit=100
```
 
**Response shape:**
 
```json
{
  "data": [
    {
      "id": 18201,
      "subject": "Shipping delay on order #4892",
      "status": "open",
      "channel": "email",
      "created_datetime": "2026-03-05T10:00:00+00:00",
      "requester": {
        "id": 678,
        "name": "Emily Tran",
        "email": "emily@example.com"
      },
      "messages": [
        {
          "id": 99001,
          "body_text": "Customer message here...",
          "source": { "type": "email" },
          "sender": { "type": "customer" }
        }
      ]
    }
  ]
}
```
 
## Determining if a ticket has an agent reply
 
Check each message in the `messages` array:
- `source.type == "helpdesk"` indicates an agent or system message
- `sender.type == "agent"` also indicates an agent message
- If any message matches either condition, the ticket has been replied to
 
## SLA Calculation Logic
 
Default SLA targets (in minutes):
 
| Channel | SLA (minutes) |
|---------|--------------|
| email | 240 (4 hours) |
| chat | 15 |
| contact-form | 240 |
| default | 240 |
 
**Steps:**
1. Parse `created_datetime` as UTC
2. Calculate elapsed minutes: `(now_utc - created_datetime) / 60`
3. Look up SLA target for the ticket's `channel`
4. Calculate remaining: `sla_target - elapsed`
5. Calculate percent elapsed: `elapsed / sla_target`
6. If percent elapsed >= 0.75 (warn threshold), the ticket is at risk
7. If remaining <= 0, the ticket has breached
 
**Note:** This uses wall-clock time. If your SLA only counts business hours, you need additional logic to subtract non-business hours from elapsed time.

Step 4: Test the skill

Invoke the skill conversationally:

/sla-alert

A typical run looks like:

Checking open tickets for SLA risk...
Found 34 open ticket(s)
 
  #18201  "Shipping delay on order #4892"    42m left
    -> Slack alert sent
  #18195  "Wrong item received"              BREACHED
    -> Slack alert sent
  #18210  "Return label request"             15m left
    -> Already alerted (skipping)
 
Done. 2 alert(s) sent.

Because the agent generates code on the fly, you can also make ad hoc requests:

  • "Which tickets are closest to breaching right now?" — the agent runs read-only
  • "Check SLA for chat tickets only" — the agent filters by channel
  • "Post a batch summary instead of individual alerts" — the agent adapts the output
Adjust SLA targets to match your policy

The default targets (4 hours email, 15 minutes chat) are starting points. Tell the agent your actual targets conversationally: "Our email SLA is 2 hours and chat is 10 minutes."

Step 5: Schedule it (optional)

Option A: Cron + Claude CLI

# Run every 15 minutes during business hours
*/15 8-18 * * 1-5 cd /path/to/your/project && claude -p "Run /sla-alert" --allowedTools 'Bash(*)' 'Read(*)'

Option B: GitHub Actions + Claude

name: SLA Breach Monitor
on:
  schedule:
    - cron: '*/15 * * * *'  # Every 15 minutes
  workflow_dispatch: {}
jobs:
  alert:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: anthropics/claude-code-action@v1
        with:
          prompt: "Run /sla-alert"
          allowed_tools: "Bash(*),Read(*)"
        env:
          ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
          GORGIAS_DOMAIN: ${{ secrets.GORGIAS_DOMAIN }}
          GORGIAS_EMAIL: ${{ secrets.GORGIAS_EMAIL }}
          GORGIAS_API_KEY: ${{ secrets.GORGIAS_API_KEY }}
          SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }}
          SLACK_CHANNEL_ID: ${{ secrets.SLACK_CHANNEL_ID }}

Option C: Cowork Scheduled Tasks

Claude Desktop's Cowork supports built-in scheduled tasks. Open a Cowork session, type /schedule, and configure the cadence — hourly, daily, weekly, or weekdays only. Each scheduled run has full access to your connected tools, plugins, and MCP servers.

Scheduled tasks only run while your computer is awake and Claude Desktop is open. If a run is missed, Cowork executes it automatically when the app reopens. For always-on scheduling, use GitHub Actions (Option B) instead. Available on all paid plans (Pro, Max, Team, Enterprise).

Wall-clock time vs. business hours

This skill calculates SLA using wall-clock hours by default. If your SLA counts only business hours, tickets created Friday evening will show as breached by Monday morning. Ask the agent to add business-hours logic, or adjust your thresholds to account for non-business hours.

Troubleshooting

When to use this approach

  • You want conversational flexibility — custom SLA targets, channel-specific checks, batch summaries alongside individual alerts
  • You want on-demand SLA checks during standups or shift handoffs
  • You're already using Claude Code and want skills that integrate with your workflow
  • You want to run tasks in the background via Claude Cowork while focusing on other work
  • You prefer guided references over rigid scripts — the agent adapts while staying reliable

When to switch approaches

  • You need real-time alerting (under 1 minute) → use n8n with a webhook trigger
  • You want native SLA tracking without external tools → use Gorgias SLA Views (limited to passive monitoring)
  • You need alerts running 24/7 at zero LLM cost → use n8n with a scheduled workflow

Common questions

Why not just use Gorgias SLA Views?

Gorgias SLA Views show at-risk tickets in a dashboard, but they cannot send proactive Slack alerts. Your team lead has to manually check the View to spot at-risk tickets. This skill pushes alerts to Slack automatically.

Does this use Claude API credits?

Yes. The agent reads skill files and generates code each time. Typical cost is $0.01-0.05 per invocation. No inner Claude calls are needed — SLA calculation is pure math.

Can I run this every 5 minutes for chat SLA?

You can, but it generates more GitHub Actions minutes and Claude API costs. For sub-minute SLA alerting, use the n8n approach with a scheduled trigger instead.

Cost

  • Claude API — $0.01-0.05 per invocation (the agent reads files and generates code)
  • Gorgias API — included in all paid plans, no per-call cost
  • Slack API — included in all plans, no per-call cost
  • GitHub Actions (if scheduled) — free tier includes 2,000 minutes/month

Looking to scale your AI operations?

We build and optimize automation systems for mid-market businesses. Let's discuss the right approach for your team.