Notification Channels
The AI DBA Workbench sends alert notifications through configurable notification channels. Administrators manage channels through the admin panel under the Notifications section. The alerter uses these channels to deliver alert notifications when rules fire, clear, or require reminders.
Channel Types
The workbench supports five notification channel types:
- Email channels send alerts via SMTP to configured recipients; the channel supports TLS/STARTTLS, authentication, and per-channel recipient management.
- Slack channels send alerts to a Slack channel through an incoming webhook URL.
- Mattermost channels send alerts to a Mattermost channel through an incoming webhook URL.
- Telegram channels send alerts to a Telegram chat, group, or channel through a bot that posts with the Telegram Bot API.
- Webhook channels send alerts to an arbitrary HTTP endpoint with configurable HTTP methods, custom headers, authentication, and JSON payload templates.
Managing Channels
Each channel type has a dedicated page in the admin panel sidebar under the Notifications section. All channel types share a common set of management operations.
The following operations are available for all channel types:
- The Add Channel button creates a new notification channel.
- The Edit icon opens the channel configuration dialog.
- The Delete icon removes a channel after confirmation.
- The Send icon sends a test notification to verify the channel configuration.
- The inline switch toggles a channel between enabled and disabled states.
Administrators must have the
manage_notification_channels permission to access
these operations.
Delivery Behaviour
The alerter delivers each notification and records the outcome against the alert in its notification history. The rules in this section apply to every channel, whatever the channel type.
Retries
A delivery that fails is retried, and a notification
that never succeeds is recorded as failed. The
max_retry_attempts and retry_backoff_minutes
settings control how many attempts the alerter makes
and how long it waits between them; see
Alerter Configuration.
The alerter makes three attempts by default, with waits
of 5 minutes and then 15 minutes between them. The
history record keeps the error from the most recent
attempt, which is the place to look when a notification
never arrives.
Redirects
Slack, Mattermost, Telegram, and webhook deliveries do
not follow HTTP redirects. A provider that answers a
delivery with a 3xx response fails that delivery. The
alerter then retries the delivery on the schedule above
and marks the notification failed once the attempts
run out, and the recorded error names the 3xx status
code.
Redirects are refused to protect the credentials that
these channels carry in their request URLs. Go copies
the full URL of the previous request into the Referer
header of a redirected request. The Slack and
Mattermost webhook URLs are themselves secrets, and the
Telegram URL carries the bot token in its path, so
following a redirect would disclose the credential to
whichever host the Location header names. A webhook
channel gains a second protection, because the
workbench validates the endpoint host when the channel
is saved, and a redirect could carry the request past
that check to a private host. The measure is
preventive; the Send icon has always refused redirects,
and delivery now behaves in the same way.
Configure the final URL in the channel when an endpoint answers with a redirect. Email channels are unaffected, because email is delivered over SMTP rather than HTTP.
Email Channels
Email channels deliver alert notifications through SMTP to a list of configured recipients.
SMTP Configuration
The following settings configure the SMTP connection:
| Setting | Required | Default | Description |
|---|---|---|---|
| SMTP Host | Yes | - | The SMTP server hostname. |
| SMTP Port | No | 587 | The SMTP server port number. |
| SMTP Username | No | - | The username for SMTP authentication. |
| SMTP Password | No | - | The password for SMTP authentication. |
| Use TLS | No | On | Enables TLS encryption for the connection. |
| From Address | Yes | - | The sender email address. |
| From Name | No | - | The sender display name. |
Recipients
The Recipients tab manages individual email recipients for the channel. Each recipient has an email address, a display name, and an enabled toggle. Administrators can add recipients during channel creation or later through the edit dialog.
Slack Channels
Slack channels deliver alert notifications to a Slack workspace channel through an incoming webhook URL.
Configuration
The following settings configure a Slack channel:
| Setting | Required | Description |
|---|---|---|
| Name | Yes | A descriptive name for the channel. |
| Description | No | An optional description of the channel. |
| Webhook URL | Yes | The Slack incoming webhook URL. |
Creating a Slack Webhook
To create an incoming webhook for Slack, follow these steps:
- Create a Slack App in the Slack API dashboard.
- Enable the Incoming Webhooks feature for the app.
- Create a new webhook and select a target channel.
- Copy the generated webhook URL into the channel settings.
For detailed instructions, see the Slack Webhooks documentation.
Mattermost Channels
Mattermost channels deliver alert notifications to a Mattermost channel through an incoming webhook URL.
Configuration
The following settings configure a Mattermost channel:
| Setting | Required | Description |
|---|---|---|
| Name | Yes | A descriptive name for the channel. |
| Description | No | An optional description of the channel. |
| Webhook URL | Yes | The Mattermost incoming webhook URL. |
Creating a Mattermost Webhook
To create an incoming webhook in Mattermost, follow these steps:
- Navigate to Main Menu, then Integrations.
- Select Incoming Webhooks and create a new webhook.
- Choose the target channel for notifications.
- Copy the generated webhook URL into the channel settings.
For detailed instructions, see the Mattermost Incoming Webhooks documentation.
Telegram Channels
Telegram channels deliver alert notifications to a Telegram chat, group, or channel through the Telegram Bot API. A Telegram channel stores two values rather than a single webhook URL: a bot token that identifies the sending bot, and a chat ID that identifies the destination.
Configuration
The following settings configure a Telegram channel:
| Setting | Required | Description |
|---|---|---|
| Name | Yes | A descriptive name for the channel. |
| Description | No | An optional description of the channel. |
| Bot Token | Yes | The token that BotFather issued for the bot, in the form <bot id>:<token>. |
| Chat ID | Yes | The numeric chat ID, or an @channelusername for a public channel. |
The workbench encrypts the bot token before storing it and never returns the token after saving. The channel list reports only whether a token is configured, and the Bot Token field is blank when an administrator edits a channel; enter a value only to replace the stored token. The chat ID is not a secret, so the admin panel and the REST API display the stored value.
The Send icon delivers a test message to the configured chat, which confirms that the bot token and the chat ID are correct and that the bot may post.
The REST API carries the two values in the
telegram_bot_token and telegram_chat_id fields of a
create or update request. A response reports
telegram_bot_token_set in place of the token, and an
update that omits telegram_bot_token keeps the stored
token.
Creating a Telegram Bot
BotFather is the Telegram bot that registers and manages other bots. To create a bot for the workbench, follow these steps:
- Open a chat with @BotFather
and send the
/newbotcommand. - Choose a display name and a username for the bot;
the username must end in
bot. - Copy the token that BotFather returns into the Bot Token field, and treat the token as a password.
- Add the bot to the group or channel that receives the notifications.
- Promote the bot to administrator when the destination is a channel, so that the bot may post messages.
Finding the Chat ID
The chat ID identifies the destination that the bot posts to. To find the chat ID of a chat, group, or channel, follow these steps:
- Send any message in the target chat, group, or channel.
- Request
https://api.telegram.org/bot<token>/getUpdates, replacing<token>with the bot token. - Read the chat ID from the
result[].message.chat.idfield of the JSON response.
Group and supergroup IDs are negative numbers, such as
-1001234567890, whereas a chat with a single user has
a positive ID. For a public channel, enter
@channelusername in place of the numeric ID.
For details of the Bot API methods, see the Telegram Bot API documentation.
Securing the Bot Token
The bot token is a bearer credential; anyone who holds
the token can post as the bot and read the updates that
the bot receives. The workbench encrypts the token with
the server secret, never displays the token after
saving, and redacts the token from log messages and
from delivery errors recorded against a notification.
The alerter also refuses HTTP redirects when it
delivers a message, so the token cannot travel to
another host in a Referer header; see
Delivery Behaviour.
If a token is exposed, use BotFather to revoke the token and issue a replacement, then save the new token in the channel configuration.
Templates
Telegram channels support custom templates through the
template_alert_fire, template_alert_clear, and
template_reminder fields of the REST API, and the
templates use the variables listed in
Template Variables.
A Telegram template renders the message text, not a
JSON request body. This differs from the Slack,
Mattermost, and webhook templates, which render a
complete JSON payload. The alerter builds the request
body itself and sends the rendered text with the
sendMessage method of the Bot API, so a template that
renders JSON delivers the JSON as visible message text.
The alerter sends messages in HTML parse mode rather
than MarkdownV2, because MarkdownV2 requires escaping
eighteen characters, among them _, ., -, (, and
), which occur constantly in PostgreSQL relation and
index names. A template may use only the tags that
Telegram supports:
- The
<b>and<i>tags set bold and italic text. - The
<u>and<s>tags set underlined and struck-through text. - The
<code>and<pre>tags set inline and block fixed-width text. - The
<a href="...">tag inserts a link. - The
<blockquote>tag sets a block quotation. - The
<tg-spoiler>tag, or a<span>element with thetg-spoilerclass, hides text behind a spoiler.
Telegram rejects a message that contains any other tag,
or a <, >, or & character that is neither part of
a tag nor written as an HTML entity. The alerter
escapes the template variables before rendering, so an
alert title or a relation name that contains those
characters is delivered safely, while the markup in the
template is left intact.
Telegram limits a message to 4096 characters after
parsing. The alerter truncates a longer message on a
character boundary and appends an ellipsis. The cut is
also kept off a markup boundary, so truncation never
severs an HTML entity or an opening tag. The rewind
that achieves this is bounded. The alerter looks back
at most 16 bytes for an unterminated entity, and at
most 512 bytes for an unterminated tag. Those windows
cover a character entity and an <a href="..."> tag;
a stray & or < further back does not move the cut.
The 4096-character limit applies after Telegram parses
the entities, so a long message that also carries
markup can still be refused.
If Telegram refuses a message because it cannot parse
the markup, the alerter sends the same text once more
with no parse mode. The message then arrives as plain
text rather than being lost. The Bot API reports such a
refusal as a 400 response whose description reads
can't parse entities or can't find end tag; the
alerter treats no other failure this way, and it makes
this retry only once.
The fallback matters most for a custom template whose
markup is malformed. Without the fallback, such a
template costs the operator the alert: the delivery is
retried on the usual schedule, recorded as failed,
and never seen in the chat. With the fallback, the
alert arrives, but the formatting is gone and the HTML
entities are visible, so & appears in place of
&. An unformatted alert with visible entities is
therefore a reliable sign that the template contains
broken markup. Correct the template rather than leaving
the channel to fall back on every alert.
A custom template is trusted markup. An administrator
who holds manage_notification_channels can put any
markup that Telegram supports into a template,
including links, and every recipient of the channel
sees the result in a workbench message. That permission
already allows a webhook channel to post any body to
any host, so the two carry comparable trust; grant the
permission accordingly.
Default Telegram Templates
The alerter provides a default template for each notification type. Administrators can copy and customize these templates.
The following template handles alert fire notifications:
{{.SeverityEmoji}} <b>Alert: {{.AlertTitle}}</b>
<b>Server:</b> {{.ServerName}} (<code>{{.ServerHost}}:{{.ServerPort}}</code>)
<b>Severity:</b> {{.Severity}}
{{if .DatabaseName}}<b>Database:</b> <code>{{.DatabaseName}}</code>
{{end}}{{if .MetricName}}<b>Metric:</b> <code>{{.MetricName}}</code>{{if .MetricValue}} = {{.MetricValue}}{{end}}{{if .ThresholdValue}} (threshold {{.Operator}} {{.ThresholdValue}}){{end}}
{{end}}<b>Triggered:</b> {{.TriggeredAt.Format "2006-01-02 15:04:05 MST"}}
{{.AlertDescription}}
The following template handles alert clear notifications:
✅ <b>Resolved: {{.AlertTitle}}</b>
<b>Server:</b> {{.ServerName}} (<code>{{.ServerHost}}:{{.ServerPort}}</code>)
<b>Severity:</b> {{.Severity}}
{{if .DatabaseName}}<b>Database:</b> <code>{{.DatabaseName}}</code>
{{end}}{{if .MetricName}}<b>Metric:</b> <code>{{.MetricName}}</code>
{{end}}<b>Duration:</b> {{.Duration}}
<b>Triggered:</b> {{.TriggeredAt.Format "2006-01-02 15:04:05 MST"}}
{{if .ClearedAt}}<b>Cleared:</b> {{.ClearedAt.Format "2006-01-02 15:04:05 MST"}}
{{end}}
{{.AlertDescription}}
The following template handles reminder notifications:
⏰ <b>Reminder: {{.AlertTitle}}</b> is still active
<b>Reminder:</b> #{{.ReminderCount}}
<b>Server:</b> {{.ServerName}} (<code>{{.ServerHost}}:{{.ServerPort}}</code>)
<b>Severity:</b> {{.Severity}}
{{if .DatabaseName}}<b>Database:</b> <code>{{.DatabaseName}}</code>
{{end}}{{if .MetricName}}<b>Metric:</b> <code>{{.MetricName}}</code>{{if .MetricValue}} = {{.MetricValue}}{{end}}
{{end}}<b>Active since:</b> {{.TriggeredAt.Format "2006-01-02 15:04:05 MST"}}
{{.AlertDescription}}
Webhook Channels
Webhook channels deliver alert notifications to any HTTP endpoint. The webhook channel offers the most flexibility through configurable HTTP methods, custom headers, authentication options, and JSON payload templates.
Settings Tab
The Settings tab configures the core webhook properties:
| Setting | Required | Default | Description |
|---|---|---|---|
| Name | Yes | - | A descriptive name for the channel. |
| Description | No | - | An optional description. |
| Endpoint URL | Yes | - | The URL to send notifications to. |
| HTTP Method | No | POST | The HTTP method: POST, GET, PUT, or PATCH. |
| Enabled | No | On | Toggles the channel on or off. |
The Endpoint URL must be the final URL that handles the request, because the alerter does not follow redirects; see Delivery Behaviour.
Headers Tab
The Headers tab manages custom HTTP headers as key-value pairs. Administrators can add or remove headers dynamically to meet the requirements of the target endpoint.
Authentication Tab
The Authentication tab configures credentials for the target endpoint. The following authentication types are available:
| Auth Type | Fields | Description |
|---|---|---|
| None | - | The request sends no authentication. |
| Basic | Username, Password | The request uses HTTP Basic authentication. |
| Bearer Token | Token | The request includes a Bearer token header. |
| API Key | Header Name, Key | The request sends the key in a custom header. |
For the API Key type, specify the header name (such as
X-API-Key) and the corresponding key value.
Templates Tab
Webhook channels support customizable JSON payload
templates using Go text/template syntax. For template
syntax details, see the
Go template documentation.
The Templates tab provides three template editors:
- The Alert Fire template formats the payload when an alert triggers.
- The Alert Clear template formats the payload when an alert resolves.
- The Reminder template formats the payload for recurring alert reminders.
If left blank, the system uses sensible default templates for each notification type.
Template Variables
Templates have access to the following context variables:
| Variable | Type | Description |
|---|---|---|
AlertID |
integer | The unique alert identifier. |
AlertTitle |
string | The alert rule name. |
AlertDescription |
string | A detailed description of the alert. |
Severity |
string | The severity level: critical, warning, or info. |
SeverityColor |
string | A hex color for the severity. |
SeverityEmoji |
string | An emoji for the severity level. |
Status |
string | The current alert status. |
ServerName |
string | The friendly name of the monitored server. |
ServerHost |
string | The hostname of the monitored server. |
ServerPort |
integer | The port number of the monitored server. |
DatabaseName |
string | The database name; may be empty. |
MetricName |
string | The name of the metric that triggered the alert; may be empty. |
MetricValue |
float | The current metric value; may be empty. |
ThresholdValue |
float | The threshold that was crossed; may be empty. |
Operator |
string | The comparison operator (such as >, <, or =). |
TriggeredAt |
time | The timestamp when the alert fired. |
ClearedAt |
time | The timestamp when the alert cleared; may be empty. |
Duration |
string | A human-readable duration the alert was active. |
Timestamp |
time | The timestamp when the notification was created. |
ReminderCount |
integer | The reminder sequence number. |
NotificationType |
string | The notification type: alert_fire, alert_clear, or reminder. |
ConnectionID |
integer | The internal connection identifier. |
Optional fields such as DatabaseName, MetricName,
MetricValue, ThresholdValue, Operator, and
ClearedAt should use {{if .FieldName}}...{{end}}
conditionals in templates to handle empty values.
Time fields support formatting with the Go time layout
syntax. In the following example, the TriggeredAt
field uses ISO 8601 format:
{{.TriggeredAt.Format "2006-01-02T15:04:05Z07:00"}}
Default Templates
The system provides default templates for each notification type. Administrators can copy and customize these templates.
The following template handles alert fire notifications:
{
"event": "alert_fire",
"alert_id": {{.AlertID}},
"title": "{{.AlertTitle}}",
"description": "{{.AlertDescription}}",
"severity": "{{.Severity}}",
"server": {
"name": "{{.ServerName}}",
"host": "{{.ServerHost}}",
"port": {{.ServerPort}}
},
{{- if .DatabaseName}}
"database": "{{.DatabaseName}}",
{{- end}}
{{- if .MetricName}}
"metric": {
"name": "{{.MetricName}}"
{{- if .MetricValue}},
"value": {{.MetricValue}}
{{- end}}
{{- if .ThresholdValue}},
"threshold": {{.ThresholdValue}}
{{- end}}
{{- if .Operator}},
"operator": "{{.Operator}}"
{{- end}}
},
{{- end}}
"triggered_at":
"{{.TriggeredAt.Format "2006-01-02T15:04:05Z07:00"}}"
}
The following template handles alert clear notifications:
{
"event": "alert_clear",
"alert_id": {{.AlertID}},
"title": "{{.AlertTitle}}",
"server": {
"name": "{{.ServerName}}",
"host": "{{.ServerHost}}",
"port": {{.ServerPort}}
},
"triggered_at":
"{{.TriggeredAt.Format "2006-01-02T15:04:05Z07:00"}}"
{{- if .ClearedAt}},
"cleared_at":
"{{.ClearedAt.Format "2006-01-02T15:04:05Z07:00"}}"
{{- end}},
"duration": "{{.Duration}}"
}
The following template handles reminder notifications:
{
"event": "reminder",
"alert_id": {{.AlertID}},
"title": "{{.AlertTitle}}",
"description": "{{.AlertDescription}}",
"severity": "{{.Severity}}",
"server": {
"name": "{{.ServerName}}",
"host": "{{.ServerHost}}",
"port": {{.ServerPort}}
},
"triggered_at":
"{{.TriggeredAt.Format "2006-01-02T15:04:05Z07:00"}}",
"reminder_count": {{.ReminderCount}}
}
Estate Defaults
Notification channels can be designated as estate defaults. A channel marked as an estate default is active for all monitored servers unless explicitly overridden at a lower level. Administrators toggle the estate default flag in the channel create or edit dialog.
The estate default flag provides a convenient way to enable a channel across the entire monitoring estate without creating individual overrides for each server, cluster, or group.
Channel Overrides
Channel overrides control which notification channels are active at each level of the server hierarchy. The override system uses the following precedence order, from highest to lowest priority:
- Server overrides apply to a specific server connection.
- Cluster overrides apply to all servers in a cluster.
- Group overrides apply to all clusters in a group.
- Estate defaults apply when no override exists.
When the alerter resolves notification channels for a server, the system checks for a server-level override first. If none exists, the system checks the cluster level, then the group level, and finally falls back to the channel's estate default setting.
Managing Overrides
Overrides are managed through the Notification Channels tab in the server, cluster, or group edit dialogs. The override panel displays all enabled channels with their current state:
- Channels without an override inherit the estate default and appear with dimmed styling.
- Channels with an override display at normal opacity with a highlight indicator.
- The Enabled switch toggles the channel on or off at the current scope level.
- The Reset button removes the override, reverting to the inherited value.
Override Resolution Example
Consider a Slack channel marked as an estate default. A group override disables the channel for a development group. A server override re-enables the channel for one server in that group. The alerter resolves notifications as follows:
- Servers in other groups receive notifications because the estate default applies.
- Servers in the development group do not receive notifications because the group override applies.
- The one server with a server override does receive notifications because the server override takes precedence.
REST API
The notification channel REST API provides endpoints
for managing channels, testing delivery, and managing
email recipients. All endpoints require the
manage_notification_channels permission.
The following table lists the available endpoints:
| Method | Endpoint | Description |
|---|---|---|
GET |
/api/v1/notification-channels |
List all channels. |
POST |
/api/v1/notification-channels |
Create a channel. |
GET |
/api/v1/notification-channels/{id} |
Get a channel. |
PUT |
/api/v1/notification-channels/{id} |
Update a channel. |
DELETE |
/api/v1/notification-channels/{id} |
Delete a channel. |
POST |
/api/v1/notification-channels/{id}/test |
Send a test notification. |
GET |
/api/v1/notification-channels/{id}/recipients |
List email recipients. |
POST |
/api/v1/notification-channels/{id}/recipients |
Add a recipient. |
PUT |
/api/v1/notification-channels/{id}/recipients/{rid} |
Update a recipient. |
DELETE |
/api/v1/notification-channels/{id}/recipients/{rid} |
Delete a recipient. |
Channel Override Endpoints
The channel override REST API manages per-scope channel
settings. Write operations require the
manage_notification_channels permission.
The following table lists the available endpoints:
| Method | Endpoint | Description |
|---|---|---|
GET |
/api/v1/channel-overrides/{scope}/{scopeId} |
List channel overrides for a scope. |
PUT |
/api/v1/channel-overrides/{scope}/{scopeId}/{channelId} |
Create or update a channel override. |
DELETE |
/api/v1/channel-overrides/{scope}/{scopeId}/{channelId} |
Remove a channel override. |
The scope parameter accepts server, cluster, or
group. The scopeId parameter is the numeric
identifier for the server connection, cluster, or
group. The PUT request body contains a single field:
| Field | Type | Description |
|---|---|---|
enabled |
boolean | Whether the channel is active at this scope. |
The GET response returns an array of channel override objects:
| Field | Type | Description |
|---|---|---|
channel_id |
integer | The notification channel identifier. |
channel_name |
string | The channel display name. |
channel_type |
string | The channel type (email, slack, mattermost, telegram, webhook). |
description |
string | The channel description; may be null. |
is_estate_default |
boolean | Whether the channel is an estate default. |
has_override |
boolean | Whether an override exists at this scope. |
override_enabled |
boolean | The override enabled state; null when no override exists. |
Related Documentation
- Alert Rules describes the rules that trigger notifications.
- Managing Users and Permissions covers the permissions required for channel management.
- API Reference provides interactive API documentation.