协同办公

Odoo @提及为什么不只是高亮名字:mention token、direct recipients 与作者通知边界讲透

在 Odoo 里,@某个人并不只是编辑器里插入一段高亮文本。源码显示,提及背后连着候选人筛选、mention token、direct recipients、作者是否自提醒等一整套通知判断链。

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

先说结论

很多人理解 Odoo 的 @提及时,会把它当成“在评论里插入一个高亮名字”。

这只看到了表层。

从官方源码看,提及真正涉及的是一整条通知链:

  • 谁可以被提及
  • 前端候选人怎么出来
  • 提及对象怎样拿到安全 token
  • 被提及的人怎样变成 partner_ids 直接收件人
  • 作者自己要不要被提醒
  • followers 与 direct recipients 到底怎么分工

一句话说:

Odoo 的 @提及不是富文本装饰,而是把某个人显式拉进本次消息通知范围的机制。


源码从哪里看

这篇最值得一起看的有两块:

候选人与 token

  • addons/mail/models/res_partner.py

这里能看到:

  • get_mention_suggestions()
  • _get_mention_token()
  • _search_mention_suggestions()

通知分发

  • addons/mail/models/mail_thread.py

这里能看到:

  • partner_ids 在通知里的作用
  • notify_author_mention
  • followers 与显式收件人的边界

如果只看编辑器 UI,你会觉得 @提及很轻;如果把这两段源码连起来看,就会知道它其实是通知系统的一部分。


第一步:不是所有人都一样进入提及候选

res_partner.py 里,get_mention_suggestions() 最终会调用 _search_mention_suggestions()

它的排序策略很有意思:

  1. 优先内部用户
  2. 再看一般用户
  3. 最后扩展到普通联系人

而且匹配条件不是只看名字,也会看邮箱。

这说明 Odoo 设计提及时,优先考虑的是:

协同里最常被提及的,往往是系统里的真实工作用户,而不是任意联系人。

这跟纯社交产品不一样,更像办公协作工具的优先级。


第二步:为什么还要有 mention_token

源码里 _get_mention_token() 会给 partner 生成一个带作用域的 token,scope 是 mail.message_mention

这说明前端里出现的“可提及对象”并不是裸露的 partner id,而是带有限权语义的引用。

这背后其实有两个好处:

1. 前端可以安全地表达“这个对象可被提及”

不是把一切内部主键都直接暴露出来。

2. 提及动作可以和权限边界挂钩

也就是:

  • 不是你知道某个 ID 就能随便拼接提及
  • 系统要明确认可这个对象处在可提及范围内

对企业系统来说,这比“插个 @name 文本”严谨得多。


第三步:提及和 partner_ids 是什么关系

mail_thread.py 时,最值得注意的一点是:

通知阶段会区分:

  • followers
  • partner_ids 这类显式收件人

注释写得非常明确:

  • notify_author_mention 允许作者在 direct recipients 中也收到通知
  • notify_skip_followers 时,消息更像 user notification,只依赖显式 recipients

换句话说:

提及最重要的后果,不是文本里多了一个 @,而是消息有了更明确的 direct recipients。

这也是为什么很多业务人员的直觉是:

  • 我被 @ 了,那这次消息应该更“点对点”地到我这里

官方实现正是朝这个方向设计的。


followers 和 direct recipients 到底有什么区别

这两者很容易被混淆。

followers

更像:

  • 你长期关注这条业务记录
  • 以后相关消息大概率也会持续收到

direct recipients / partner_ids

更像:

  • 这一次消息明确点名发给你
  • 它有更强的即时性和针对性

所以在 Odoo 的协同里:

  • follower 是“订阅关系”
  • mention 更接近“本次消息的显式收件关系”

这就是为什么你不能只靠 follower 来理解 @提及。


为什么源码专门有 notify_author_mention

这是一个很容易被忽略、但很说明问题的细节。

通常系统不会给作者自己发通知,否则会产生大量自我提醒噪音。

mail_thread.py 又留了一个例外:

  • 如果作者本人也出现在 direct recipients 里
  • 并且 notify_author_mention 开启
  • 那就允许作者收到通知

这反映出一个很务实的设计选择:

默认不提醒作者,但当作者是被显式点名的收件人时,可以破例。

为什么需要这个例外?

因为现实协同里确实有这种场景:

  • 机器人或自动流程代某人发消息
  • 当前用户既是作者语义上的发起者,也是这条消息必须被提醒的人
  • 或者某些内部提醒需要作者自己也看到通知链落地情况

所以这不是多余开关,而是对复杂协同语义的保留。


为什么说 @提及不是“自动关注”的替代品

很多实现会把“提及某人”直接做成“把某人加为 follower”。

但官方思路并不是这样简单粗暴。

因为两者语义不一样:

提及

强调:

  • 本次消息你要看
  • 这是一次显式点名

关注

强调:

  • 这个记录以后你持续处在消息链里

如果把两者混成一件事,就会出现两个问题:

  • 只是临时点名,却被永久订阅
  • 或者明明应该长期跟进,却只收到一次提醒

所以更好的理解是:

提及是本次消息级别的显式收件,关注是记录级别的持续订阅。


这套设计对办公协同有什么价值

1. 能把“群里说一下”升级成“明确点名谁处理”

这让沟通责任更清楚。

2. 能让提醒精度高于单纯 follower 广播

不是所有关注者都需要每次都被强提醒。

3. 能保留作者不自扰的默认体验

但又允许在必要时精确打破这个规则。

4. 能把候选人筛选和权限安全绑在一起

这比一个普通富文本 @ 功能成熟得多。


做相关定制时最容易踩的坑

1. 只做前端高亮,不接通知链

结果用户以为自己“@到了”,其实没有真正被纳入收件范围。

2. 把提及和 follower 强绑定

结果一次性沟通被错误地变成长期订阅。

3. 忽略作者通知例外

一些自动化或代理发送场景下,提醒行为会和官方语义不一致。

4. 候选人搜索不区分内部用户优先级

办公产品的提及体验会变得很乱。


一句话记忆法

Odoo 的 @提及,本质上是把某个人显式放进这次消息的 direct recipients,而不只是把名字高亮出来。

理解这一句,就能分清 mention、followers 和通知分发之间真正的边界。

DISCUSSION

评论区

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