Skip to content

Fan Out

sarmakska edited this page May 31, 2026 · 1 revision

Fan-Out

Besides email, the service can post each delivered event to Slack and Telegram. Both channels are best-effort: a fan-out failure is logged but never fails or retries the job, because email is the source of truth and re-sending the email to recover a chat notification would spam the inbox. Fan-out runs only after the email send succeeds.

Slack

Set SLACK_WEBHOOK_URL to an incoming webhook URL:

SLACK_WEBHOOK_URL=https://hooks.slack.com/services/T.../B.../...

Get one from Slack, Apps, Incoming Webhooks, Add to channel.

The message is posted as Slack Block Kit: a header block with the subject, a section block with the body converted to Slack mrkdwn (bold, headings and links translated), and a context block naming the source. The body is truncated to fit Slack's block limits.

Telegram

Both variables must be set for Telegram fan-out to activate:

TELEGRAM_BOT_TOKEN=123456:ABC-DEF...
TELEGRAM_CHAT_ID=123456789

Get a bot token

  1. Message @BotFather on Telegram.
  2. Send /newbot and follow the prompts.
  3. Copy the token it gives you into TELEGRAM_BOT_TOKEN.

Get a chat id

  1. Add the bot to the target chat or start a direct message with it.
  2. Resolve the chat id, for example by messaging @userinfobot, or by reading https://api.telegram.org/bot<token>/getUpdates after sending the bot a message.
  3. Put the id into TELEGRAM_CHAT_ID.

The message is sent with parse_mode: Markdown: a bold subject followed by the plain-text body, with characters that break Telegram's parser escaped, and link previews disabled.

How fan-out fits the flow

graph LR
  W[Worker delivers email] -->|ok| E[Resend]
  W -->|ok| S{Slack set?}
  W -->|ok| T{Telegram set?}
  S -->|yes| SL[Slack Block Kit]
  T -->|yes| TG[Telegram sendMessage]
Loading

Fan-out calls run in parallel and their failures are swallowed after a warning. The job is considered delivered as soon as the email send succeeds.

Verifying fan-out

Send a test webhook and watch stdout. A successful fan-out is silent; a failure logs Slack fan-out failed: or Telegram fan-out failed: with the reason. The notifier is fully injectable, so the test suite covers both channels, including the rule that both Telegram variables must be present before it fires.

Clone this wiki locally