feat: add Discord role mention support to routes

This commit is contained in:
RhenCloud 2026-08-11 15:48:44 +08:00
parent 869d84d78c
commit 76ba2c0a89
17 changed files with 201 additions and 14 deletions

View file

@ -41,7 +41,7 @@ See [Configuration → Web UI](../guide/configuration.md#web-ui) for setup. Admi
- `GET /admin` — Serves the config console HTML
- `GET /admin/api/routes` — Returns `{ "routes": Route[] }`
- `PUT /admin/api/routes` — Body `{ "routes": Route[] }`; validates each route (id pattern, unique id, name, enabled, `groupId`, filters — empty only allowed for `fallback` routes — and platform-aware targets: `target.channelId` for Discord, `target.chatId` for Telegram) and persists to KV `config:routes`. Returns `200 { ok, count }` or `400 { error }` / `401 { error }` / `403 { error }`.
- `PUT /admin/api/routes` — Body `{ "routes": Route[] }`; validates each route (id pattern, unique id, name, enabled, `groupId`, filters — empty only allowed for `fallback` routes — optional `discordRoleIds` (list of role id strings), and platform-aware targets: `target.channelId` for Discord, `target.chatId` for Telegram) and persists to KV `config:routes`. Returns `200 { ok, count }` or `400 { error }` / `401 { error }` / `403 { error }`.
## Health Check

View file

@ -75,6 +75,7 @@ There are **no default routes** — each route must define its own target. If no
"groupId": "my-group",
"fallback": false,
"stop": false,
"discordRoleIds": ["111111111111111111"],
"filters": [
{ "type": "event", "match": "push" },
{ "type": "repo", "match": "org/repo", "exclude": false }
@ -91,14 +92,33 @@ There are **no default routes** — each route must define its own target. If no
Each entry of `targets` is a push destination, so one route can forward to several channels at once (e.g. a Discord channel **and** a Telegram group). `target.platform` selects the platform: `discord` (default) or `telegram`. For **Discord**, `target.channelId` is required (a thread in `target.threadId` is optional). For **Telegram**, `target.chatId` (the group/supergroup chat id, e.g. `-1001234567890`) is required and `target.topicId` (the `message_thread_id` of a topic, equivalent of a Discord thread) is optional. There is no fallback to a default channel.
### Discord Role Mentions
Set `discordRoleIds` on a route to ping one or more Discord roles (身份组) whenever that route fires. The mention (`<@&roleId>`) is prepended to the message content of every **Discord** target of the route; Telegram targets ignore this field. Mentions only trigger notifications when the bot has the `Mention Everyone` permission (or the role is marked mentionable), and the bot must be able to see the role.
```json
{
"id": "release-notify",
"name": "Notify on Release",
"enabled": true,
"groupId": "default",
"discordRoleIds": ["111111111111111111", "222222222222222222"],
"filters": [{ "type": "event", "match": "release" }],
"targets": [{ "platform": "discord", "channelId": "REQUIRED_CHANNEL_ID" }]
}
```
You can add role ids in the admin console under _Discord role mentions_.
Other route fields:
| Field | Type | Required | Description |
| ---------- | ------- | -------- | ----------------------------------------------------------------------------------------------- |
| `groupId` | string | Yes | Id of the [group](#groups) this route belongs to |
| `fallback` | boolean | No | When `true`, fires only if no non-fallback route matched the event; its own filters are ignored |
| `stop` | boolean | No | When `true` and this route matches, no further routes are evaluated for this event |
| `lang` | string | No | Message language override for this route (e.g. `en`, `zh`); defaults to the global setting |
| Field | Type | Required | Description |
| ---------------- | -------- | -------- | ----------------------------------------------------------------------------------------------- |
| `groupId` | string | Yes | Id of the [group](#groups) this route belongs to |
| `fallback` | boolean | No | When `true`, fires only if no non-fallback route matched the event; its own filters are ignored |
| `stop` | boolean | No | When `true` and this route matches, no further routes are evaluated for this event |
| `lang` | string | No | Message language override for this route (e.g. `en`, `zh`); defaults to the global setting |
| `discordRoleIds` | string[] | No | Discord role ids to ping when this route fires; applied to Discord targets only |
### Custom Route Example

View file

@ -41,7 +41,7 @@ https://your-worker.workers.dev
- `GET /admin` — 提供配置控制台 HTML
- `GET /admin/api/routes` — 返回 `{ "routes": Route[] }`
- `PUT /admin/api/routes` — 请求体为 `{ "routes": Route[] }`校验每条路由id 格式、唯一 id、name、enabled、groupId、过滤器、平台感知的 targetsDiscord 需 `target.channelId`Telegram 需 `target.chatId`)并持久化到 KV `config:routes`。返回 `200 { ok, count }``400 { error }` / `401 { error }` / `403 { error }`
- `PUT /admin/api/routes` — 请求体为 `{ "routes": Route[] }`校验每条路由id 格式、唯一 id、name、enabled、groupId、过滤器、可选的 `discordRoleIds`(身份组 id 字符串列表)、平台感知的 targetsDiscord 需 `target.channelId`Telegram 需 `target.chatId`)并持久化到 KV `config:routes`。返回 `200 { ok, count }``400 { error }` / `401 { error }` / `403 { error }`
## 健康检查

View file

@ -75,6 +75,7 @@ WebHooker 内置了位于 `/admin` 的配置控制台,可在浏览器中管理
"groupId": "my-group",
"fallback": false,
"stop": false,
"discordRoleIds": ["111111111111111111"],
"filters": [
{ "type": "event", "match": "push" },
{ "type": "repo", "match": "org/repo", "exclude": false }
@ -91,14 +92,33 @@ WebHooker 内置了位于 `/admin` 的配置控制台,可在浏览器中管理
`targets` 数组的每一项是一个推送目标,因此一条路由可同时转发到多个频道(例如同时发到 Discord 频道 **和** Telegram 群组)。`target.platform` 选择推送目标:`discord`(默认)或 `telegram`。**Discord** 需 `target.channelId``target.threadId` 可选的子区);**Telegram** 需 `target.chatId`(群组/超级群组聊天 id`-1001234567890``target.topicId`(话题的 `message_thread_id`,相当于 Discord 的子区)可选。不存在默认频道回退。
### Discord 身份组提醒
在路由上设置 `discordRoleIds`,当该路由触发时会 @提醒ping一个或多个 Discord 身份组。`<@&roleId>` 形式的提醒会拼接到该路由所有 **Discord** 目标的消息正文开头Telegram 目标会忽略此字段。只有在机器人拥有 `Mention Everyone` 权限(或该身份组被标记为可被提及 mentionable且机器人能看到该身份组时提醒才会真正触发通知。
```json
{
"id": "release-notify",
"name": "发布时提醒",
"enabled": true,
"groupId": "default",
"discordRoleIds": ["111111111111111111", "222222222222222222"],
"filters": [{ "type": "event", "match": "release" }],
"targets": [{ "platform": "discord", "channelId": "必填频道ID" }]
}
```
也可以在管理控制台的“Discord 身份组提醒”中配置。
其他路由字段:
| 字段 | 类型 | 必需 | 说明 |
| ---------- | ------- | ---- | ---------------------------------------------------------------------- |
| `groupId` | string | 是 | 该路由所属[分组](#分组)的 id |
| `fallback` | boolean | 否 | 为 `true` 时,仅当没有其它路由匹配该事件时才发送,其自身过滤器会被忽略 |
| `stop` | boolean | 否 | 为 `true` 且该路由匹配时,停止评估后续路由 |
| `lang` | string | 否 | 该路由的消息语言覆盖(如 `en``zh`),默认跟随全局设置 |
| 字段 | 类型 | 必需 | 说明 |
| ---------------- | -------- | ---- | ---------------------------------------------------------------------- |
| `groupId` | string | 是 | 该路由所属[分组](#分组)的 id |
| `fallback` | boolean | 否 | 为 `true` 时,仅当没有其它路由匹配该事件时才发送,其自身过滤器会被忽略 |
| `stop` | boolean | 否 | 为 `true` 且该路由匹配时,停止评估后续路由 |
| `lang` | string | 否 | 该路由的消息语言覆盖(如 `en``zh`),默认跟随全局设置 |
| `discordRoleIds` | string[] | 否 | 该路由触发时要在 Discord 目标中 @提醒的身份组 id |
### 自定义路由示例