feat: add Slack and Telegram adapters with adapter-owned routing#16
feat: add Slack and Telegram adapters with adapter-owned routing#16Royal-lobster merged 11 commits intomainfrom
Conversation
Covers adapter-owned routing (Approach A), message formatting, rate limits, breaking changes to RoutingConfig/FormattedAlert, and migration path from global routing to per-adapter config. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
BREAKING CHANGE: RoutingConfig, Router, and webhookUrl/pings on FormattedAlert are removed. Routing is now configured per-adapter via channels/tags/mentions constructor options. DiscordAdapter now accepts channels, tags, and mentions directly. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Supports per-level channel routing via webhook URLs, tag-based routing, mentions, and 429 retry with Retry-After header. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Supports per-level forum topic routing, tag-based topic routing, @username mentions, and 429 retry with body-based retry_after. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Code Review
This pull request implements Slack and Telegram adapters for the alert logger and refactors the routing system to be adapter-owned, removing the global Router and RoutingConfig. Core types like FormattedAlert were simplified by removing webhookUrl and pings to support this decentralized routing. Feedback focuses on aligning the new formatters with design specifications, such as ensuring the Slack context block is present in all alert phases and correcting emoji inconsistencies in the Telegram formatter. The reviewer also identified code duplication in the Telegram formatter and suggested formatting improvements for Slack fields and Telegram mentions. Additionally, several test files were flagged for violating project rules by explicitly importing Vitest globals.
- Slack formatter: context block now appears in all phases, not just onset - Slack formatter: field format changed to inline '*key:* value' - Telegram formatter: info emoji changed from green to blue circle per design spec - Telegram formatter: footer moved outside switch to reduce duplication - Telegram adapter: mentions use double newline separator for readability Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
CI was failing because new files used tabs instead of spaces (biome.json specifies indentStyle: "space", indentWidth: 2). Also fixes multi-line function signatures and import ordering. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Telegram formatter: truncate stack traces before wrapping in <code> tags so HTML stays balanced when hitting the 4096 char limit. Drop code blocks entirely if message is still over limit. - Telegram adapter: re-enforce 4096 limit after prepending mentions to prevent sendMessage 400 errors on near-limit alerts. - Slack formatter: sanitize alert content in mrkdwn blocks to prevent mention injection (<@u123>, <!channel>, @everyone etc), matching the sanitization already present in the Discord formatter. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Summary
RoutingConfiginto per-adapter constructor options (channels,tags,mentions). RemovesRouterclass,webhookUrl/pingsfromFormattedAlert.SlackAdapter— Incoming Webhooks with Block Kit formatting, per-level channel routing, mention support, 429 retryTelegramAdapter— Bot API with HTML formatting, per-level forum topic routing, tag-to-topic mapping, @username mentions, 429 retryMigration
Move
routing.channels,routing.tags, androuting.pingsinto adapter constructors:Usage
Test plan
🤖 Generated with Claude Code