OneUptime 状态页订阅者与通知机制:五种订阅通道、双重确认与公告计划的全景解析
2026/9/17 23:26:17 网站建设 项目流程

OneUptime 状态页订阅者与通知机制:五种订阅通道、双重确认与公告计划的全景解析

【免费下载链接】oneuptimeComplete open-source monitoring and observability platform.项目地址: https://gitcode.com/GitHub_Trending/on/oneuptime

本文围绕 OneUptime 状态页的订阅者体系与通知体系展开:状态页支持的五种订阅通道及其开启条件、访客订阅页的表单构成、邮箱双重确认(double opt-in)与退订流程、订阅者可自定义的资源与事件类型范围、通知模板定制,以及公告(Announcement)的创建向导、时间窗口计划规则与 SSRF 安全防护。读完后,你可以完整配置一个可运营的状态页订阅与通知方案,并能从数据模型层面理解每个开关字段的实际作用。

状态页订阅者与公告:两条互补的信息通道

状态页是用户主动来访问的页面,而订阅者是希望"不用来也能收到"的那批人——他们一次性留下邮箱、电话、Slack Webhook 或 HTTP 端点,之后状态更新会主动推送给他们。

公告是另一半任务。监控可以告诉访客"checkout 正在返回 500 错误",但监控无法告诉他们"周六要迁移数据库""某个第三方供应商今天状态不佳",或者"他们昨天看的那起事件已经彻底关闭了"。公告是覆盖这些检查项无法感知之事的自由文本通道,且发布到同一份订阅者列表上。本文同时覆盖这两个主题:五种订阅通道、访客如何订阅、订阅者可以自选哪些内容、双重确认与退订的完整流程,以及公告的撰写、计划与模板化保存。

五种订阅通道与开启条件

一个状态页支持五种订阅通道,每种通道在状态页中都有自己独立的配置项。进入状态页 → 你的页面 → 订阅者 → 订阅设置,可以看到五个开关:

通道字段名默认状态
邮箱订阅者enableEmailSubscribers开启
SMS 订阅者enableSmsSubscribers关闭
Slack 订阅者enableSlackSubscribers关闭
Microsoft Teams 订阅者enableMicrosoftTeamsSubscribers关闭
Webhook 订阅者enableWebhookSubscribers关闭

从源码结构看,这些字段定义在状态页数据模型 StatusPage.ts 上,并在 StatusPageService.ts 等服务层被消费,与文档描述的"邮箱默认开、其余默认关"一致。仓库中还存在一条专门删除早期"总开关"列enableSubscribers的数据库迁移 RemoveDeprecatedEnableSubscribersFromStatusPage:迁移注释说明该旧字段早已被"显示订阅页 + 按通道开关"的方案取代(superseded byshowSubscriberPageOnStatusPage+ the per-channelenableEmailSubscribers/enableSmsSubscribers/enableSlackSubscribersflags),这也印证了当前多通道开关的设计是最终形态。

每个通道还会在状态页的侧边菜单"订阅者"下拥有独立的列表页:邮箱订阅者SMS 订阅者Slack 订阅者MS Teams 订阅者Webhook 订阅者。你可以在这些列表中查看谁已注册、手动添加订阅者,或在某个订阅者条目上留下internalNote(内部备注)。

仅开启一个开关是不够的。状态页导航栏中的"订阅"入口,只有在显示订阅页面showSubscriberPageOnStatusPage)打开、并且至少一个通道被启用时才会出现。如果你开启了邮箱订阅但关闭了"显示订阅页面",访客将没有任何路径到达订阅表单。

同样的五个开关还会出现在高级设置页的"订阅设置"卡片中,与"显示订阅页面"并排展示——底层是相同的字段。建议固定在专用的"订阅设置"页操作,因为订阅配置的其他部分都集中在那里。

访客在订阅页上看到什么

