Scitor + Slack
Notify Slack when a support ticket needs attention
A Scitor ticket is a GitHub Issue. When Scitor finishes triaging an inbound email and applies its spam:clean label, a GitHub Actions workflow can post it straight to Slack — category, sentiment, and a link back to the ticket. No Slack app to build, no vendor connector, no extra plan.
What this workflow does
It fires once per ticket, when Scitor applies spam:clean — meaning AI triage (if enabled) has already run and the message is a real inbound request, not spam. It posts one Slack message with the ticket's category, sentiment, and a button linking back to the GitHub Issue.
What it does not do
It is one-way. Replying in Slack does not reply to the customer — that still happens on the GitHub Issue with /send. And by default it notifies on every clean ticket, not just urgent ones; the workflow's comment shows the one-line change to filter on priority:urgent or sentiment:negative instead. It also doesn't de-duplicate — removing and re-applying the trigger label on the same ticket posts a second Slack message, so treat the label as a one-shot trigger.
The workflow file
Save this as .github/workflows/slack-ticket-feed.yml in your Scitor-connected repository.
# New ticket Slack feed
#
# Posts a Slack message for every clean incoming Scitor ticket, showing
# category, sentiment, and priority, with a button linking to the GitHub Issue.
#
# What this does:
# - Fires once per ticket, when Scitor finishes AI triage and applies the
# `spam:clean` label (meaning the message is a real inbound request, not spam).
# - Sends one Slack message per ticket via an incoming webhook.
#
# What this does NOT do:
# - It does not read Slack replies back into the ticket. Slack -> GitHub is
# one-way; replying to the customer still happens on the GitHub Issue with /send.
# - It does not filter by urgency. To notify only on frustrated/urgent tickets,
# change the `if:` condition to check `sentiment:negative` or `priority:urgent`
# instead of `spam:clean` (see the alternate condition below).
# - It does not de-duplicate: removing and re-applying the trigger label on
# the same ticket posts a second Slack message. Treat the label as a
# one-shot trigger.
#
# Required secret:
# SLACK_WEBHOOK_URL — an Incoming Webhook URL from your Slack workspace
# (Slack app settings -> Incoming Webhooks -> Add New Webhook to Workspace).
#
# Source: adapted from Scitor's own documented example at
# https://support.scitor.io/guides/github-actions#slack-new-ticket-feed
# (slackapi/slack-github-action pinned to v4.0.0, the version Slack's own
# docs currently recommend, as of 2026-09-17 --
# https://docs.slack.dev/tools/slack-github-action/sending-data-slack-incoming-webhook/ --
# the incoming-webhook payload syntax is unchanged from the v2 the support
# docs illustrate).
name: New ticket Slack feed
on:
issues:
types: [labeled]
jobs:
slack:
# Fires on every clean ticket. To notify only on urgent/negative tickets instead, use:
# if: github.event.label.name == 'priority:urgent' || github.event.label.name == 'sentiment:negative'
if: >
github.event.label.name == 'spam:clean' &&
github.event.issue.user.login == 'scitor-customerops[bot]'
runs-on: ubuntu-latest
steps:
- name: Build Slack payload
id: meta
uses: actions/github-script@v7
with:
script: |
const labels = context.payload.issue.labels.map(l => l.name);
const category = labels.find(l => l.startsWith('category:'))?.replace('category:', '') ?? 'uncategorized';
const sentiment = labels.find(l => l.startsWith('sentiment:'))?.replace('sentiment:', '') ?? 'unknown';
const priority = labels.find(l => l.startsWith('priority:'))?.replace('priority:', '');
const emoji = { positive: '🟢', neutral: '🟡', negative: '🔴' }[sentiment] ?? '⚪';
// Build the payload as a real object and let JSON.stringify escape
// the ticket title/URL — string-interpolating them straight into a
// JSON literal breaks if a title contains a `"`, `\`, or newline.
const priorityText = priority ? ` · *${priority}*` : '';
const text = `${emoji} *${category}*${priorityText}\n<${context.payload.issue.html_url}|${context.payload.issue.title}>`;
const payload = {
blocks: [
{
type: 'section',
text: { type: 'mrkdwn', text },
accessory: {
type: 'button',
text: { type: 'plain_text', text: 'View ticket' },
url: context.payload.issue.html_url,
},
},
],
};
core.setOutput('payload', JSON.stringify(payload));
- name: Post to Slack
uses: slackapi/slack-github-action@v4.0.0
with:
webhook: ${{ secrets.SLACK_WEBHOOK_URL }}
webhook-type: incoming-webhook
payload: ${{ steps.meta.outputs.payload }} Required secret
| Secret | Where to get it |
|---|---|
| SLACK_WEBHOOK_URL | Slack app settings → Incoming Webhooks → Add New Webhook to Workspace. Add it under Settings → Secrets and variables → Actions in your repository. |
Questions about this integration
- Does this need a paid Scitor plan?
- No — the labels this workflow reads (spam:clean, category:*, sentiment:*, priority:*) are applied by Scitor's own triage on inbound tickets. Sentiment and category labels specifically come from AI analysis, which requires the Pro plan and the ai: true opt-in in scitor.yaml (AI is off by default). Without AI enabled, the workflow still fires on spam:clean, just without a sentiment/category label to show.
- Can I get notified only for urgent tickets, not every ticket?
- Yes. Change the workflow's `if:` condition from `spam:clean` to check `priority:urgent` or `sentiment:negative` instead — both are labels Scitor applies automatically, so no extra configuration is needed beyond editing that one line.
- Does replying in Slack reply to the customer?
- No. This integration is one-way — Slack is a notification feed. Replying to the customer still happens on the GitHub Issue with the /send command, which is how Scitor's email reply pipeline works regardless of any integration.
Your support inbox, one Slack message away
Takes under 5 minutes. Free tier available. No credit card required.