# Discord Alerts

URL: https://zerodev.ca/docs/vail/discord

> Post status updates to a Discord channel through a webhook.



Vail can post embeds to a Discord channel through a webhook. It does not post on its own when a service goes down. You send each update to Vail's `/api/notify` endpoint, by hand or from a script, and Vail forwards it to Discord.

## Set Up the Webhook

1. In Discord, open the channel's settings, go to **Integrations > Webhooks** and click **New Webhook**.
2. Copy the webhook URL.
3. Add it to `settings.json`:

```json title="settings.json"
{
  "discord": {
    "enabled": true,
    "webhookUrl": "https://discord.com/api/webhooks/...",
    "apiKey": "a-long-random-string",
    "username": "Vail Status",
    "avatarUrl": "https://status.example.com/logo.png"
  }
}
```

| Setting      | What it does                                                                         |
| ------------ | ------------------------------------------------------------------------------------ |
| `enabled`    | Turns alerts on.                                                                     |
| `webhookUrl` | The Discord webhook URL.                                                             |
| `apiKey`     | The key callers must send to `/api/notify`. The endpoint is off while this is empty. |
| `username`   | Optional. The name the webhook posts as.                                             |
| `avatarUrl`  | Optional. The picture the webhook posts with.                                        |

## Send an Update

```bash
curl -X POST https://status.example.com/api/notify \
  -H "Authorization: Bearer a-long-random-string" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "API Degraded",
    "message": "Requests are slower than usual. We are looking into it.",
    "status": "degraded",
    "url": "https://status.example.com"
  }'
```

| Field     | Required | What it does                                                             |
| --------- | -------- | ------------------------------------------------------------------------ |
| `title`   | Yes      | The embed title.                                                         |
| `message` | Yes      | The embed text.                                                          |
| `status`  |          | `operational`, `degraded`, `outage` or `maintenance`. Sets the colour.   |
| `type`    |          | `info`, `warning` or `error`. Sets the colour when there is no `status`. |
| `url`     |          | Makes the title a link.                                                  |

Vail answers `{ "success": true }`, or an error with the reason.

| Status | Meaning                                                    |
| ------ | ---------------------------------------------------------- |
| `401`  | The `Authorization` header is missing or the key is wrong. |
| `403`  | `apiKey` is empty in `settings.json`.                      |
| `400`  | `title` or `message` is missing, or alerts are turned off. |

Generate a key with `openssl rand -hex 32` and keep it out of anything public, such as a GitHub repository.

| Colour | Used for              |
| ------ | --------------------- |
| Green  | `operational`         |
| Yellow | `degraded`, `warning` |
| Red    | `outage`, `error`     |
| Blue   | `maintenance`, `info` |

## Ideas

* Call it from an uptime checker, such as a cron job that runs `curl` when a service stops answering.
* Post the same text you add to `incidents` in `settings.json`, so the page and Discord match.