订阅页(Abonner)有一个子菜单,每个已启用的通道对应一个标签页——邮箱SMSSlackMS TeamsWebhooks,分别对应路由/subscribe/email/subscribe/sms/subscribe/slack/subscribe/microsoft-teams/subscribe/webhooks。每个标签页只索要它需要的信息:

  • 邮箱——标题"通过邮箱订阅",一个字段"你的邮箱",占位符为abonnent@firma.dk
  • SMS——标题"通过 SMS 订阅",一个字段"你的电话号码",占位符为+4512345678
  • Slack——标题"通过 Slack 订阅",包含Slack 工作区名称(用于校验)和Slack 入站 Webhook URL,占位符https://hooks.slack.com/services/...
  • MS Teams——标题"通过 Microsoft Teams 订阅",包含Microsoft Teams 工作区名称Microsoft Teams 入站 Webhook URL,占位符https://outlook.office.com/webhook/...
  • Webhooks——标题"通过 Webhook 订阅",一个字段Webhook URL。每次状态页事件发生时都会向该地址发送 JSONPOST请求。

提交按钮叫"订阅",注册成功后页面显示"你已订阅"(Du er blevet tilmeldt.)。页面还分为新建订阅管理已有订阅两个区域,已经订阅过的用户可以回到自己的设置而无需翻找旧邮件。

从数据模型看,这些表单字段一一对应订阅者实体 StatusPageSubscriber.ts 中的列:subscriberEmail(邮箱)、subscriberPhone(电话)、subscriberWebhook(Webhook)、slackIncomingWebhookUrl+slackWorkspaceName(Slack)、microsoftTeamsIncomingWebhookUrl+microsoftTeamsWorkspaceName(Teams)。其中 Slack 与 Teams 的 Webhook URL 列被标记为仅创建可见、不可读取(read: []),从访问控制配置看,这是一项防止公开页泄露入站 Webhook 地址的安全设计。

允许订阅者自选资源与事件类型

默认情况下,订阅者收到页面上的全部内容。"高级订阅者设置"卡片中的两个开关会改变这一点:

  • 允许订阅者选择资源allowSubscribersToChooseResources)——默认关闭。开启后,订阅表单会出现"订阅所有资源"复选框;取消勾选后显示"选择要订阅的资源",让访客只挑选部分资源。
  • 允许订阅者选择事件类型allowSubscribersToChooseEventTypes)——默认关闭。同样的形式:一个"订阅所有事件类型"复选框,取消后显示"选择要订阅的事件类型"。

事件类型共三种:Incident(事件)、Announcement(公告)、Scheduled Event(计划事件)。这与源码枚举 StatusPageEventType.ts 完全一致:

enum StatusPageEventType { Incident = "Incident", Announcement = "Announcement", ScheduledEvent = "Scheduled Event", }

选择结果最终落在订阅者记录上,对应 StatusPageSubscriber.ts 中的以下字段:

字段默认值含义
isSubscribedToAllResourcestrue是否订阅全部资源
isSubscribedToAllEventTypestrue是否订阅全部事件类型
statusPageResources(Subscribed to Resources)多对多关联到具体的状态页资源
statusPageEventTypes(Subscribed to Event Types)[]订阅的事件类型列表(JSON 列)

适用场景:一个覆盖多个产品的页面。只使用你 API 的客户端并不想收到营销站点抖动时的每一条消息——与其让他们干脆退订,不如让他们自己裁剪订阅范围。

同一张卡片里还包含订阅者时区设置。

邮箱双重确认(Double Opt-In)

邮箱订阅者必须经过确认。当一个以邮箱地址创建的订阅者还不是已确认状态时,系统会将isSubscriptionConfirmed(是否已确认订阅)强制置为false,并生成一个六位数字的订阅确认令牌(Subscription Confirmation Token)。OneUptime 随后发送形如{statusPageUrl}/confirm-subscription/{statusPageSubscriberId}?verification-token={token}的确认链接。访客打开后进入"确认订阅"页面,成功后显示"订阅已确认"(Abonnement bekræftet)。

在数据模型中,这两个字段都有明确定义:isSubscriptionConfirmed 默认false,而 subscriptionConfirmationToken 为可空短文本列,且与确认标志一样被限制为不可通过读接口暴露。

SMS、Slack、Microsoft Teams 和 Webhook 订阅者跳过这一步——它们在创建时即把isSubscriptionConfirmed设为true

未确认即静默。拉取通知收件人列表的查询会按isUnsubscribed: falseisSubscriptionConfirmed: true过滤。一个从未点击确认链接的邮箱地址会一直留在"邮箱订阅者"列表中,但收不到任何消息。如果有人坚称自己已订阅却什么都没收到,先检查这一列。

