Skip to content

Slack

Slack works with pg_relay through the webhook transport, posting to Slack's chat.postMessage Web API with a bot token. This is the transport's home ground: a JSON API pg_relay has no native knowledge of, driven entirely by pg_relay_notifier's configuration — the Processor needs zero Slack-specific code.

One-time Slack setup

Slack doesn't let software post with a personal login; you create a small Slack app in your workspace and Slack issues it a bot token (a credential starting xoxb-):

  1. At api.slack.com/appsCreate New AppFrom scratch → name it (e.g. pg-relay) in your workspace.
  2. OAuth & Permissions → Bot Token Scopes → add chat:write — "post messages" is the only permission pg_relay needs.
  3. Install to WorkspaceAllow, then copy the Bot User OAuth Token (xoxb-...). Treat it like a password; the same page can regenerate it if it ever leaks.
  4. In the channel notifications should land in, invite the app: /invite @pg-relay. A bot that isn't a channel member gets not_in_channel on every post.
  5. Note the channel's ID (channel details → About tab, C0XXXXXXX) — more robust than the channel's name in API calls.

Export the token on the Processor host (for a service, in its environment file — see Keeping Secrets Out of the Database):

export SLACK_BOT_TOKEN=xoxb-...

Profile and message

// profile
{
  "url": "https://slack.com/api/chat.postMessage",
  "auth": {"style": "bearer_header", "secret": "_env:SLACK_BOT_TOKEN"},
  "timeout_seconds": 30
}

// message — Slack's own request shape, sent verbatim
{
  "channel": "C0XXXXXXX",
  "text": "disk alert: volume is filling"
}

Because message is sent verbatim, anything chat.postMessage accepts works — text uses Slack's mrkdwn formatting, and richer layouts can supply a Block Kit blocks array alongside it. Email concepts (subject, cc/bcc, attachments) have no chat.postMessage equivalent and simply don't appear.

Interpreting the response

Slack has one famous quirk: it answers HTTP 200 for both success and failure, distinguishing in the JSON body — so the body, not the status code, decides. Have classify_webhook_response treat:

  • 200 with body "ok": true as sent — the body's ts is Slack's id for the posted message; return it as the provider reference.
  • 200 with body "ok": false as failed — the body's error field names the cause and makes ideal detail text: not_in_channel (invite the bot), channel_not_found (wrong channel ID), invalid_auth (bad or revoked token), msg_too_long.
  • 429, any 5xx, and http_status = 0 (no response) as retry — Slack rate-limits posting to roughly one message per second per channel, so 429 on a burst of notifications is routine and self-heals through the retry chain (the lower-cased retry-after header says how long Slack asked for).

Things Slack enforces

The chat:write scope only lets the bot post to channels it is a member of — the /invite in setup step 4 is functional, not cosmetic. And since a Slack "recipient" is a channel rather than an address, point separate notification profiles (or messages) at separate channel IDs to fan different event types into different channels.

Pinning a profile to one channel

When a profile should only ever post to one channel — an alerts profile that must never leak into a general channel, or vice versa — make it non-negotiable with body_merge instead of trusting every producer to pass the right id:

// profile
{
  "url": "https://slack.com/api/chat.postMessage",
  "auth": {"style": "bearer_header", "secret": "_env:SLACK_BOT_TOKEN"},
  "body_merge": {"channel": "C0XXXXXXX"}
}

The Processor overlays the profile's channel onto the message immediately before sending, unconditionally replacing whatever the producer supplied — a wrong id, a stale copy-paste, or a deliberate redirect all land in the pinned channel anyway. Channel routing becomes a decision the profile owner makes once, not one every call site re-makes. Use an _env: reference as the value ("_env:SLACK_ALERT_CHANNEL") when the target channel differs between environments while the profile JSON stays identical.


Continue to Formatting Slack Messages — mrkdwn, Block Kit alert layouts, and deep links into complete guides.