先说结论
Odoo 的会议提醒并不是“时间到了就发邮件”。
从 calendar.alarm、calendar.alarm_manager 和官方通知测试看,系统至少拆成两条路径:
- notification:走站内 / bus 提醒
- email:走模板邮件提醒
而且它不是给每个未来事件都铺一堆定时器,而是尽量只维护“下一次可能要触发的提醒点”。
所以最短结论是:
Odoo 会议提醒的核心不是群发,而是用最少的触发器维护最可靠的下一次提醒。
calendar.alarm 为什么先把时间统一成分钟
calendar.alarm 允许用户配置:
- 分钟
- 小时
- 天
但后端会计算 duration_minutes。
这一步很朴素,却非常重要,因为后续无论:
- 查找下一次提醒
- 比较不同 alarm 谁更早
- 做 recurrence 计算
都需要统一量纲。
如果不先归一,很多提醒逻辑会越来越分叉。
为什么 notification 和 email 要走两套链路
notification 的目标是:
- 把提醒推到当前用户的工作界面
- 通过 bus 给出近期即将开始的会议提示
email 的目标则是:
- 给参会人发送正式提醒邮件
- 使用模板渲染正文
- 在必要时带上 ICS 附件
这两者虽然都叫提醒,但协作语义不同:
- notification 更偏个人即时感知
- email 更偏外部可追溯沟通
把两者混成一个开关,通常会让企业不是“提醒太少”,就是“提醒太吵”。
为什么周期会议只保留一个 trigger
官方测试 test_email_alarm_recurrence() 特别强调:
- 创建周期会议时,只生成一个 cron trigger
- 当前一次提醒发完后,再去安排下一次
这是非常成熟的实现。
因为如果一个 12 个月周期会议一创建就铺 12 个触发器,会立刻带来:
- 触发器数量膨胀
- 规则修改后的清理复杂度激增
- 数据库里积累大量未来计划噪音
Odoo 选择只盯“下一次”,就是为了把提醒系统做成滚动窗口,而不是预埋炸弹。
为什么 _send_reminder() 还要考虑 force_send_limit
发送 email reminder 时,Odoo 会参考 mail.mail_force_send_limit。
这说明提醒邮件不是无脑立即发,而是:
- 人少时可以即时发送
- 人多时可能进入队列,避免一次提交过重
这对会议邀请尤其重要。
因为一次大型会议改时间,影响的参会人可能很多。提醒系统必须考虑吞吐,而不是只考虑功能存在。
为什么 organizer 也可能收到 reminder
测试里还验证 organizer 也会被提醒。
这件事看似平常,其实很合理。
因为提醒并不只是“提醒别人来开会”,也是提醒会议组织者自己:
- 会要开始了
- 附件、议程、视频入口是否准备好
协同办公里最怕一种误判:总以为提醒只服务参会者,不服务发起者。
最容易踩的误区
误区一:把 notification 和 email 当同一回事
它们面向的场景完全不同。
误区二:周期会议想一次性预埋所有未来提醒
短期看省事,长期看维护成本很高。
误区三:提醒没发就只查 mail server
notification 走的是另一条链路,先别急着只盯 SMTP。
排错顺序
建议按这个顺序查:
- alarm_type 是
notification还是email - 会议是否 active,参会人是否未拒绝
- cron lastcall 与 trigger 是否正常推进
- 大规模提醒是否被 force_send_limit 改成排队发送
- 周期会议是否只存在单个“下一次提醒” trigger,而不是期待很多未来 trigger
一句话记忆
Odoo 会议提醒不是到点群发,而是用 email 与 notification 两条链路,滚动地维护下一次最该触发的提醒。
DISCUSSION
评论区