其他深度

Odoo Mass Mailing 为什么不是“点发送就完了”:黑名单、seen list、队列发送与失败重试讲透

真正决定群发系统是否稳定的,不是编辑器,而是发送前如何排除 opt-out、如何避免重复触达、如何用队列推进,以及失败后怎么重试。Odoo 在 mailing.py 里把这些都做成了明确链路。

其他
进阶 开发者 1 分钟阅读
0 评论 0 点赞 0 收藏 5 阅读

先说结论

群发最怕的不是“没发出去”,而是“该排除的没排除、不该重复的重复了、失败后还不知道怎么补救”。Odoo 的发送引擎核心,其实都在这些看不见的地方。

第一层:opt-out list 为什么优先于发送动作

_get_opt_out_list() 先把目标模型自己的退订逻辑收上来,再交给后续发送流程使用。这说明群发系统并不是“先发,失败了再说”,而是先定义不该发给谁。真正成熟的系统,第一步不是扩大发送量,而是收紧错误触达。

第二层:seen list 在防什么

_get_seen_list() 会去查已经被当前 mailing 或 campaign 触达过的邮箱,从而避免重复发送。尤其在 A/B、分批和重试场景里,这层非常关键。否则你明明是在“补发”,结果用户收到两三封一样的内容。

第三层:剩余收件人为什么还要再算一次

_get_remaining_recipients() 会基于候选收件人,再减去已有 trace 的 res_id。也就是说,Odoo 不信任“理论名单”,而是更相信“真正已经留痕的发送事实”。这是一种很稳的设计:以 trace 为准,而不是只看列表。

第四层:为什么发送要走队列

_process_mass_mailing_queue() 会扫 in_queue / sending 状态的 mailing,再逐个推进。这意味着群发不是一个前台同步动作,而是后台批处理流程。对于大名单或多批次发送,这层队列化是系统稳定性的前提。

第五层:失败重试为什么先删旧失败邮件和 trace

action_retry_failed() 并不是简单再点一次发送,而是先把 exception 状态的 mail.mail 及其 trace 清掉,再重新排队。这样做可以避免旧失败记录和新尝试交织,导致统计和状态混乱。

最容易误解的三个点

  • 误区一:群发系统的核心是编辑器。真正难的是名单过滤、去重和恢复。
  • 误区二:失败重试就是再发一遍。没有先清失败痕迹,统计很容易乱。
  • 误区三:只要名单没重复就不会重复触达。A/B 和多批次下还需要 seen list 兜底。

实战上怎么用更稳

  • 查“为什么有人收了两次”时,优先看 seen list 与 trace,而不是先看联系人表。
  • 查“为什么没发出去”时,分清是被 opt-out 排除了,还是进入 exception 失败。
  • 做大批量邮件时,别绕开队列直接同步发,短期省事长期会翻车。

最后总结

Mass Mailing 能不能稳定,不取决于按钮叫不叫“发送”,而取决于它发前排除了谁、发中怎么推进、发后如何修复。Odoo 把这三步都做得很清楚。

DISCUSSION

评论区

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