企业 移动消息

Odoo 企业版移动消息为什么不是“有新消息就推送”:device token、bus fallback 与未读同步讲透

基于 mail_mobile 源码,讲清移动端消息推送如何围绕 OCN token、线程通知、回退链路与未读状态同步来保证移动体验。

企业 协同办公
进阶 开发者 1 分钟阅读
0 评论 0 点赞 0 收藏 5 阅读

站内已经有一篇 web push 文章,但它更偏浏览器设备生命周期。这一篇故意换主链路:讲移动端。enterprise/mail_mobile/models/res_partner.pyenterprise/mail_mobile/models/mail_thread.py 说明,Odoo 企业版移动消息不是“消息来了就推一下”,而是围绕设备注册、OCN 推送、线程通知和未读状态同步做了一层专门设计。

一、移动推送首先是设备身份问题,不是消息问题

res.partner 上的 ocn_token 注释写得很直白:当任一设备注册后,会从 OCN 服务拿到 token。这个 token 不是附件字段,而是移动设备被纳入推送网络的标志。

也就是说,系统在决定“能不能推”之前,先要回答“这个 partner 现在有没有可用移动设备”。没有 token,后面一切移动通知策略都无从谈起。

二、线程通知不是直接发推送,而是先走统一通知编排

mail_thread.py 里,_notify_thread() 仍然是入口;移动逻辑是以 _notify_thread_by_ocn()_notify_by_ocn_send()_notify_by_ocn_prepare_payload() 的形式插进去的。这种设计很重要,因为它说明:

  • 移动推送不是绕开 mail thread 单干;
  • 它跟桌面通知、频道消息、@mention 一样,属于统一通知流水线的一部分;
  • 只有先经过线程级 recipients 编排,系统才知道哪些人该收到 OCN 消息,哪些人该被排除。

这就是“bus fallback”能成立的基础:移动推送不是独立世界,而是统一消息架构上的一个投递分支。

三、所谓 fallback,本质是不要让移动端因为一种投递方式失效就失联

虽然 mail_mobile 源码不会写一句“这里正式进入 fallback 状态机”,但从它的插入位置你能看出设计意图:当消息线程在正常 bus / discuss 通知链路上运转时,移动端再额外拿到一份适合 OCN 的 payload。这样做的结果是,即使实时前台通信、活跃会话和移动推送三者不总在同一设备、同一时刻成立,用户仍有机会在某个终端上看见提醒。

对企业协同来说,这比“推送一定成功”更现实。移动通知永远会受系统权限、厂商限制、离线状态影响,真正能做的是多给一层可靠的补偿链路。

四、未读同步的关键,不在 badge,而在 payload 携带的线程语义

_notify_by_ocn_prepare_payload() 负责把消息信息打成适合移动端消费的数据包,_notify_get_action_link()_at_mention_analyser() 进一步影响通知内容和落地动作。这里的重点不是 UI 花样,而是:移动端收到提醒后,能否正确打开对应线程、知道这条消息属于哪个对象、并把未读状态与服务端线程状态对齐。

这也是为什么“未读同步”通常不能靠客户端自己猜。真正可信的未读,必须基于服务端消息线程与接收者关系来回写。

五、容易误解的地方

1. 有 token 不等于一定能推送成功

token 只是设备注册成功,不代表用户系统权限没关、第三方通道没抖、厂商后台不拦截。

2. 移动推送不是替代 discuss/bus

它是线程通知的补充分支,而不是另一套独立消息中心。

3. 未读同步不是视觉问题

真正难的是线程状态对齐,不是角标显示成 3 还是 5。

六、实战建议

  • 先排查 partner 上有没有有效 ocn_token
  • 再看消息是否通过 _notify_thread() 进入正确 recipients;
  • 最后才去看移动端是否正确消费 payload、是否能回到对应线程。

七、结论

Odoo 企业版移动消息做对的地方,是把移动推送放进统一线程通知架构里,再用设备 token 和 OCN payload 把移动端接进来。这样即便实时在线、系统推送、用户阅读发生在不同终端,消息仍能维持一条相对稳定的协同链路。

主要源码锚点:

  • enterprise/mail_mobile/models/res_partner.py
  • enterprise/mail_mobile/models/mail_thread.py

DISCUSSION

评论区

想参与讨论?先 登录 再发表评论。
还没有评论,你可以成为第一个留言的人。