Seerr 集成 Pushover 推送通知完整指南:从应用注册、Token 配置到消息发送源码解析
Seerr 集成 Pushover 推送通知完整指南从应用注册、Token 配置到消息发送源码解析【免费下载链接】seerrOpen-source media request and discovery manager for Jellyfin, Plex, and Emby.项目地址: https://gitcode.com/GitHub_Trending/je/seerrSeerr 内置 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 TokenaccessTokenUser Key标识「消息发送给谁」接收者凭证可填用户密钥或群组密钥User or Group KeyuserToken前端表单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.tsxEnable Agent打开「启用代理」开关该开关对应enabled字段Embed Poster勾选「嵌入海报」后通知会附带媒体海报图片对应embedPoster字段默认开启Application API Token粘贴第一步获取的 30 位应用 TokenUser or Group Key粘贴你的用户密钥或群组密钥Notification Sound选择通知铃声。该下拉框默认显示「Device Default设备默认」输入 Token 后 Seerr 会实时调用 Pushover 接口拉取可用铃声列表详见下文铃声拉取接口Notification Types通过 NotificationTypeSelector 勾选要接收的事件类型媒体请求、审批、可用、问题反馈等。注意启用状态下至少需要勾选一种类型否则保存按钮会被禁用点击Test测试按钮发送一条 Check check, 1, 2, 3... 的测试消息确认手机端能收到后再点击Save保存。配置的持久化表单提交后前端通过POST /api/v1/settings/notifications/pushover将完整配置写入后端路由实现在 server/routes/settings/notifications.tsnotificationRoutes.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?tokenappTokenserver/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.tsnotificationRoutes.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.jsonpushover.ts负载结构定义在PushoverPayload接口中字段说明token应用 API Tokenuser用户/群组密钥title通知标题事件名或媒体标题message通知正文HTML 格式url/url_title回链到 Seerr 对应页面媒体详情页或问题页priority优先级普通 0 / 高优先级 1html固定为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 0MEDIA_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()内部按优先级依次处理三类接收者系统通知payload.notifySystem为真、事件类型命中settings.types位掩码、且代理已启用并填全凭证时使用系统配置的 Token/Key/Sound 发送个人通知payload.notifyUser为真且该用户在UserSettings中开启了 Pushover 订阅hasNotificationType(NotificationAgentKey.PUSHOVER, type)并填有自己的pushoverApplicationToken/pushoverUserKey时用用户自己的凭证发送。源码中还隐含一个去重逻辑当用户凭证与系统凭证完全相同时跳过个人发送避免同一用户收到重复消息管理员通知当payload.notifyAdmin为真时遍历所有用户找出启用了 Pushover 订阅且满足管理员通知条件的用户逐一按各自凭证发送。个人通知的相关字段pushoverApplicationToken、pushoverUserKey、pushoverSound定义在 server/entity/UserSettings.ts并由迁移脚本 AddPushbulletPushoverUserSettings.ts 与 AddUserPushoverSound.ts 逐版本补充这也解释了为何用户级配置支持独立的铃声选择。用户级个人通知配置若用户希望使用自己的Pushover 账户接收通知可在个人设置或管理员编辑用户的「通知」页中独立配置进入「用户设置 → 通知」找到 Pushover 区块填入自己的Application API Token与User or Group Key选择铃声与订阅的通知类型保存即可。该表单对应组件 UserNotificationsPushover.tsx与系统级配置同样使用^[a-z\d]{30}$校验且只有在勾选了至少一种通知类型时才要求填写凭证。个人配置通过POST /api/v1/user/{userId}/settings/notifications持久化到UserSettings。这种「系统一套、个人一套」的设计让 Seerr 既能满足管理员全局广播的需求也能让每个用户按自己的偏好与权限接收消息二者互不干扰。常见问题与排查建议测试失败 / 收不到消息优先检查shouldSend()的三个条件——代理已启用enabled、accessToken与userToken均非空。任一项缺失都会导致发送被跳过服务端日志label 为Notifications会打印 Sending Pushover notification 调试信息提示 Token 格式错误确认两项凭证均为 30 位字母数字串大小写均可可到 Pushover 账户页核对后重新粘贴铃声下拉框为空铃声列表依赖输入的应用 Token 实时拉取若 Token 无效或网络受限下拉框仅显示「Device Default」前端据此禁用选择器通知丢失或重复注意源码中的去重逻辑——当用户凭证与系统凭证一致时该用户只收到系统级投递不会重复收到个人投递反之凭证不同的用户会按自己的凭证独立接收希望团队共享通知将 User Key 换成 Pushover 群组密钥即可实现一对多广播无需为每个成员单独配置。小结Pushover 通知的完整链路可概括为管理员在设置页NotificationsPushover/index.tsx填写 30 位应用 Token 与用户/群组密钥 → 配置保存至settings.notifications.agents.pushoverserver/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),仅供参考