Skip to main content
RStack notifies your team where they already are. One event fans out to every channel you configure; a webhook failure never fails a run.

What gets notified

  • Run started (sdlc_start)
  • Task validated — pass/fail with summary and attempt count
  • A rich task execution report — tool calls, guardrail hits, memory actions, checks
  • Human approval recorded (sdlc_approve)
  • A gate blocking — the moment work is blocked on an approval, every channel is paged

Configure — environment variables

ChannelVariables
SlackRSTACK_SLACK_WEBHOOK (Teams/Discord URLs are auto-routed too)
TeamsRSTACK_TEAMS_WEBHOOK
DiscordRSTACK_DISCORD_WEBHOOK
TelegramRSTACK_TELEGRAM_BOT_TOKEN + RSTACK_TELEGRAM_CHAT_ID
WhatsAppRSTACK_WHATSAPP_TOKEN + RSTACK_WHATSAPP_PHONE_ID + RSTACK_WHATSAPP_TO

Configure — .rstack/notifications.json

{
  "channels": {
    "slack":    { "webhook": "https://hooks.slack.com/services/..." },
    "teams":    { "webhook": "https://yourorg.webhook.office.com/..." },
    "discord":  { "webhook": "https://discord.com/api/webhooks/..." },
    "telegram": { "bot_token": "123456:ABC...", "chat_id": "-1001234567890" },
    "whatsapp": { "token": "EAAB...", "phone_number_id": "1055...", "to": "15551234567" }
  }
}
Environment variables win over the file for the same channel.

Verify in seconds

npx rstack-agents notify          # show which channels are configured
npx rstack-agents notify --test   # send a test message to every channel
Per-channel results are printed; exit code is non-zero if any channel fails.

Channel notes

  • Slack — incoming webhook; native Block Kit payloads.
  • Teams — incoming webhook (connector); converted to MessageCard.
  • Discord — webhook; converted to embeds.
  • Telegram — create a bot with @BotFather, add it to your chat/group, use the bot token + chat id. Rendered as plain text.
  • WhatsApp — Meta WhatsApp Business Cloud API: a Meta app with the WhatsApp product, a system-user token, the sender phone-number id, and the recipient number in international format (no +).

For adapter authors

import { notifyAll, hasConfiguredChannels, formatSlackStageMessage } from 'rstack-agents';

if (hasConfiguredChannels({ projectRoot })) {
  await notifyAll(formatSlackStageMessage(runId, stageId, 'PASS', { message }), { projectRoot });
}
notifyAll never throws — it returns [{ channel, ok, detail }].