OneUptime Discord 集成实战:用内置工作流把事件(Incident)实时推送到 Discord 频道
【免费下载链接】oneuptimeComplete open-source monitoring and observability platform.项目地址: https://gitcode.com/GitHub_Trending/on/oneuptime
本文基于 OneUptime 官方文档中的 Discord 集成指南(integrations/discord.md)编写,完整讲解如何把事件更新(Incident)推送到 Discord 频道:创建 Webhook、配置全局变量、搭建工作流,并用 API 组件替代方案实现更丰富的消息格式。结合仓库中 Discord 工作流组件的元数据定义、执行实现与内置工作流模板源码,还会说明该集成的底层调用链、URL 校验与防重定向等安全细节。
1. 集成定位与数据流
OneUptime 内置了一个Discord工作流组件,因此将事件更新推送到 Discord 是平台中最快搭建的集成之一。
该集成是**出站(outgoing)**方向:OneUptime 通过一条 Discord 入站 Webhook URL 向目标频道发消息,Discord 侧不需要开放任何回调接口给 OneUptime。
OneUptime Incident → On Create ──► Discord component ──► message in your channel即:当项目中的一个事件被创建时,触发器(Incident → On Create)驱动工作流执行,Discord 组件携带消息文本向 Webhook 地址发起 POST 请求,消息最终出现在指定的频道里。
2. 第一步:在 Discord 中创建入站 Webhook
- 打开 Discord,进入目标频道,选择Edit Channel → Integrations → Webhooks;
- 点击New Webhook,为其命名(例如
OneUptime),选择消息投递的目标频道,然后复制生成的 Webhook URL。
Webhook URL 形如https://discord.com/api/webhooks/<id>/<token>。这条 URL 本身就是访问凭据,拿到 URL 的人即可向该频道发消息,因此要按机密信息对待。
3. 第二步:保存 Webhook URL 为全局变量(可选但推荐)
- 在 OneUptime 中进入Arbeitsabläufe(工作流)→ Globale Variablen(全局变量)→ 创建;
- 将变量命名为
DISCORD_WEBHOOK_URL,粘贴 Webhook URL,并勾选Is Secret(机密)。
把 URL 存成变量有两个直接好处(原文档原文):
- 多个工作流可以复用同一条 URL,不必逐处粘贴;
- 轮换 Webhook 时只需改一处。
配合Is Secret标记,该值不会以明文形式出现在工作流展示中,避免凭据泄露到日志或截图里。
4. 第三步:创建工作流
- 打开工作流 → 创建工作流,命名为
Incidents → Discord,进入Builder; - 添加一个Vorfall(Incident)触发器,动作选On Create(创建时),将其命名为
Incident; - 添加一个Discord组件并连接到触发器上,配置两个必填参数:
- Webhook URL:填
{{variable.DISCORD_WEBHOOK_URL}}(引用全局变量),也可以直接粘贴 URL; - Message(消息文本):例如
🔴 New incident: {{Incident.title}}\n{{Incident.description}}
- Webhook URL:填
- 保存并启用工作流,随后创建一个测试事件,消息就会出现在 Discord 频道中。
组件参数对照源码
文档中的两个字段与组件元数据定义一一对应。在 Discord 组件元数据 中,该组件注册为 “Send Message to Discord”(分类 Discord),参数定义如下:
| 参数 ID | 名称 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
webhook-url | Discord Incoming Webhook URL | URL | 是 | 标记为isSensitive: true(敏感字段),占位示例为https://discord.com/api/webhooks/1234567890/XXXX... |
text | Message Text | LongText | 是 | 实际发送的消息内容 |
组件只有一个输入端口in,两个输出端口:success(消息发送成功后执行后续节点)与error(失败时走错误分支),返回值error用于承载失败原因。也就是说,在工作流画布里你可以把“发送成功”和“发送失败”接成两条不同的后续处理链路。
执行实现与两条安全设计
执行逻辑位于 SendMessageToChannel,核心流程为:
- 校验
text参数存在,否则直接走错误分支并抛出 “Discord message not found”; - 通过
IncomingWebhookUtils.getPinnedWebhookUrl对webhook-url做主机固定(host pinning)校验,允许域名为 DISCORD_WEBHOOK_DOMAINS 中定义的两个域:discord.com与discordapp.com; - 以
Content-Type: application/json向 Webhook 发起 POST,Body 为{ "content": <text> }(对应 Discord 执行 Webhook 的官方接口); - 请求显式设置
doNotFollowRedirects: true——源码注释解释得很直白:主机已经被固定,跟随重定向会把消息(以及 Webhook 凭据)交还给重定向目标控制者,因此拒绝跟随后端重定向; - 成功则从
success端口继续,遇到HTTPErrorResponse或异常则携带错误信息从error端口走,并可通过返回值error记录到日志节点。
这两点(域名白名单校验 + 禁止跟随重定向)意味着:即使有人在工作流中填写了伪造的 Discord 风格地址或恶意跳转地址,组件也会拒绝执行,而不是把凭据发往任意主机。
5. 内置模板:一键导入“事件创建即通知 Discord”工作流
从源码结构看,OneUptime 在工作流模板库中已经内置了与本文档完全对应的现成模板。在 工作流模板定义 中,模板incident-created-discord(名称 “Notify Discord on new incident”)声明了本地变量discordWebhookUrl(提示文案指引用户去 Discord 的 Channel Settings → Integrations → Webhooks 复制 URL),其图形结构为:
incident-on-create-1:事件创建触发器;discord-1:discord-send-message-to-channel组件,参数引用{{local.variables.discordWebhookUrl}},消息文本自动拼接事件编号、标题、严重级与状态:
🚨 **Incident {{...model.incidentNumberWithPrefix}} declared** **Title:** {{...model.title}} **Severity:** {{...model.incidentSeverity.name}} **State:** {{...model.currentIncidentState.name}}log-delivery-failed:挂在 Discord 组件的error端口上,输出❌ Discord could not deliver the incident notification: {{...returnValues.error}},用于把投递失败记入日志。
如果你不需要自定义消息格式,直接导入这个模板、填好变量即可,省去了手工连线的步骤。
6. 替代方案:用 API 组件手动调用 Discord Webhook
如果不想使用专用组件,一个API块也能达到同样效果:
- Method:
POST - URL:
{{variable.DISCORD_WEBHOOK_URL}} - Headers:
Content-Type: application/json - Body:
{ "content": "New incident: {{Incident.title}}" }
这个方式在需要用到 Discord 更丰富的Embeds(嵌入式卡片)时尤其有用——只需在 Body 中追加embeds数组(Discord 的 Webhook 接口支持embeds字段来构造带标题、描述、颜色、字段列表的卡片式消息)。需要注意的取舍是:API 块是通用 HTTP 请求,不具备专用组件内置的域名白名单校验,因此 URL 务必通过变量引用、并保证只指向真实的 Discord Webhook 地址。
7. 进阶技巧
- 按严重级过滤:使用**条件(Condition)**节点,在 Discord 块之前按
{{Incident.incidentSeverity.name}}分支,只对特定严重级(例如仅严重/致命)发通知,避免频道被低优先级事件刷屏; - 覆盖事件全生命周期:再为Incident → On Update添加一条工作流,把“已确认(Acknowledged)”“已解决(Resolved)”等状态变更也推送到同一频道,与 On Create 消息形成完整的事件时间线。
8. 参考资料与延伸阅读
- 集成总览(出站集成模式):integrations/index.md
- Telegram 集成(同样的 Webhook 原理):integrations/telegram.md
- 工作流组件参考(含 Discord 组件说明):workflows/components.md
- 工作流变量与触发器:workflows/variables.md、workflows/triggers.md
- 组件元数据定义:Common/Types/Workflow/Components/Discord.ts
- 组件执行实现:Common/Server/Types/Workflow/Components/Discord/SendMessageToChannel.ts
- Webhook 域名白名单与 URL 固定校验:Common/Server/Types/Workflow/Components/IncomingWebhookUtils.ts
- 内置“事件通知 Discord”模板:Common/Types/Workflow/Templates.ts
适用前提说明:本文基于当前仓库中的文档与源码(组件 ID 为
discord-send-message-to-channel,Webhook 白名单域为discord.com/discordapp.com)。UI 中的菜单名称可能随版本与界面语言略有差异,以实际控制台为准。
【免费下载链接】oneuptimeComplete open-source monitoring and observability platform.项目地址: https://gitcode.com/GitHub_Trending/on/oneuptime
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考