← All recipes

GitHub Actions recipe · Pro plan

Alert Slack when a frustrated customer reports a bug

Scitor's AI triage (Pro plan) labels every ticket with a sentiment and a category. When both sentiment:negative and category:bug-report land on the same ticket — Scitor's own docs call this combination out as worth watching — this workflow posts it to Slack.

What this workflow does

It fires whenever a sentiment or category label is applied (AI triage adds them one at a time), rechecks the ticket's full label set, and — only when both the negative sentiment and bug-report category are present — posts one Slack message linking back to the GitHub Issue.

What it does not do

It doesn't reply to the customer — that still happens on the Issue with /send. It requires the Pro plan's AI triage to be enabled (ai: true in scitor.yaml) — on Free, neither label ever exists, so this never fires.

The workflow file

Save as .github/workflows/alert-frustrated-bug-report.yml.

# Alert Slack when a frustrated customer reports a bug
#
# Scitor's AI triage (Pro plan) labels every ticket with a sentiment
# (positive/neutral/negative) and a category (bug-report, billing, etc.).
# This fires when a ticket has both `sentiment:negative` and
# `category:bug-report` — a frustrated customer with a real bug, the
# combination Scitor's own docs call out as worth a dedicated alert.
#
# What this does:
#   - Fires when either the sentiment or category label is applied (AI
#     triage adds them one at a time, so both trigger a check).
#   - Re-reads all of the issue's current labels and only proceeds if both
#     are present.
#   - Posts one Slack message linking back to the ticket.
#
# What this does NOT do:
#   - It does not reply to the customer. That still happens on the GitHub
#     Issue with `/send` — this is purely an internal notification.
#   - It does not de-duplicate: if AI re-labels the same ticket (labels are
#     not normally removed and re-added by Scitor, but a human could), this
#     fires again. Add an "already posted" comment check if that matters
#     for your workflow.
#
# Required secret:
#   SLACK_WEBHOOK_URL — Slack app settings -> Incoming Webhooks -> Add New
#   Webhook to Workspace.
#
# Source: adapted from Scitor's own documented examples at
# https://support.scitor.io/features/ai-analysis#github-actions-automation
# and https://support.scitor.io/guides/github-actions#slack-notification-for-urgent-issues
# (both use sentiment:negative + category:bug-report as the trigger
# condition). Slack action pinned to slackapi/slack-github-action@v4.0.0 —
# newer than the @v2 shown in Scitor's own docs; verified as the current
# real release (github.com/slackapi/slack-github-action/releases) and kept
# consistent with /integrations/slack on this site, which made the same
# upgrade for the same reason.

name: Alert Slack on frustrated bug report
on:
  issues:
    types: [labeled]

jobs:
  notify:
    if: github.event.issue.user.login == 'scitor-customerops[bot]'
    runs-on: ubuntu-latest
    steps:
      - name: Check labels and build Slack payload
        id: check
        uses: actions/github-script@v7
        with:
          script: |
            const labels = context.payload.issue.labels.map((l) => l.name);
            const match = labels.includes('sentiment:negative') && labels.includes('category:bug-report');
            core.setOutput('match', match ? 'true' : 'false');
            if (!match) return;

            // 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 payload = {
              text: 'Frustrated customer bug report',
              blocks: [
                {
                  type: 'section',
                  text: {
                    type: 'mrkdwn',
                    text: `*Frustrated customer bug report*\n<${context.payload.issue.html_url}|${context.payload.issue.title}>`,
                  },
                },
              ],
            };
            core.setOutput('payload', JSON.stringify(payload));

      - name: Send Slack notification
        if: steps.check.outputs.match == 'true'
        uses: slackapi/slack-github-action@v4.0.0
        with:
          webhook: ${{ secrets.SLACK_WEBHOOK_URL }}
          webhook-type: incoming-webhook
          payload: ${{ steps.check.outputs.payload }}

Same mechanism as the Slack integration, filtered to one label combination.

Required secret

Secret Where to get it
SLACK_WEBHOOK_URL Slack app settings → Incoming Webhooks → Add New Webhook to Workspace.

Catch the tickets that need eyes now

Takes under 5 minutes. Free tier available. No credit card required.