通知
Libre WebUI 为每位用户维护持久通知收件箱,使团队活动(提及、私信、共享、自动化 失败和日历提醒)在相关页面关闭时也能送达。
收件箱
通知首先是数据库行:标题和正文静态加密,每用户最多 500 条(清理最旧条目), 并可通过可选来源键去重,使重复发布合并为一条而不是反复响铃。REST 接口支持列出、 统计未读、标记一条或全部已读以及删除。
实时交付通过每用户持久事件流 notify:<userId>,使用
GET /api/notifications/events(SSE)。流身份来自已认证会话,绝不取自客户端
输入;SQL 收件箱仍是真实来源:错过事件时读取列表恢复,而不是重放流。
通知来源
| 类型 | 触发条件 |
|---|---|
channel-dm | 有人向你发送私信 |
channel-mention | 有人在频道中 @mentions 你或回复你的消息 |
channel-invite | 你被加入频道 |
share | 有人与你共享资源 |
automation-failed | 你的自动化失败(除非选择不通知) |
calendar-reminder | 带提醒偏移的事件到达提醒时间 |
work-run-finished | 你雇用的某个 Work 代理完成一次运行 |
work-run-attention | 已雇用代理停下来等待输入或遇到错误 |
work-takeover | Work 代理请求你接管其屏幕 |
work-approval | 某次 Work 运行正在等待你批准一项有副作用的操作 |
system | 实例级公告 |
通知始终只发给受影响用户;提及不属于频道的用户名不会产生任何内容。
出站 webhook
管理员可注册接收团队事件的 webhook 目标。
- **出站防护。**目标遵循与工具服务器相同的目的地政策:必须是精确 URL,不跟随重定向,
不允许私有或链路本地地址,除非管理员通过
TOOLS_PRIVATE_NETWORK_ALLOWLIST明确 放行主机。每次交付都会重新解析并检查主机名。 - **签名。**配置密钥后,每次交付都带
X-Libre-Signature: sha256=<hmac>,按准确正文计算。 - **脱敏。**信封包含事件种类、通知类型、标题、标识符和时间戳。通知正文、消息内容、 提示词和文档绝不会离开实例。
- **持久。**交付作为持久任务运行,重试次数受限;接收方 5xx 会重试,4xx 被视为 接收方结论并结束。
- **限定范围。**每个目标订阅指定通知类型(或
*)。
浏览器推送
设置 → 通知会为 Web Push 注册当前浏览器,让提及、共享、提醒和已完成工作在标签页 关闭时也能送达。实现标准且自包含:
- **VAPID (RFC 8292)。**服务器使用 ES256 密钥对签名每次交付;密钥对只生成一次并
加密存储,或用
VAPID_PUBLIC_KEY/VAPID_PRIVATE_KEY固定 (VAPID_SUBJECT设置联系声明)。除浏览器提供商的推送端点外,不使用第三方 推送库或服务账户。 - **加密负载 (RFC 8291)。**每条消息离开实例前都用 aes128gcm 加密到设备自己的 密钥;推送服务只能转发无法读取的密文。
- **按设备并绑定会话。**订阅属于创建它的浏览器和该浏览器的认证会话;退出会话 (或“退出其他会话”)也会移除推送注册。端点加密存储并带有键控查找令牌,且必须 是公共 HTTPS 目的地。
- **持久。**推送交付作为持久任务运行并有限重试;服务报告订阅已消失(404/410) 时将其删除。
- 负载包含通知标题、可选正文、类型和目标链接,脱敏边界与收件箱一致。
推送要求生产应用(service worker 仅在那里注册)和安全来源。同一 service worker 也提供离线外壳和可安装性:应用清单使 Libre WebUI 可安装,离线导航回退到缓存外壳, 带哈希的构建资源不可变缓存。API 流量绝不缓存。
边界
- 尚未实现按类型的用户偏好;自动化遵循自己的通知设置,离开频道会停止该频道通知。