Seerr 集成 Pushover 推送通知完整指南:从应用注册、Token 配置到消息发送源码解析
2026/9/15 19:00:36 网站建设 项目流程

Seerr 集成 Pushover 推送通知完整指南:从应用注册、Token 配置到消息发送源码解析

【免费下载链接】seerrOpen-source media request and discovery manager for Jellyfin, Plex, and Emby.项目地址: https://gitcode.com/GitHub_Trending/je/seerr

Seerr 内置 Pushover 通知代理(Agent),可将媒体请求、审批、下载完成、问题反馈等系统事件实时推送到你的 Pushover 账户或群组。本文以官方文档 docs/using-seerr/notifications/pushover.md 为主线,完整讲解 Pushover 应用注册、API Token 与 User Key 的获取与填写、通知类型选择、测试验证,并结合仓库源码(代理实现、API 封装、设置接口、前端表单)深入剖析消息发送的底层原理,帮助你完成配置的同时理解其工作机制。

Pushover 通知在 Seerr 中的角色

Pushover 是一种面向个人与团队的消息推送服务,通过「应用(Application)+ 用户/群组(User/Group)」两级凭证模型实现定向推送:应用代表消息的发送方,用户密钥代表消息的接收方。在 Seerr 中,Pushover 通知被划分为两类场景(这一点在官方文档开头有明确说明):

  • 系统通知(System Notifications):由管理员在「设置 → 通知」中全局配置,作用于整个实例;
  • 个人通知(User Notifications):由用户在个人设置中自行配置,与系统通知相互独立,且可选的通知类型受用户权限约束——用户只能订阅自己权限允许看到的事件类型。

从源码结构看,Seerr 的通知体系由 server/lib/notifications/agents/pushover.ts 中的PushoverAgent承担,它同时处理系统通知、个人通知和面向管理员的通知三种投递路径,同一份配置结构贯穿前后端。

前置条件:理解两类凭证

配置 Pushover 前,先理清两个关键凭证的含义:

