Blog Incident response

Slack incident alerts you can acknowledge

Most alert-to-Slack setups only go one way. A message lands in #alerts, someone adds an emoji to say "on it", and then opens another tool to actually acknowledge the page. An hour later nobody can tell from the channel whether the incident is still open.

ZipLogger's Slack app posts each incident as one message and keeps that message up to date. It has buttons, and a click changes the real incident in ZipLogger, as the person who clicked. This post covers the setup, what the message looks like, how Slack users are matched to ZipLogger users, and when a plain incoming webhook is enough.

Two ways to get incidents into Slack

Slack app (a destination)Incoming webhook (on an alert rule)
Set up inSettings → Integrations, then Alerts → Delivery → Destinationsthe alert rule's Webhook URL field
Which incidentsany incident that matches a severity, service and environmentonly incidents from that one alert rule
Messagesone per incident, edited as it changesa new message when it fires, another when it recovers
ButtonsAcknowledge, Assign to me, Resolvenone
Private channelsnoyes, if the webhook belongs to one

The rest of this post is about the app. The webhook is covered at the end.

Connect the Slack workspace

A ZipLogger Admin opens Settings → Integrations and clicks Connect Slack → on the Slack card. ZipLogger sends you to Slack's own consent screen, where you pick the workspace. The app asks for two bot scopes and nothing else:

  • chat:write, to post its messages and edit them
  • channels:read, to list public channels for the channel picker

So it cannot read message history, cannot look up members' email addresses, and cannot post to a channel it was not invited to. After you approve, Slack sends you back to Settings → Integrations, which now shows the workspace, who connected it, and when.

A few rules the install enforces:

  • Start from ZipLogger. The install link works once, expires after 10 minutes, and is tied to the browser that started it. An install that did not start from the Connect Slack button is refused.
  • One to one. A ZipLogger workspace connects to one Slack workspace, and a Slack workspace can belong to only one ZipLogger workspace at a time. If it is already taken, the banner says Could not connect Slack (team_taken).
  • Connecting posts nothing. No message reaches Slack until you add a destination.

Pick a channel

First, invite the bot to the channel in Slack:

/invite @ZipLogger

Then an Admin goes to Alerts → Delivery → Destinations, clicks + Connect a destination and sets Tool to Slack. Editors can change a destination later. There is no API key to paste. The form shows a Channel list loaded from your Slack workspace instead. Only public channels are listed, because the app does not ask for the scope that lists private ones.

Under Which incidents go there, choose a Minimum severity and, if you want, one Service and one Environment. Empty means any. Environment matches the incident's environment label, which comes from job monitors and inbound integrations. Incidents from alert rules have no label, so they only match an empty Environment. Keep Send matching incidents automatically ticked for a normal channel feed. Untick it if the channel should only be used by an escalation policy step. Then click Verify the channel and connect.

The check at save time is light. It confirms that Slack is connected and that a channel was chosen. It does not ask Slack whether the bot is in that channel. If you skipped the /invite, the first incident fails with Slack's not_in_channel error, which shows on the destination instead of being retried forever.

You can add several Slack destinations, for example one channel for everything high and above, and another for one service at any severity.

The message, and how it changes

This is the Block Kit the destination adapter builds for a new incident. It was rendered from ZipLogger's own code for a sample incident. The header block (a coloured dot for the severity, then the title) is left out, and the encrypted button values are shortened:

[
  { "type": "section", "text": { "type": "mrkdwn",
      "text": "*Triggered* · severity *high*\nAlert rule \"Checkout errors\" fired: 37 errors in 5 minutes." } },
  { "type": "section", "fields": [
      { "type": "mrkdwn", "text": "*Service*\ncheckout-api" },
      { "type": "mrkdwn", "text": "*Environment*\nproduction" } ] },
  { "type": "actions", "elements": [
      { "type": "button", "text": { "type": "plain_text", "text": "Acknowledge" },
        "action_id": "acknowledge", "value": "<encrypted>" },
      { "type": "button", "text": { "type": "plain_text", "text": "Assign to me" },
        "action_id": "assign_to_me", "value": "<encrypted>" },
      { "type": "button", "text": { "type": "plain_text", "text": "View in ZipLogger" },
        "url": "https://app.ziplogger.ai/alerts/incidents/…" } ] }
]

The buttons follow the incident's current state:

