Blog Incident response

Discord and Telegram incident alerts

Plenty of small teams run on Discord or Telegram rather than Slack. An alert bot that posts a new message for every change turns the channel into a scroll of "FIRING" and "RESOLVED" lines, and nobody can tell at a glance which incidents are still open.

ZipLogger posts each incident to a Discord channel or a Telegram chat as one message, and edits that message as the incident is acknowledged and resolved. This post covers the setup for each, what the message contains, how errors show up, and what it does not do.

How it differs from Slack and Teams

DiscordTelegramSlack and Microsoft Teams apps
What you connecta channel's webhook URLa bot token and a chatan installed app
One message per incident, edited in placeyesyesyes
Acknowledge, assign or resolve from the messagenonoyes
Link to the incidentyesan Open in ZipLogger buttonyes

So Discord and Telegram show the state; they do not change it. To acknowledge from your phone, use the paging email, SMS or call (the SMS and voice paging post covers how), or open the link. If you want buttons, see Slack incident alerts and Microsoft Teams incident alerts.

Discord: create a webhook

In Discord, open Server settings → Integrations → Webhooks → New webhook, pick the channel the incidents should go to, and click Copy webhook URL. It looks like this:

https://discord.com/api/webhooks/123456789012345678/AbCdEf…

Treat it like a password. Anyone with the URL can post to that channel.

Then in ZipLogger, an Admin opens Alerts → Destinations, clicks + Connect a destination, sets Tool to Discord and pastes the URL into Webhook URL.

Telegram: create a bot and add it to the chat

  1. In Telegram, talk to @BotFather and send /newbot. It gives you a bot token, a long string with a colon in it.
  2. Add the bot to the group or channel that should get incidents. In a channel it has to be an admin that can post.
  3. Find the chat id. For a group or private chat it is a number such as -1001234567890; forwarding a message from the chat to @userinfobot shows it. A public channel can be given as @name instead.

In ZipLogger, set Tool to Telegram, paste the token into Bot token and the id into Chat id or @channel.

Which incidents go there

The rest of the form is the same as for any destination: give it a name, then under Which incidents go there choose a Minimum severity and, if you want, one Service and one Environment; empty means any. Keep Send matching incidents automatically ticked for a normal channel feed, or untick it to use the destination only from an escalation policy step that names it. Under Keeping both sides in step, leave Acknowledging here acknowledges there and Resolving here resolves there ticked: for Discord and Telegram they decide whether the message is edited when the incident is acknowledged or resolved. Click Verify the credential and connect. ZipLogger checks before it saves anything:

  • Discord: it reads the webhook, which tells it the webhook exists. Nothing is posted to the channel.
  • Telegram: it calls getMe to check the token, then getChat for your chat. getChat fails unless the bot is already in the chat, and the error then ends with "(add the bot to the chat first)".

A URL that is not a Discord webhook is refused with "Paste a Discord webhook URL: https://discord.com/api/webhooks/…". The webhook URL and the bot token are stored encrypted and never shown again.

What the Discord message looks like

This is the body ZipLogger's Discord adapter builds for a triggered incident from a sample alert rule. The embed title starts with a status mark (a red circle, then eyes once acknowledged, then a check mark once resolved), which is left out here:

{
  "username": "ZipLogger",
  "allowed_mentions": { "parse": [] },
  "embeds": [
    {
      "title": "Checkout errors",
      "url": "https://app.ziplogger.ai/alerts/incidents/…",
      "description": "Alert rule \"Checkout errors\" fired: 37 errors in 5 minutes.",
      "color": 14692657,
      "fields": [
        { "name": "Status", "value": "Triggered", "inline": true },
        { "name": "Severity", "value": "high", "inline": true },
        { "name": "Service", "value": "checkout-api", "inline": true },
        { "name": "Environment", "value": "production", "inline": true }
      ],
      "footer": { "text": "ZipLogger incident" },
      "timestamp": "2026-10-15T07:40:00.0000000Z"
    }
  ]
}

The colour follows the state: red (14692657, #E03131) while triggered, amber (16097024, #F59F00) once acknowledged, green (3120708, #2F9E44) once resolved. Service and Environment are left out when the incident has none.

allowed_mentions with an empty parse list switches mentions off for the message. An incident titled @everyone or <@&role> shows that text and pings nobody, which matters when a title comes from someone else's alert.

The first post uses ?wait=true so Discord returns the message id. Every later change is a PATCH to …/messages/{id}. If someone deleted the message in Discord, the next change posts a new one.

What the Telegram message looks like

Telegram gets a text message in its HTML mode, with the title and the status in bold and an inline Open in ZipLogger button under it. In the chat, the same incident reads:

Checkout errors
Status: Triggered · Severity: high
Service: checkout-api (production)
Alert rule "Checkout errors" fired: 37 errors in 5 minutes.
[ Open in ZipLogger ]

Like on Discord, the title starts with a status mark. Everything taken from the incident is HTML-escaped before it is sent, so a title with < or & in it shows as written. Changes use editMessageText on the same message.

When it fails

Each post goes through the same delivery ledger as SMS and email pages, and every attempt is on the incident timeline.

What came backWhat ZipLogger does
429 or a 5xx, from eitherretries with backoff
Discord 401 or 403stops: "Discord refused the credential (401). Reconnect the destination."
Discord 404stops: "Discord says the target does not exist (404). It was deleted, or the address is wrong."
any other Telegram errorstops, with Telegram's own description after "Telegram: "

A 404 on Discord usually means someone deleted the webhook in the server settings. Create a new one and paste it into the destination.

What it does not do

  • No acknowledge buttons. Neither Discord nor Telegram messages can change the incident. Use the link, the app, or the paging email, SMS or call.
  • No mentions on Discord. On purpose, as above. If the channel should ping a role, set that up on Discord's side, for example with the channel's notification settings.
  • No posts during planned silence. An incident that opens inside a maintenance window, or while flood control is holding back a burst, is recorded in ZipLogger but not posted.
  • Not a pager. A chat message does not wake anyone. Keep an escalation policy for that; see on-call schedules and escalation.

The same setup is in the Discord and Telegram docs. To try it, create a free workspace and add a destination under Alerts → Destinations.

Alert on error logs and quiet services

Set up log-based alert rules that fire on error spikes or when a service goes quiet, send them to email or Slack, and keep them from paging for nothing.

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.

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.