Repository navigation
Releases: chromoany/dsh-notify-me
Release list
dsh-notify-me v1.14.2
1.14.2
桌面端「测试「审批按钮」」点了没反应,问题不在按钮,在通知标签的长度。
Windows 拒收 tag 超过 64 字符的通知,而 Chromium 交给平台的最终 tag 不是我们的字符串,是 n#<origin>#<tag>——桌面页面 dsh-app://app 先占 16 字符,留给插件 48。审批测试的 key 是 test:approval:<13 位毫秒>,整条 tag 51 字符、合计 67,new Notification() 构造时直接抛 The size of the notification tag is too large;异常被 showToast() 的空 catch 吞掉,而设置页早就写了「已发送」。
现在所有 tag 统一走 toastTag():按 location.origin 算出平台前缀的占位,装不下就保留可读前缀、尾部换 FNV-1a base36 哈希收口;审批 tag 仍由 closeNotificationTag() 用记录里的同一个字符串关闭,审批测试的 key 缩短到 t + base36 毫秒(tag 33 字符)。平台拒收也不再静默——失败记进 debug().lastToastReject,设置页改报「系统拒收了这条通知:<原因>」,不再谎报成功。
(issue #18)
安装 / 升级
dsh plugin add dsh-notify-me
# 或升级
dsh plugin update dsh-notify-me完整变更见 CHANGELOG。
dsh-notify-me v1.14.1
1.14.1
抬窗路由的安全闸门换了口径。1.14.0 把 x-dsh-notify-me-focus: focus 头当成防线,理由是「跨源页面带这个头要先过预检」——这条对 DNS rebinding 不成立,rebinding 页面与目标地址同源,能带任意自定义头、不触发预检。
现在校验的是本地性,三层:对端地址必须 loopback;Host 必须是 loopback 名(127.0.0.1 / localhost / [::1],可带端口);带了 Origin 就必须与 Host 同源。任一条不满足回 403,reason 写 bad-remote / bad-host / cross-origin。OPTIONS 一律 405,从不回 CORS 头。
Host 是真正的分界:壳转发 dsh-app://app 时会把 host 删掉、由 fetch 按 loopback URL 重填,所以桌面页面永远带 loopback 的 Host;rebinding 的页面 Host 仍是攻击者域名。自定义头保留,但只当「这是页面发的」标记。
桌面端行为不变,抬窗链路照旧。已发版用户升级后无需改配置。
安装 / 升级
dsh plugin add dsh-notify-me
# 或升级
dsh plugin update dsh-notify-me完整变更见 CHANGELOG。
dsh-notify-me v1.14.0
1.14.0
桌面端点通知抬不起窗的问题修好了。1.5.2 起用的是 dsh://open 深链加隐藏 iframe,指望单实例把窗口顶到前台;在 0.2.1-rc.2 上复测三次三次失败,第二个实例约 130 ms 退出码 1,窗口的 IsIconic 一动不动。这条通道已经删掉,不留静默兜底。
现在页面点击 POST 到宿主注册的 exact 路由 /__dsh-notify-me/focus-window,宿主跑一次 PowerShell 做原生激活:按 pid 选出主窗口,先合成一次 ALT 抖动给当前线程前台权限,再 SetForegroundWindow,窗口最小化就先恢复,最后拿 GetForegroundWindow() 和目标句柄比对决定回 200 还是 202。思路来自 discussions #10446 里 @xinming-chenniang 的实测——单独调 SetForegroundWindow 被前台锁拒绝是调用级规则,跟锁超时无关,合成一次 ALT 按键就绕过去了。
真机数据(powershell.exe 5.1,pid 72788 那个窗口):窗口在前台、最小化后被别的应用顶掉、未最小化被盖住,三个场景各跑三次全部成功,wall 618–782 ms,脚本内部最坏 434 ms;端到端从触发路由到返回 200 约 600 ms。抬不起来的场合(提权窗口、虚拟桌面、托盘隐藏)返回 202 并带原因,window.__dshNotifyMe.debug() 里新增的 raiseLast 记着最后一次的结果。
路由只认带 x-dsh-notify-me-focus 头的 POST:其它方法 405,非桌面宿主 501,头不对 403,另有 8 秒超时和 400 ms 合并。跨源页面发不出这个自定义头(预检没人应答),所以它同时是 CSRF 闸门。只 Windows 有效。
安装 / 升级:
dsh plugin --profile web add dsh-notify-me@1.14.0详见 CHANGELOG。
dsh-notify-me v1.13.0
1.13.0
回应 #17:外部推送新增 飞书群机器人 / Server酱(Turbo 与 Server酱³)/ WxPusher 三种目标——手机上走系统级推送通道、不用保活。Discord 在国内连不上、Bark 又没有安卓端的尴尬,到这里可以绕开了。
同版把「能发出去」补成「可靠地发出去」:明显临时的失败(网络中断、5xx、429)按 2 秒 / 6 秒退避重试,重试仍失败进「失败记录」(最多 10 条,只留标题摘要与主机名,不留完整端点);每个目标可单独启停并显示最近一次投递结果;自定义目标可带 X-DSH-Notify-Signature(HMAC-SHA256),飞书按官方算法签名;消息模板支持 {{title}} / {{body}} / {{event}} / {{time}} / {{session}}。
钉钉没有做成目标类型:它的接口不放行任何 CORS 头,而且只收 application/json,浏览器页面既读不到响应也发不出合规请求。要用钉钉,请自建一个中转,再用「自定义 Webhook」指向它。
安装 / 升级:
dsh plugin --profile web add dsh-notify-me@1.13.0详见 CHANGELOG。
dsh-notify-me v1.12.0
1.12.0
收编 #16:idleMinutes(人在前台、但 3 分钟没输入也算离开)、donePolicy(「回复完成」提醒时机三选一:仅后台 / 仅当前对话静默 / 总是提醒)、autoDismiss(通知自动消失三档:离开时保留 / 总是关闭 / 从不关闭),并补上闲置到期补发被压下的审批。
同时彻底删掉页内审批卡片。1.11.0 删掉浮层通道后,桌面端还留着一层兜底卡片,结果审批提醒同时弹系统通知和页内卡片;现在审批提醒只走系统通知,桌面端点通知回到对话里裁决。
安装 / 升级:
dsh plugin --profile web add dsh-notify-me@1.12.0详见 CHANGELOG。
dsh-notify-me v1.11.0
移除
- 「提醒方式」二选一整段删掉:设置页不再有「通知类型」分段选择器,系统通知是唯一通道。页面浮层当独立通道只在窗口处于前台时看得见,而需要提醒的时刻恰恰是窗口在后台;选了浮层、切走之后后台只剩提示音和标题标记。1.10.6 用「后台补发系统通知」来救,又违背了选定的通道,所以这个选项直接去掉。
channel/overlay/toast三个配置键失效,旧配置读取时清掉,其余设置不动;overlayCorner保留。window.__dshNotifyMe.debug()去掉channel、toast,overlay更名card。
保留
- 桌面端审批卡片:
dsh-app://注册不了 Service Worker,系统通知带不了「同意 / 拒绝」,所以审批提醒仍在窗口角落画一张可点卡片(12 秒回收、同一条审批不叠卡),位置改由「审批卡片位置」控制。 - 1.10.5 的「窗口失焦也算后台」原样保留。
- 1.10.3 的「每条通知独立 tag」原样保留(#15 已修)。
完整对比:v1.10.6...v1.11.0
dsh-notify-me v1.10.6
修复
- 提醒方式选「页面浮层」时,窗口在后台就等于没有提醒:浮层卡片画在页面里,窗口被别的应用挡住(或最小化)时它既看不见、又会在 12 秒后自己收起,于是只剩下提示音,屏幕上什么都没有。现在浮层通道在页面离开前台时会额外发一条系统通知——那是唯一能追到「人在别处」的手段;窗口回到前台则不加,屏幕上还是一张卡片,不重复。系统通知仍受通知权限约束,未授权时保持原样(只有卡片)。
新增
- 设置页「通知类型」下方新增「窗口在后台时补发系统通知」开关(默认开),关掉后浮层严格留在页面内。
变更
- 设置页「页面浮层提醒」的说明补上这条例外。
安装:dsh plugin add dsh-notify-me(或升级后重启 DSH)。
Full Changelog: v1.10.5...v1.10.6
dsh-notify-me v1.10.5
修复
- 桌面端窗口被遮住时「回复完成」不提醒:插件判断「你离开了」原本只看页面的
document.hidden/visibilityState,而桌面壳里把 DSH 窗口切到别的应用后、或被别的窗口盖住时,页面依然是visible—— 只有最小化或整窗被遮挡才会变成hidden。于是「只在后台提醒」的回复完成提醒在窗口只是被盖住时被静默丢弃。现在把窗口焦点也算进「离开」:页面失焦即视为后台;失焦瞬间还会补发此前因为「就在你眼前」而被压下的审批提醒;窗口回到前台后照常安静。设置页相关开关文案同步改为「窗口在前台时也提醒」,写明「切走 / 被遮挡 / 最小化」都算后台。
测试
- 冒烟新增
awayWithoutHiding用例:焦点在时回复完成静默、失焦后同一页发出提醒、回焦再次静默、visibilityState全程保持visible、失焦时补发被压下的审批提醒。
升级
- Web:刷新页面即可(npm 版
dsh-notify-me@1.10.5)。 - 桌面端:重启客户端后生效(插件在启动时加载)。
完整变更:v1.10.4...v1.10.5
dsh-notify-me v1.10.4
桌面端:审批的「同意 / 拒绝」现在画在窗口里的卡片上
桌面壳拿不到 Service Worker(dsh-app:// 注册被拒),带按钮的审批通知在桌面端只剩一行标题,点不出裁决。1.10.4 起,拿不到 Service Worker 时改在窗口角落画一张卡片:
- 标题 + 正文,正文过长可就地展开「详情」
同意/拒绝两个按钮,走的是和系统通知完全同一条裁决路径(allowed-once/rejected),不多放行任何东西- 12 秒自动收起;同一条审批不叠第二张卡
- Web 端不变:Service Worker 可用时仍是带按钮的系统通知
- 关掉「审批通知上直接裁决」时不画卡,只发普通提醒
已知限制:卡片画在页面层,浮不出 DSH 窗口——窗口最小化或被别的应用盖住时看不见卡片,这时靠仍会弹出的系统通知提示。
修复
- 页内
api.version与package.json对齐(1.10.3 的发版提交只改了 package.json)。
升级
dsh plugin --profile web add dsh-notify-me # Web,会拿到 1.10.4桌面端:插件 → 添加插件,输入 dsh-notify-me,装完完全退出并重启 DSH Desktop。
完整改动见 CHANGELOG。
dsh-notify-me v1.10.3
修掉桌面端「同类系统通知只弹第一条」的问题(#15)。
普通通知的 tag 以前按类别固定(dsh-notify-me-<kind>),指望 renotify: true 让同 tag 的新通知替换并重新提示;Electron 不认这个标志,第二条起就被静默替换,横幅不再出现。现在每条普通通知用独立 tag(类别 + 计数器 + 时间戳),同类通知改为堆叠,占用时间仍由 5 秒/12 秒的自动收起兜住。
审批通知的 tag 保持稳定,closeNotificationTag() 在请求被处理时撤回对应那条的逻辑不变。
冒烟新增回归用例:连发三次「回复完成」断言三条 tag 互不相同、审批 tag 前缀不变。