Skip to content

Slack

The Slack notifier posts to a channel through a Slack incoming webhook.

[notifiers.slack-ops]
type = "slack"
webhook_url = "${SLACK_OPS_URL}"
channel = "#ops" # optional
Key Required What it does
webhook_url yes The webhook URL. Keep it out of the file; see Storing the secret.
channel no Post somewhere other than the webhook’s default. Starts with # (channel) or @ (user).
template_path no A Go template file that replaces the built-in message.
  1. Open api.slack.com/apps and create an app (or pick one) in the workspace you want messages in.
  2. Under Incoming Webhooks, turn the feature on.
  3. Click Add New Webhook to Workspace, pick the channel (for example #ops), and allow it.
  4. Copy the URL. It looks like https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX.

Anyone with the URL can post to your channel, so treat it as a secret. Without channel, messages go to the channel you picked in step 3.

To send different tasks to different channels with one webhook, use "slack-ops:#deploys" in notify; see One channel, several destinations.

Each event is one Block Kit message:

❌ backup-postgres failed
Exited with code 1 after 0.3s.
Triggered via the REST API · 14 May, 17:11.
Error: connection refused
dial tcp 127.0.0.1:5432: connect:
connection refused
[ View full run ]
from runwisp · bright-falcon
  • The last lines of output appear for failures and timeouts, when there is a log.
  • The View full run button appears only when external_url is set.
  • The footer names the daemon that sent it.

Every kind of event uses the same layout; only the emoji, verb, and sentence change.

Point template_path at your own Go template. Start from the built-in slack.tmpl.json, which has the Block Kit layout and the sentence for each event. The template gets the whole event (task name, run id, exit code, end reason, time, output tail) and these helpers:

  • Event: statusEmoji, statusVerb, humanTime, humanDuration, runDuration, triggerPhrase, eventSentence, eventTrigger, linkLabel, runURL, taskURL, outputTail, fingerprint, and emoji (a Slack emoji code for the event’s severity).
  • Escaping: jsonStr (for a JSON string), htmlEsc (for HTML), and tgEscape (for Telegram HTML).
  • Text: upper, lower, trim, and timeRFC (an RFC 3339 timestamp).

Every template type gets the same helpers.

  • A missing or empty webhook_url.
  • A channel, or a slack-ops:<target> override, that doesn’t start with # or @.