Incident stateButtons on the message
TriggeredAcknowledge, Assign to me, View in ZipLogger
AcknowledgedResolve, Assign to me, View in ZipLogger
ResolvedView in ZipLogger only

When the incident is acknowledged, resolved or reassigned, ZipLogger edits the same message with chat.update instead of posting a new one. An assignment adds an Assigned to: line with the person's name, or the on-call team's name followed by "(team)". It does not matter where the change happened. A click in Slack, the ZipLogger UI, a Microsoft Teams card or a PagerDuty acknowledgement all refresh the Slack message. The destination's Acknowledging here acknowledges there and Resolving here resolves there boxes control whether those updates are sent, so leave them ticked for Slack.

Who is acting when someone clicks

A Slack click carries a Slack user id, not a ZipLogger login. ZipLogger maps one to the other with an explicit link, never by email address. A Slack workspace admin can set any member's email to anything, so matching on email would let them take over someone else's ZipLogger identity.

A link is made in one of two ways:

  1. The Admin who connected the workspace is linked automatically during the install.
  2. Everyone else links on their first click. That click is not applied. Instead, only they see "Link your ZipLogger account to use this button." with a Link your account button. It opens the Link your Slack account page in ZipLogger. They sign in if needed, click Confirm, and see a Linked badge. The link request works once and expires after 10 minutes.

After that, they click the button again. From then on it acts as their ZipLogger user, and the incident timeline records the actor as Slack: followed by their name.

Permissions come from ZipLogger roles, not Slack roles. Admins and Editors can act. A Viewer who clicks gets "You don't have permission to do this in ZipLogger." The role is checked when the click arrives and again when it is applied, so someone downgraded in between is refused.

Two timing details:

  • Slack wants an answer within 3 seconds, so ZipLogger queues the click and applies it in the background. The queue is checked every 10 seconds, so the message can take several seconds to change after a click.
  • Double clicks and Slack's own retries are safe. The same click is stored once, and acknowledging an incident that someone else already acknowledged does nothing.

Disconnecting

Disconnect on the Slack card revokes the app's token. Slack destinations then fail with "Slack is not connected for this workspace." until you connect again. User links are kept, so nobody has to link again after a reconnect. Removing the app from inside Slack has the same effect: Slack sends app_uninstalled or tokens_revoked, and ZipLogger marks the connection as revoked.

When the incoming webhook is enough

The alert rule's Webhook URL field still exists. It sends an HTTP POST with a Slack-compatible body to whatever URL you paste, so a Slack incoming webhook works, and so does anything else that accepts the same shape. The body is:

{"text": ":rotating_light: *Checkout errors* FIRING\n<summary>\n<link to the incident>"}

On recovery it starts with :large_green_circle: and says RESOLVED instead.

Use it when the alerts must go to a private channel, when you can't install an app in the workspace, or when only one rule should post. Its limits are the reverse of the app's: it only covers that rule's incidents (not job monitors or other sources), every change is a new message, and there is nothing to click. The log alert rules post covers the rule side.

What the Slack app does not do

  • No private channels. The picker lists public channels only.
  • No slash commands. You can't open or search incidents from Slack. The three buttons are the only actions.
  • No Sign in with Slack. Linking attaches a Slack user to an existing ZipLogger account. It is not a login method.
  • No posts during planned silence. An incident that opens inside a maintenance window, or while flood control is holding back a burst of incidents, is recorded in ZipLogger but not posted.
  • It doesn't replace paging. A Slack message is not a phone call. For someone who must wake up, pair the channel with an escalation policy. See on-call schedules and escalation.

The same steps are in the Slack docs. To try it, create a free workspace, connect Slack under Settings → Integrations, and add a channel under Alerts → Delivery → Destinations.

Microsoft Teams incident alerts with actions

Get ZipLogger incident cards in a Teams channel or chat, and acknowledge, assign or resolve them from the card. Setup, account linking and limits.

On-call schedules and escalation policies

Set up on-call teams, rotations with primary and secondary layers, overrides, a repeating escalation policy, calendar subscriptions and postmortems in ZipLogger.

Discord and Telegram incident alerts

Post ZipLogger incidents to a Discord channel or a Telegram chat as one message that is edited as the incident is acknowledged and resolved. Setup, payloads and limits.

Try it on your own logs

There is a free plan and no sales call. Install an SDK, send a few log lines, and search them.