凭证作用在 Seerr 中的字段名
Application/API Token标识「哪个应用在发送消息」(应用凭证)Application API Token(accessToken
User Key标识「消息发送给谁」(接收者凭证),可填用户密钥或群组密钥User or Group Key(userToken

前端表单(src/components/Settings/Notifications/NotificationsPushover/index.tsx)对两项字段做了严格格式校验:正则^[a-z\d]{30}$(大小写不敏感),即两者都必须是由 30 位字母数字组成的凭证串,否则表单会拒绝保存并提示 "You must provide a valid application token" / "You must provide a valid user or group key"。这一校验同样存在于个人通知设置页 UserNotificationsPushover.tsx,前后端保持了一致的约束。

第一步:注册应用并获取 API Token

按照官方文档说明,需要先在 Pushover 平台注册一个应用程序(Application),注册完成后即可获得该应用的 API Token。官方文档同时提示:注册应用时可以选用仓库public/目录下提供的官方图标(例如 public/images/os_icon.svg、public/logo_full.png 等),让推送在手机端展示为 Seerr 的专属图标,提升辨识度。

注册与 Token 相关细节以 Pushover 官方 API 文档的注册(registration)章节为准。在 Seerr 中,这一 Token 最终落位到设置对象settings.notifications.agents.pushover.options.accessToken

第二步:填写 User Key(或群组密钥)

User Key 即你 Pushover 账户的 30 位用户密钥。官方文档特别强调一个实用技巧:

除了填自己的用户密钥外,也可以填写群组密钥(Group Key),从而把同一条通知同时投递给群组内的多个成员。

这对家庭媒体库、团队运维场景非常实用:管理员只需维护一个群组密钥,所有成员的设备都能收到请求审批、媒体可用等通知,无需逐一配置。

User Key 在设置对象中对应options.userToken。当启用代理且两项凭证均非空时,PushoverAgent.shouldSend()才返回true(见 pushover.ts),这也是发送测试通知的硬性前置条件。

在 Seerr 中完成系统级配置

进入「设置(Settings)→ 通知(Notifications)→ Pushover」,按以下步骤操作(对应表单组件 NotificationsPushover/index.tsx):

  1. Enable Agent:打开「启用代理」开关,该开关对应enabled字段;
  2. Embed Poster:勾选「嵌入海报」后,通知会附带媒体海报图片(对应embedPoster字段,默认开启);
  3. Application API Token:粘贴第一步获取的 30 位应用 Token;
  4. User or Group Key:粘贴你的用户密钥或群组密钥;
  5. Notification Sound:选择通知铃声。该下拉框默认显示「Device Default(设备默认)」,输入 Token 后 Seerr 会实时调用 Pushover 接口拉取可用铃声列表(详见下文"铃声拉取接口");
  6. Notification Types:通过 NotificationTypeSelector 勾选要接收的事件类型(媒体请求、审批、可用、问题反馈等)。注意:启用状态下至少需要勾选一种类型,否则保存按钮会被禁用;
  7. 点击Test(测试)按钮发送一条 "Check check, 1, 2, 3..." 的测试消息,确认手机端能收到后再点击Save保存。

配置的持久化

表单提交后,前端通过POST /api/v1/settings/notifications/pushover将完整配置写入后端,路由实现在 server/routes/settings/notifications.ts:

notificationRoutes.post('/pushover', async (req, res) => { const settings = getSettings(); settings.notifications.agents.pushover = req.body; await settings.save(); res.status(200).json(settings.notifications.agents.pushover); });

同时提供GET /api/v1/settings/notifications/pushover读取当前配置。该路由挂载在isAuthenticated(Permission.ADMIN)权限之下(见 server/routes/index.ts),只有管理员可读写系统级推送配置。

默认配置一览

从 server/lib/settings/index.ts 可看到 Pushover 代理的默认值:

pushover: { enabled: false, embedPoster: true, types: 0, options: { accessToken: '', userToken: '', sound: '', }, }

即:默认关闭、默认嵌入海报、默认不勾选任何通知类型、sound 为空字符串表示使用设备默认铃声。类型字段types是位掩码(bitmask)整数,0表示不订阅任何事件。

铃声拉取接口

通知设置页的铃声下拉框数据并非写死的,而是通过后端代理实时从 Pushover 获取:

  • 路由GET /settings/notifications/pushover/sounds?token=<appToken>(server/routes/index.ts)要求请求中携带应用 Token;
  • 底层由 server/api/pushover.ts 中的PushoverAPI.getSounds(appToken)调用https://api.pushover.net/1/sounds.json实现,返回的sounds映射(铃声名 → 描述)经mapSounds转换为{ name, description }列表;
  • 前端拿到列表后渲染为下拉选项,空值代表「Device Default」。

测试通知的发送链路

点击「Test」按钮时,前端直接POST /api/v1/settings/notifications/pushover/test(携带当前表单的完整配置,无需先保存)。服务端处理位于 notifications.ts:

notificationRoutes.post('/pushover/test', async (req, res, next) => { const pushoverAgent = new PushoverAgent(req.body); if (await sendTestNotification(pushoverAgent, req.user)) { return res.status(204).send(); } else { return next({ status: 500, message: 'Failed to send Pushover notification.', }); } });

sendTestNotification会构造一条Notification.TEST_NOTIFICATION事件(主题 "Test Notification"、正文 "Check check, 1, 2, 3. Are we coming in clear?"),并分别以系统通知与当前用户个人通知两种身份尝试投递。前端对应有三种 Toast 反馈:发送中、发送成功、发送失败(见表单组件中的toastPushoverTestSending/TestSuccess/TestFailed)。

消息发送的源码级原理

请求目标与负载结构

PushoverAgent.send()将消息 POST 到https://api.pushover.net/1/messages.json(pushover.ts),负载结构定义在PushoverPayload接口中:

字段说明
token应用 API Token
user用户/群组密钥
title通知标题(事件名或媒体标题)
message通知正文(HTML 格式)
url/url_title回链到 Seerr 对应页面(媒体详情页或问题页)
priority优先级(普通 0 / 高优先级 1)
html固定为1,启用 HTML 富文本渲染
sound铃声名称
attachment_base64/attachment_type海报图片的 Base64 数据与 MIME 类型

正文组装与本地化

正文由getNotificationPayload()动态拼接,并基于接收者的locale进行国际化(getIntl(locale)):

  • 事件类消息先输出加粗的媒体标题<b>...</b>,再追加<small>正文细节;
  • 请求类事件附带「请求人(requestedBy)」与「请求状态(pendingApproval / processing / available / declined / failed)」;
  • 评论类事件附带「评论人与评论内容」;
  • 问题类事件附带「报告人、问题类型、问题状态(open / resolved)」;
  • 额外字段extra名称: 值的形式逐行追加。

优先级的自动提升

priority字段不是静态的,而是根据事件类型自动调整:

  • 普通事件:priority = 0
  • MEDIA_DECLINED(请求被拒绝)、MEDIA_FAILED(媒体获取失败)、ISSUE_CREATED(新问题上报):priority = 1,即 Pushover 的高优先级模式,确保关键事件得到即时提醒。

回链地址

若 Seerr 配置了applicationUrl(主设置中的应用地址),消息会附带url回链:问题事件跳转/issues/{issueId},媒体事件跳转/{mediaType}/{tmdbId}url_title则本地化为「查看媒体 / 查看问题」。

海报嵌入的实现

勾选 Embed Poster 后,代理会通过getImagePayload()arraybuffer方式下载海报原图,转成 Base64 与 MIME 类型后作为attachment_base64/attachment_type一起提交(pushover.ts)。下载失败时仅记录错误日志并继续发送纯文本消息,不会导致整个通知中断。

三种投递路径

send()内部按优先级依次处理三类接收者:

  1. 系统通知payload.notifySystem为真、事件类型命中settings.types位掩码、且代理已启用并填全凭证时,使用系统配置的 Token/Key/Sound 发送;
  2. 个人通知payload.notifyUser为真,且该用户在UserSettings中开启了 Pushover 订阅(hasNotificationType(NotificationAgentKey.PUSHOVER, type))并填有自己的pushoverApplicationToken/pushoverUserKey时,用用户自己的凭证发送。源码中还隐含一个去重逻辑:当用户凭证与系统凭证完全相同时跳过个人发送,避免同一用户收到重复消息;
  3. 管理员通知:当payload.notifyAdmin为真时,遍历所有用户,找出启用了 Pushover 订阅且满足管理员通知条件的用户,逐一按各自凭证发送。

个人通知的相关字段(pushoverApplicationTokenpushoverUserKeypushoverSound)定义在 server/entity/UserSettings.ts,并由迁移脚本 AddPushbulletPushoverUserSettings.ts 与 AddUserPushoverSound.ts 逐版本补充,这也解释了为何用户级配置支持独立的铃声选择。

用户级个人通知配置

若用户希望使用自己的Pushover 账户接收通知,可在个人设置(或管理员编辑用户的「通知」页)中独立配置:

  1. 进入「用户设置 → 通知」;
  2. 找到 Pushover 区块,填入自己的Application API TokenUser or Group Key
  3. 选择铃声与订阅的通知类型,保存即可。

该表单对应组件 UserNotificationsPushover.tsx,与系统级配置同样使用^[a-z\d]{30}$校验,且只有在勾选了至少一种通知类型时才要求填写凭证。个人配置通过POST /api/v1/user/{userId}/settings/notifications持久化到UserSettings

这种「系统一套、个人一套」的设计,让 Seerr 既能满足管理员全局广播的需求,也能让每个用户按自己的偏好与权限接收消息,二者互不干扰。

常见问题与排查建议

  1. 测试失败 / 收不到消息:优先检查shouldSend()的三个条件——代理已启用(enabled)、accessTokenuserToken均非空。任一项缺失都会导致发送被跳过,服务端日志(label 为Notifications)会打印 "Sending Pushover notification" 调试信息;
  2. 提示 Token 格式错误:确认两项凭证均为 30 位字母数字串(大小写均可),可到 Pushover 账户页核对后重新粘贴;
  3. 铃声下拉框为空:铃声列表依赖输入的应用 Token 实时拉取,若 Token 无效或网络受限,下拉框仅显示「Device Default」(前端据此禁用选择器);
  4. 通知丢失或重复:注意源码中的去重逻辑——当用户凭证与系统凭证一致时,该用户只收到系统级投递,不会重复收到个人投递;反之,凭证不同的用户会按自己的凭证独立接收;
  5. 希望团队共享通知:将 User Key 换成 Pushover 群组密钥即可实现一对多广播,无需为每个成员单独配置。

小结

Pushover 通知的完整链路可概括为:管理员在设置页(NotificationsPushover/index.tsx)填写 30 位应用 Token 与用户/群组密钥 → 配置保存至settings.notifications.agents.pushover(server/lib/settings/index.ts)→ 事件触发时由PushoverAgent.send()(server/lib/notifications/agents/pushover.ts)组装含标题、HTML 正文、优先级、回链、海报附件的负载,POST 至 Pushover 消息接口;铃声列表则由 server/api/pushover.ts 通过sounds.json接口实时拉取。掌握这些配置项与源码细节后,你既能完成开箱即用的推送部署,也能在出现问题时快速定位是凭证、事件订阅还是负载组装环节出了偏差。

【免费下载链接】seerrOpen-source media request and discovery manager for Jellyfin, Plex, and Emby.项目地址: https://gitcode.com/GitHub_Trending/je/seerr

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

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

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

立即咨询