很多公司上线 Odoo 协同时,都会有一种模糊理解:
- 关注了记录,就会收到邮件;
- 收到通知,就说明被关注了;
- 被分配了 activity,就等于成了关注者;
- chatter、邮箱、待办,本质是一回事。
这套直觉很省脑子,但不对。
从 /home/ubuntu/odoo-temp/addons/mail/models/mail_thread.py 和 mail_activity_mixin.py 看,Odoo 其实在维护三套相关但不同的机制:
- followers:谁跟着这条记录;
- notifications:消息发出去以后,走 inbox、email 还是 web push;
- activities:这是待办任务,不是消息订阅本身。
一、followers 解决的是“谁跟着这条记录”
message_subscribe() 的职责很明确:
- 做访问校验;
- 把 partner 插到
mail.followers; - 如有 subtype,则按 subtype 建订阅关系。
也就是说,followers 的核心语义不是“立刻发一封邮件”,而是:
以后这条记录上的相关消息,哪些人原则上属于接收候选。
它更像“订阅关系”,不是“发送动作”。
二、真正发通知时,走的是 _notify_thread()
消息创建以后,_notify_thread() 才会开始算接收人,并把它们分流到不同通知通道。
源码里这一段特别关键:
- 先
_notify_get_recipients(...)算 recipients; - 再根据情况走:
_notify_thread_by_inbox()_notify_thread_by_email()_notify_thread_by_web_push()
这说明两个很重要的事实:
1)“通知”与“关注”不是同义词
一个人是 follower,说明他进入了候选集; 但最终走 inbox、email 还是别的通道,还要看接收人属性和通知策略。
2)“有消息”不等于“一定发邮件”
很多内部用户看到的是 Inbox 通知,而不是 Email; 有些外部联系人可能主要走邮件; 某些情况下甚至会延迟调度发送。
所以排查“为什么没收到邮件”时,不能只看有没有 follower,还要看:
- 这条通知最终分配到什么
notif通道; - 接收人是内部用户、共享用户还是纯 partner;
- 当前消息是否符合邮箱发送条件。
三、auto subscribe 只是“自动帮你加关注者”,不是 activity 引擎
_message_auto_subscribe_followers() 的默认行为很典型:
- 如果某个跟踪字段(比如
user_id)变了; - 而且它指向
res.users; - 那么新负责人会被自动订阅,并可能收到一条“你被指派了”的通知模板。
这就是很多业务单据在切负责人后,对方会自动开始跟记录的原因。
但要注意:
- auto subscribe 解决的是 follower 关系;
- 它不是 activity 记录本身;
- 它也不保证所有场景都自动发 email。
四、activity 是待办,不是消息订阅
activity_schedule() 在 mail_activity_mixin.py 里做的事情非常清楚:
- 创建
mail.activity记录; - 写上
activity_type_id、date_deadline、user_id、note 等。
它的语义是:
给某人安排一件待办。
而不是:
把某人变成这条记录的 follower。
所以你会看到非常典型的现象:
- 某人被安排了 activity,但并没有成为长期 follower;
- 某人是 follower,会收到相关消息,却不一定有任何待办;
- 某人既是 follower,又被安排了 activity,这时两套机制同时存在。
五、为什么现场最容易混淆这三件事
因为在用户体验上,它们都长得像“系统提醒”。
但本质不同:
- followers:订阅关系;
- notifications:消息投递通道;
- activities:待办任务。
这三者有交集,但不能互相替代。
六、几个特别常见的误解
1)“把人加成 follower 就等于给他派任务”
不对。follow 只是订阅,不是待办。
2)“给人建了 activity,他以后就会一直收到这条记录消息”
也不对。activity 不自动等于 follower。
3)“没收到邮件,就是没被通知”
也不对。他可能收到了 Inbox 或 web push,只是不是 email。
七、一个更靠谱的排查顺序
如果现场有人说“我怎么没收到提醒”,我建议这样查:
- 这人是不是 follower;
- 如果不是,他本来是否应该被自动订阅;
- 如果是 follower,这条消息通知渠道最终分流到哪;
- 这是消息通知问题,还是其实应该建一条 activity;
- 这条业务需求到底要的是“订阅消息”还是“必须处理的待办”。
很多需求吵半天,最后只是产品语义没说清。
总结
Odoo 协同里最容易混掉的,不是技术实现,而是业务语义。
从源码看,这三件事必须分开理解:
message_subscribe():建立 follower 关系;_notify_thread():把消息按通道发出去;activity_schedule():创建待办活动。
如果只记一句,就记这句:
Follower 解决“谁跟着记录”,通知解决“消息怎么送”,Activity 解决“谁要去做事”。
DISCUSSION
评论区