不存在关闭邮箱确认的开关——它对所有通过状态页注册的人无条件生效。而另一个独立的字段sendYouHaveSubscribedMessage(是否发送"你已订阅"消息,默认true,见 StatusPageSubscriber.ts)控制的是订阅者被确认之后发送的那封"你已订阅"通知邮件。

管理订阅与退订

每封发给订阅者的邮件都带有形如{statusPageUrl}/update-subscription/{statusPageSubscriberId}的退订链接。该页面名为"更新订阅",会告诉访客可以在此修改设置或取消订阅。页面包含:

  • 当前允许的资源与事件类型选择器;
  • 一个"退订"复选框,说明为"从所有资源退订",它写入isUnsubscribed(已退订,默认false);
  • 一个名为"更新订阅"的按钮,保存成功后显示"你的更改已保存"。

如果访客弄丢了链接,可以在订阅页的管理已有订阅区域点击"发送管理链接"。OneUptime 会回复说明管理邮件已发出,如果没收到请检查垃圾邮件文件夹。

支撑这一切的后端端点为:POST .../subscribe/:statusPageIdPOST .../manage-subscription/:statusPageIdPOST .../get-subscription/:statusPageId/:subscriberIdPUT .../update-subscription/:statusPageId/:subscriberId

退订是翻转一个标志而不是删除记录,因此该条目会一直保留在通道列表中并标记为"已退订"——将来需要解释"为什么某个地址不再收到消息"时,这条历史仍在。

订阅者会收到什么通知

订阅者会收到上述三种事件类型的通知,但每种来源都有独立的开关,避免误发。

公告通知

公告本身带有是否通知状态页订阅者shouldStatusPageSubscribersBeNotified)字段,在创建表单中显示为"通知状态页订阅者"复选框,默认开启。如果公告在**受影响监控(可选)**中指定了监控,则通知范围限定为这些监控的订阅者;留空则通知所有订阅者。

计划维护事件

计划维护事件(Scheduled Maintenance)拥有自己的一组订阅者字段:是否在事件创建时通知状态页订阅者是否在事件状态变为进行中时通知是否在事件状态变为结束时通知,以及事件前的订阅者通知下一次事件前通知时间两个提前量配置。事件上的状态页字段决定它出现在哪些页面上,而是否应在状态页显示决定它是否可见。

从源码结构看,通知事件粒度比三种业务事件类型更细:StatusPageSubscriberNotificationEventType.ts 枚举列出了事件创建、状态变更、备注创建、复盘发布等独立事件(如SubscriberIncidentCreatedSubscriberIncidentStateChangedSubscriberScheduledMaintenanceStateChanged),还包括订阅生命周期事件(确认、订阅、管理)与周期性报表事件,供模板按事件类型分别配置文案。

事件(Incident)

Incident是第三种事件类型。一个事件凭什么会出现在状态页上——它涉及哪些资源、哪些状态会保持它可见——参见 OneUptime 文档中"事件状态与严重级别"一章。

状态页侧边菜单中的通知日志部分({id}/notification-logs)是排查"这个页面实际发送了什么"时的入口。

通知模板定制

"订阅设置"中的通知模板卡片展示该状态页当前使用的模板,列为模板名称事件类型通知方式——你可以按事件类型、按通道分别定制文案,而不是对所有消息使用同一套话术。

项目级模板位于上一层级:状态页 → 设置 → 订阅模板,与公告模板并列。

邮箱页脚、自定义 SMTP 与 Twilio

"订阅设置"上还有三张卡片控制订阅者消息如何离开你的项目:

  • 邮箱页脚设置——"启用自定义邮箱页脚文本"和"订阅者邮件通知页脚文本",为订阅者邮件加上你自己的页脚;
  • 自定义 SMTP——"自定义 SMTP 配置",让订阅者邮件走你自己的邮件服务器而非默认服务器;
  • Twilio 配置——"Twilio 配置",SMS 订阅者使用的 Twilio 账号。

如果你有邮箱订阅者,值得尽早配置自定义 SMTP:来自自己域名的邮件被过滤的概率更低,深夜两点读到邮件的客户也更可能信任它。

公告(Announcement)的创建

