From 76ba2c0a89166bcd5edd4697298b66f3849266a6 Mon Sep 17 00:00:00 2001 From: RhenCloud Date: Tue, 11 Aug 2026 15:48:44 +0800 Subject: [PATCH] feat: add Discord role mention support to routes --- AGENTS.md | 1 + README.md | 14 ++++++++++ README.zh.md | 14 ++++++++++ admin/components/RouteCard.vue | 1 + admin/components/RouteEditor.vue | 20 ++++++++++++++ admin/composables/useI18n.ts | 9 +++++++ admin/types.ts | 1 + config.example.yaml | 16 +++++++++++ docs/api/overview.md | 2 +- docs/guide/configuration.md | 32 +++++++++++++++++----- docs/zh/api/overview.md | 2 +- docs/zh/guide/configuration.md | 32 +++++++++++++++++----- src/__tests__/discord.test.ts | 46 ++++++++++++++++++++++++++++++++ src/core/dispatch.ts | 3 +++ src/drivers/discord/render.ts | 4 +++ src/types.ts | 11 ++++++++ src/web/admin-routes.ts | 7 +++++ 17 files changed, 201 insertions(+), 14 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 8f3b88f..ad64ac8 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -81,6 +81,7 @@ src/__tests__/ # bun test unit tests (webhook, formatter, discord, te - Verify Telegram webhook calls (X-Telegram-Bot-Api-Secret-Token when configured) - Filter events by: event type, repo name, actor, action, branch, keyword (regex supported) - Filter routes by group owner restriction (`Group.owners`) and skip fallback routes whenever a regular route matched; stop evaluating further routes when a matched route has `stop: true` +- Mention Discord roles on route trigger: route-level `discordRoleIds` are rendered as `<@&id>` into the Discord message `content` (Telegram targets ignore the field) - Format 28 event types as platform-neutral messages (Discord embeds + Telegram HTML) - Route messages to Discord channels/threads and Telegram chats/topics via REST - Edit already-sent messages in place for `workflow_run` progress (stable `updateKey`, KV `msg:*` tracking) diff --git a/README.md b/README.md index 1e359a9..6f5436f 100644 --- a/README.md +++ b/README.md @@ -90,6 +90,20 @@ Routes are stored in KV (`config:routes` as JSON). There are **no default routes `target.platform` selects the push target: `discord` (default) or `telegram`. Discord targets require `target.channelId` (optional `threadId` for a thread); Telegram targets require `target.chatId` (optional `topicId` for a topic). The legacy singular `target` field is still migrated automatically. There is no fallback to a default channel. +Set `discordRoleIds` on a route to ping Discord roles (身份组) whenever it fires: + +```json +{ + "id": "release-notify", + "name": "Notify on Release", + "enabled": true, + "groupId": "default", + "discordRoleIds": ["111111111111111111"], + "filters": [{ "type": "event", "match": "release" }], + "targets": [{ "platform": "discord", "channelId": "CHANNEL_ID" }] +} +``` + Routes belong to **groups** (KV `config:groups`) that scope admin access and can restrict which org/user events flow in. See `config.example.yaml` and `docs/guide/configuration.md` for the full schema. ### Web UI (`/admin`) diff --git a/README.zh.md b/README.zh.md index 6722c33..aeadfaf 100644 --- a/README.zh.md +++ b/README.zh.md @@ -90,6 +90,20 @@ npx wrangler dev # 启动本地开发服务器 `target.platform` 选择推送目标:`discord`(默认)或 `telegram`。Discord 目标需 `target.channelId`(可选 `threadId` 指向子区);Telegram 目标需 `target.chatId`(可选 `topicId` 指向话题)。旧的单数 `target` 字段仍会被自动迁移。不存在默认频道回退。 +在路由上设置 `discordRoleIds`,可在该路由触发时 @提醒 Discord 身份组: + +```json +{ + "id": "release-notify", + "name": "发布时提醒", + "enabled": true, + "groupId": "default", + "discordRoleIds": ["111111111111111111"], + "filters": [{ "type": "event", "match": "release" }], + "targets": [{ "platform": "discord", "channelId": "频道ID" }] +} +``` + 路由隶属于**分组**(KV `config:groups`),分组用于限定管理权限,并可限制哪些组织/用户的事件流入。完整模式见 `config.example.yaml` 与 `docs/zh/guide/configuration.md`。 ### Web 控制台(`/admin`) diff --git a/admin/components/RouteCard.vue b/admin/components/RouteCard.vue index c0c825b..10781d9 100644 --- a/admin/components/RouteCard.vue +++ b/admin/components/RouteCard.vue @@ -18,6 +18,7 @@ > {{ t("route.fallback") }} {{ t("route.stop") }} + @roles
+
+ + +
{{ t("routeEditor.discordRolesHint") }}
+