尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

OneUptime 状态页订阅者与公告实战指南:五通道订阅、双重确认与公告排期

OneUptime 状态页订阅者与公告实战指南:五通道订阅、双重确认与公告排期 OneUptime 状态页订阅者与公告实战指南五通道订阅、双重确认与公告排期【免费下载链接】oneuptimeComplete open-source monitoring and observability platform.项目地址: https://gitcode.com/GitHub_Trending/on/oneuptime订阅者Subscribers与公告Announcements是状态页Status Page的两大核心组件状态页本身是人们会主动访问的地方而订阅者恰恰是不想主动访问的人群——他们一次性留下邮箱、手机号、Slack 或微软 Teams 的 Webhook 地址、或者一个 HTTP 端点之后所有更新都由 OneUptime 主动推送到他们面前。公告则补齐了监控系统看不见的另一半监控器只能告诉你结账接口正在返回 500却无法告诉你本周六要迁移数据库第三方供应商今天不太稳定或者昨天的事件已完全解决。本文以 OneUptime 开源仓库中的官方文档与源码为据完整讲解五种订阅通道及其开启方式、订阅表单的访客视角、订阅者对资源与事件类型的选择权、邮件双重确认double opt-in与退订流程以及公告的编写、排期与模板定制并深入到StatusPageSubscriber、StatusPage、StatusPageAnnouncement等模型与服务层的实现细节。五种订阅通道与各自的开关一个状态页支持五种订阅通道每种通道在状态页上都有独立的开关。入口为Status Pages → 你的页面 → Subscribers → Subscriber Settings开关配置字段源码列名默认值Enable Email SubscribersenableEmailSubscribers开启Enable SMS SubscribersenableSmsSubscribers关闭Enable Slack SubscribersenableSlackSubscribers关闭Enable Microsoft Teams SubscribersenableMicrosoftTeamsSubscribers关闭Enable Webhook SubscribersenableWebhookSubscribers关闭邮件订阅默认开启其余四种默认关闭直到你主动打开。在源码中这五个字段定义于 Common/Models/DatabaseModels/StatusPage.ts均为TableColumnType.Boolean类型的默认值列其中enableEmailSubscribers的defaultValue: true与文档描述一致StatusPage.ts。每个通道在状态页侧边菜单的Subscribers下还各有一份独立列表Email Subscribers、SMS Subscribers、Slack Subscribers、MS Teams Subscribers与Webhook Subscribers。在那里你可以查看谁已订阅、手动添加某人或者在某个订阅者上留下Notes对应internalNote字段备忘。需要注意单一开关并不够用。状态页导航栏里的Subscribe菜单项只有在Show Subscriber PageshowSubscriberPageOnStatusPage开启且至少有一个通道被启用时才会出现。如果你只打开了Enable Email Subscribers却保留Show Subscriber Page关闭访客将没有任何途径触达订阅表单。另外这五个开关会第二次出现在Advanced Settings的Subscriber Settings卡片中与Show Subscriber Page并列。它们在底层对应的是同一批字段——所以请任选一个界面并保持一致优先使用专门的Subscriber Settings页面因为其余的订阅配置都集中在那里。访客视角的 Subscribe 页面Subscribe页面带有一个子菜单每个已启用的通道对应一个标签页——Email、SMS、Slack、MS Teams、Webhooks——分别映射到/subscribe/email、/subscribe/sms、/subscribe/slack、/subscribe/microsoft-teams与/subscribe/webhooks。每个标签页只收集它所需的最少信息Email—— 标题Subscribe by Email只有一个字段Your Email占位符为subscribercompany.com。SMS—— 标题Subscribe by SMS只有一个字段Your Phone Number占位符为11234567890。Slack—— 标题Subscribe by Slack包含Slack Workspace Name用于校验与标识与Slack Incoming Webhook URL占位符为https://hooks.slack.com/services/...。MS Teams—— 标题Subscribe by Microsoft Teams包含Microsoft Teams Workspace Name与Microsoft Teams Incoming Webhook URL占位符为https://outlook.office.com/webhook/...。Webhooks—— 标题Subscribe by Webhook只有一个字段Webhook URL。每次状态页事件发生时OneUptime 都会向该地址发送一个 JSONPOST请求。这些字段与数据模型的列一一对应subscriberEmail、subscriberPhone、subscriberWebhook、slackIncomingWebhookUrl、slackWorkspaceName、microsoftTeamsIncomingWebhookUrl与microsoftTeamsWorkspaceName均定义在 Common/Models/DatabaseModels/StatusPageSubscriber.ts 中。其中subscriberEmail与subscriberPhone两个列上还建有组合索引Index([statusPageId, subscriberEmail])与Index([statusPageId, subscriberPhone])用于订阅时的去重查找StatusPageSubscriber.ts。从该模型的列访问控制ColumnAccessControl可以看到邮箱、电话、Webhook 与 Slack/Teams 相关字段在创建时均允许Permission.Public写入——这正是公开状态页上任何人可自助订阅的权限基础。提交按钮文案为Subscribe成功订阅后会显示You have been subscribed successfully.。页面还提供New Subscription / Manage Existing Subscription两种入口的切换让已经订阅过的人不必翻找旧邮件就能回到自己的偏好设置页。让订阅者自行选择资源与事件类型默认情况下订阅者会收到页面上的所有内容。Advanced Subscriber Settings卡片中的两个开关可以改变这一点Allow Subscribers to Choose ResourcesallowSubscribersToChooseResources—— 默认关闭。开启后订阅表单会多出一个Subscribe to All Resources开关取消勾选后出现Select Resources to Subscribe让访客逐个挑选资源。Allow Subscribers to Choose Event TypesallowSubscribersToChooseEventTypes—— 默认关闭。形态相同一个Subscribe to All Event Types开关取消勾选后出现Select Event Types to Subscribe。事件类型共三种Incident事件、Announcement公告与Scheduled Event计划维护事件。订阅者的选择会落到订阅记录上对应字段为Is Subscribed to All ResourcesisSubscribedToAllResources默认true、Is Subscribed to All Event TypesisSubscribedToAllEventTypes默认true、Subscribed to ResourcesstatusPageResources与Subscribed to Event TypesstatusPageEventTypes。在源码中statusPageResources是一个与StatusPageResource的多对多关系通过StatusPageSubscriberStatusPageResource连接表而statusPageEventTypes是ArrayStatusPageEventType类型的 JSON 列StatusPageSubscriber.ts。订阅过滤的实际逻辑在服务层StatusPageSubscriberService.shouldSendNotification()会先检查订阅者是否已退订然后当页面开启了allowSubscribersToChooseResources且订阅者未勾选订阅所有资源时按其选中的statusPageResources进行匹配其中对公告有一个特例——公告未绑定任何监控器时不做资源过滤StatusPageSubscriberService.ts。此外从StatusPage.ts的ColumnBillingAccessControl可以看出这两个允许订阅者自主选择的开关在更新时对应PlanType.Scale套餐等级StatusPage.ts。适用场景一个覆盖多个产品的状态页。只使用你 API 的客户并不希望在营销站点每次抖动时都收到通知——与其看着他们直接退订不如让他们自己收窄订阅范围。同一卡片还提供Subscriber TimezonessubscriberTimezonesArrayTimezone用于时区相关通知。邮件双重确认Double Opt-in邮件订阅者必须始终确认订阅。当一条订阅记录以邮箱地址创建、且创建时未标记为已确认时Is Subscription ConfirmedisSubscriptionConfirmed会被强制置为false同时生成一个六位数的Subscription Confirmation Token。OneUptime 随后发送一封包含确认链接的邮件链接形如{statusPageUrl}/confirm-subscription/{statusPageSubscriberId}?verification-token{token}访客进入Confirm Subscription页面完成确认后会看到Subscription confirmed successfully。SMS、Slack、Microsoft Teams 与 Webhook 订阅者跳过此流程——它们创建时isSubscriptionConfirmed直接被置为true。未确认即静默。拉取订阅者用于发送通知的查询会同时过滤isUnsubscribed: false与isSubscriptionConfirmed: true。一个从未点击确认链接的邮箱地址会一直躺在Email Subscribers列表里却收不到任何通知。如果有人坚称自己订阅了却毫无动静请先检查这一列。源码佐证getSubscribersByStatusPage()的查询条件正是这两个字段StatusPageSubscriberService.ts而创建前的onBeforeCreate钩子实现了邮箱订阅者未确认则强制false其余通道一律true的规则并使用NumberUtil.getRandomNumber(100000, 999999)生成六位确认令牌StatusPageSubscriberService.ts。邮件确认没有开关可以关闭——凡是通过状态页自助注册的订阅者一律需要确认。另有一个独立的按订阅者维度字段Send You Have Subscribed MessagesendYouHaveSubscribedMessage默认true控制订阅者确认后是否收到一封 you have subscribed 确认邮件。管理订阅与退订每封发给订阅者的邮件都带有一个退订链接形如{statusPageUrl}/update-subscription/{statusPageSubscriberId}。该页面标题为Update Subscription告知访客可以在这里更新偏好或退订包含页面允许的资源与事件类型选择器一个Unsubscribe开关描述为从所有资源退订写入Is UnsubscribedisUnsubscribed默认false一个文案为Update Subscription的提交按钮保存后显示Your changes have been saved.。丢失链接的人可以在Subscribe页面使用Manage Existing Subscription并点击Send Management Link。OneUptime 会回复称包含链接的邮件已发出并提醒如果没收到请检查垃圾邮件文件夹。背后的端点包括POST .../subscribe/:statusPageId、POST .../manage-subscription/:statusPageId、POST .../get-subscription/:statusPageId/:subscriberId与PUT .../update-subscription/:statusPageId/:subscriberId。服务层同样提供了getUnsubscribeLink()方法将{statusPageUrl}拼接/update-subscription/{statusPageSubscriberId}生成退订链接StatusPageSubscriberService.ts。退订是翻转标志位而不是删除记录——isUnsubscribed置true后记录仍保留在通道列表中。当你需要解释某个地址为何停止收到邮件时这条历史记录非常有用。在数据模型上isUnsubscribed与isSubscriptionConfirmed一样都是默认false的布尔默认值列StatusPageSubscriber.ts。订阅者会收到什么通知订阅者会听到上述三种事件类型但每种来源都有自己的独立开关因此不会误发。公告通知公告自身携带Should subscribers be notified?shouldStatusPageSubscribersBeNotified在创建表单上以Notify Status Page Subscribers复选框呈现默认勾选。如果公告在Monitors affected (Optional)中指定了监控器则通知范围收窄到这些监控器的订阅者留空则通知所有订阅者。该字段在 StatusPageAnnouncement.ts 中为默认true的默认值列。计划维护事件计划维护事件Scheduled maintenance event有一套独立的订阅者字段Should subscribers be notified when event is created?创建时通知、Should subscribers be notified when event is changed to ongoing?转为进行中时通知、Should subscribers be notified when event is changed to ended?转为结束时通知另有Subscriber notifications before the event提前通知与Next subscriber notification before the event at?下一次提前通知时间用于预警。事件上的Status Pages决定它出现在哪些页面上而Should be visible on status page?决定它是否可见。事件IncidentIncident是第三种事件类型。一个事件最初如何上状态页——它触及哪些资源、哪些状态会使其保持可见——在 事件状态与严重级别指南 中有详细说明。状态页侧边菜单中的Notification Logs区域{id}/notification-logs是查看页面实际发送了什么的去处。编辑后如何告知订阅者订阅者只会在公告或公开备注public note发布的那一刻听到一次。之后的编辑只改变状态页上显示的内容不会通知任何人——除非你在这条编辑上主动要求。公告的编辑表单以及事件、计划维护事件或事件片段incident episode上的公开备注编辑表单都有一个Notify subscribers about this update复选框。它每次默认不勾选所以修正拼写错误会保持安静只有当改动重要时才勾选——例如新的维护窗口、修订后的影响范围、更正后的客户更新。创建表单上没有这个复选框因为它们有自己的Notify Status Page Subscribers选项。勾选后保存订阅者收到的编辑内容会被标记为更新而非新帖子Email使用自己的模板——例如主题[Announcement Updated] title、标题Announcement Updated: title备注邮件的详情框中则显示Updated Note。SMS、Slack与Microsoft Teams会说明该公告或备注已更新。Webhook订阅者收到AnnouncementUpdated、IncidentNoteUpdated、ScheduledMaintenanceNoteUpdated或EpisodeNoteUpdated作为eventType最新内容放在data中。更新会送达与原始消息今天能触达的相同人群相同的通道开关、相同的资源与事件类型偏好、相同的可见性检查隐藏的事件或关闭了Show Announcements的页面依然不会发送任何内容。有两种情况会刻意不发送并记录原因原始通知尚未发出。如果公告或备注仍在等待发布那条通知在真正发送时会读取最新内容、天然携带你的编辑再单独发一条已更新反而会混淆读者。公告排期在未来。在Start Showing Announcement At到达之前它不在任何状态页上正式上线时被通知到的人看到的本来就是编辑后的版本。编辑后的对象会显示Update Notification Status与原始通知的状态Sending Soon、Notifications Sent、Failed等并列。Retry按钮重发的是更新通知绝不会重发原始的已发布消息。每个状态页都可以通过Subscriber Announcement Updated、Subscriber Incident Note Updated、Subscriber Scheduled Maintenance Note Updated与Subscriber Episode Note Updated模板事件类型定制这些消息未定制时使用内置的更新措辞。通过 API 发送该选择时将它放在miscDataProps中与你要修改的字段并列{ data: { description: The maintenance now starts on Sunday at 02:00 UTC. }, miscDataProps: { notifySubscribersOfUpdate: true } }作为PUT /api/status-page-announcement/announcement-id或incident-public-note、scheduled-maintenance-public-note、incident-episode-public-note的请求体。不带miscDataProps的编辑保持静默与之前一致。这一能力与模型中的计算列对应StatusPageAnnouncement上有subscriberNotificationStatusOnAnnouncementUpdated与subscriberNotificationStatusMessageOnAnnouncementUpdated分别记录公告更新通知的状态与原因说明StatusPageAnnouncement.ts。定制通知模板Subscriber Settings上的Notification Templates卡片列出该状态页使用的模板列为Template Name、Event Type与Notification Method——因此你可以按事件类型和通道分别定制措辞而不是所有消息都用一个统一文案。项目级模板再往上一级位于Status Pages → Settings → Subscriber Templates紧挨着Announcement Templates。在源码中模板通过StatusPageSubscriberNotificationTemplate与StatusPageSubscriberNotificationTemplateStatusPage两个模型建立模板—事件类型—通知方法—状态页的关联见 Common/Models/DatabaseModels/StatusPageSubscriberNotificationTemplate.ts并有对应的模板编译服务与变量测试如 StatusPageSubscriberNotificationTemplateCompile.test.ts来保证渲染正确。邮件页脚、自定义 SMTP 与 TwilioSubscriber Settings上还有三张卡片控制订阅消息如何离开你的项目Email Footer Settings——Enable Custom Email Footer Text与Subscriber Email Notification Footer Text为订阅邮件加上你自己的页脚。Custom SMTP——Custom SMTP Config让订阅邮件改走你自己的邮件服务器而非默认通道。Twilio Config——Twilio Config指定用于 SMS 订阅者的 Twilio 账户。如果你有邮件订阅者自定义 SMTP 值得尽早配置来自你自己域名的邮件被过滤的概率要低得多也更容易赢得凌晨两点还在读邮件的客户的信任。从源码结构看这些配置与项目的ProjectSmtpConfig、ProjectCallSMSConfig模型关联StatusPage模型引用了这两个配置实体最终由通知服务在发送时读取。公告Announcements公告是项目级记录StatusPageAnnouncement模型你可以把它扇出到一个或多个状态页可选地限定到特定监控器并设置展示时间窗口。在 StatusPageAnnouncement.ts 中可以看到statusPages与monitors都是多对多关系分别通过AnnouncementStatusPage与AnnouncementMonitor连接表且该表在创建/更新上带有PlanType.Growth的计费门控StatusPageAnnouncement.ts。创建入口为Status Pages → More → Announcements或单个状态页侧边菜单中的Announcements。创建表单是一个四步向导Basic Information——Announcement Title必填至少两个字符、DescriptionMarkdown可选与Attachments需要随公告一起在状态页上提供的附件文件。Status Pages——Show announcement on these status pages必填多选。一条公告可以同时面向多个页面。Resources Affected——Monitors affected (Optional)。一个都不选则通知所有订阅者。Schedule Settings——Start Showing Announcement At必填默认为现在、End Showing Announcement At可选与Notify Status Page Subscribers默认开启。访客在/announcements阅读公告页面分为Active Announcements与Past Announcements每条都标有Announced at。当前正在展示的公告还会置顶在概览页顶部。没有任何内容时页面显示No Announcement并提示尚未发布任何公告。附件通过GET {statusPageCrudPath}/status-page-announcement/attachment/:statusPageId/:announcementId/:fileId提供与状态页本身共用同一读取校验——因此私有页面上的附件始终是私有的。公告排期的工作原理Show AtshowAnnouncementAt与End AtendAnnouncementAt驱动一切但概览页与公告列表提出的问题不同这个差异常常让人困惑概览页当showAnnouncementAt在过去、且endAnnouncementAt在未来或为空时展示该公告。/announcements列表展示showAnnouncementAt落在Show Announcement History (in days)showAnnouncementHistoryInDays默认 14 天窗口内的公告然后在客户端将其拆分为进行中与已结束。两个值得提前规划的后果没有结束日期的公告永不失效。留空End Showing Announcement At它会无限期置顶在概览页。任何有时效的内容都请设置结束日期。一条老而仍在生效的公告可能从列表消失。如果它的开始时间早于showAnnouncementHistoryInDays窗口它会从/announcements掉出却仍留在概览页。如果你有长期展示的通知请调大历史窗口。公告是否出现由Advanced Settings上的Announcement Settings卡片控制Show AnnouncementsshowAnnouncementsOnStatusPage默认true与Show Announcement History (in days)默认 14。Show Announcements关闭时公告端点会直接拒绝请求。公告模板如果你反复发布同类型的通知——每月维护预告、周期性第三方降级——请提前做好模板。Status Pages → Settings → Announcement Templates存储StatusPageAnnouncementTemplate模型其表单包含Template Name、Template Description、Announcement Title、Description、Show announcement on these status pages、Monitors affected (Optional)与Notify Subscribers——扇出目标与是否通知的决定只需做一次而不用每次重复。Webhook 订阅者与 SSRF 防护Webhook 订阅者在每次状态页事件发生时收到一个 JSONPOST请求因此它是把状态页更新接入自有系统聊天机器人、内部仪表盘、工单队列的最便捷方式。实际发送的负载结构定义在 Common/Server/Utils/StatusPageSubscriberWebhook.ts 中包含eventType、statusPageId、statusPageName、statusPageUrl、unsubscribeUrl与data六个字段。由于订阅是公开页面上的公开操作OneUptime 对目标地址做了防护通用的Webhook URL在接受前会被校验私有地址、回环地址、链路本地地址与云元数据地址cloud-metadata一律拒绝。你无法把订阅指向 OneUptime 部署自身网络内部的任何东西。Slack Incoming Webhook URL必须以https://hooks.slack.com/services/开头Microsoft Teams 的 Webhook URL 也会经过MicrosoftTeamsUtil.isValidMicrosoftTeamsIncomingWebhookUrl的格式校验。如果一条 Webhook 订阅在注册时被拒绝内部地址或畸形 URL 是首先要检查的。更重要的是SSRF 防护并非只在创建时执行一次sendWebhookNotification()在每次发送前都会再次调用SSRFProtection.validateWebhookTargetIsSafe()校验目标以防范此前已存储的 URL 或 DNS 重绑定攻击同时发送时不跟随重定向doNotFollowRedirects: true并带 3 次指数退避重试避免一个已验证的公网主机通过 3xx 把服务器引到内部地址StatusPageSubscriberWebhook.ts。创建侧的校验逻辑则在StatusPageSubscriberService.onBeforeCreate中StatusPageSubscriberService.ts注释明确指出订阅创建对Permission.Public开放因此不能享受仅供已认证项目成员使用的私有网络例外issue #3424否则等于把向运营者内网 POST的能力交给互联网上的任何访客。延伸阅读状态页概览 —— 什么是状态页、它由哪些部分构成。状态页资源与分组 —— 订阅者可以在哪些监控器与分组之间选择。状态页品牌与域名 —— 自定义域名、Logo 以及你邮件所指向页面的外观。公共 API —— 以编程方式读取状态页数据。事件状态与严重级别 —— 什么把事件放上状态页、什么把它拿下来。事件设置与自动化 —— 事件沟通背后的项目级规则。相关源码与测试路径订阅者模型 StatusPageSubscriber.ts、状态页模型 StatusPage.ts、公告模型 StatusPageAnnouncement.ts、订阅服务 StatusPageSubscriberService.ts、Webhook 发送工具 StatusPageSubscriberWebhook.ts以及 Webhook 相关测试 StatusPageSubscriberWebhookPrivateNetwork.test.ts可作为进一步深入源码的起点。【免费下载链接】oneuptimeComplete open-source monitoring and observability platform.项目地址: https://gitcode.com/GitHub_Trending/on/oneuptime创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表