公告是项目级别的一条记录(模型StatusPageAnnouncement),可以发布到一个或多个状态页,可选地限定到特定监控,并带有显示时间窗口。

创建入口在状态页 → 更多 → 公告,或在单个状态页侧边菜单的公告中。创建表单是一个四步向导:

  1. 基本信息——公告标题(必填,至少两个字符)、描述(Markdown,可选)、附件(与公告一起放在状态页上的文件);
  2. 状态页——在此状态页显示公告,必填的多选列表,一条公告可以同时命中多个页面;
  3. 受影响资源——受影响监控(可选),不选则所有订阅者都会收到通知;
  4. 时间与设置——开始显示公告的时间(必填,默认为现在)、停止显示公告的时间(可选)、通知状态页订阅者(默认开启)。

访客在/announcements阅读公告,页面分为当前公告历史公告两个区域,每条都标注"发布于"时间戳。当前生效的公告同时悬挂在概览页顶部。如果没有任何内容可显示,页面会显示"没有公告"并注明尚未发布任何内容。

附件通过GET {statusPageCrudPath}/status-page-announcement/attachment/:statusPageId/:announcementId/:fileId提供,背后是与状态页本身相同的读取校验——私有页面上的附件保持私有。

公告计划(Plan)机制的底层规则

显示时间showAnnouncementAt)与结束时间endAnnouncementAt)控制一切,但概览页和公告列表回答的是两个不同的问题,这个差异容易让人踩坑:

  • 概览页:当showAnnouncementAt早于当前时间,且endAnnouncementAt晚于当前时间或为空时,公告显示出来;
  • /announcements列表:只列出showAnnouncementAt落在显示公告历史(天数)showAnnouncementHistoryInDays,默认 14 天)范围内的公告,然后在客户端按活跃/历史分组。

两个值得在排期时记住的推论:

  • 没有结束时间的公告永不过期。如果"停止显示公告的时间"留空,它会永远挂在概览页上。所有有时限的内容都应设置结束时间。
  • 旧但仍活跃的公告可能从列表中消失。如果公告的显示时间早于showAnnouncementHistoryInDays天之前,它会从/announcements列表中消失,但仍保留在概览页上。长期运营公告时应调大这个历史窗口。

公告是否显示本身由高级设置中的公告设置卡片控制:显示公告showAnnouncementsOnStatusPage,默认true)与显示公告历史(天数)(默认 14)。若"显示公告"关闭,公告端点会直接拒绝请求。

公告模板

如果反复发布同一类公告——每月的维护预告、某个第三方反复出现的服务降级——就提前做成模板。状态页 → 设置 → 公告模板承载模型StatusPageAnnouncementTemplate,其表单要求模板名称模板描述公告标题描述在此状态页显示公告受影响监控(可选)通知订阅者,让发布范围与"是否通知"这两个决定一次做出,而不是每次重新判断。

Webhook 订阅者与 SSRF 防护

Webhook 订阅者在每次状态页事件发生时收到一个 JSONPOST请求,因此把状态页更新导入你自己的系统(聊天机器人、内部仪表盘、工单系统)是最简单的方式。

由于订阅是公开页面上的公开操作,OneUptime 会对目标地址做防护:

  • 普通Webhook URL在接受前会被校验:私有地址、回环地址、链路本地地址与云元数据地址都会被拒绝,无法把一个订阅指向 OneUptime 安装所在网络内部的地址;
  • Slack 入站 Webhook URL必须以https://hooks.slack.com/services/开头。

如果一个 Webhook 订阅在注册时被拒绝,内部地址或格式错误的 URL 是你应该首先排查的原因。

进一步阅读

  • 状态页 – 概览——状态页是什么、如何组成;
  • 状态页 – 资源与分组——订阅者可以从中挑选的监控与分组;
  • 状态页 – 品牌与域名——自定义域名、Logo 以及邮件所链接页面的外观;
  • 公共 API——以编程方式读取状态页数据。

配合数据模型源码 StatusPageSubscriber.ts 与事件类型枚举 StatusPageEventType.ts、StatusPageSubscriberNotificationEventType.ts,可以在字段级别核对本文所述的每个开关、默认值与访问控制配置。

【免费下载链接】oneuptimeComplete open-source monitoring and observability platform.项目地址: https://gitcode.com/GitHub_Trending/on/oneuptime

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询