先说结论
Odoo 的邮件 alias 从来不只是“给模型配个邮箱入口”。
从 mail.alias、mail.alias.mixin 和 mail.gateway.allowed 可以看出,官方主要在守四类边界:
- alias 域名是否和公司 / 所属记录匹配
- alias 联系人策略是否允许这个发件人进入
- alias 默认值是否是合法可解析的字典
- 邮件网关是否会因为高频自动邮件或回环被打爆
所以最短结论是:
alias 是业务入口,但它首先是一个必须被严密约束的安全边界。
为什么 alias 域名要校验公司归属
_check_alias_domain_id_mc() 会验证:
- alias owner record 属于哪个公司
- target document 属于哪个公司
- alias 所用域名是否允许给这个公司使用
这一步非常关键。
因为多公司环境下,如果 alias 域名可以随便跨公司挂,后果会很严重:
- 邮件入口与业务实体归属错位
- 外部回复落进错误公司上下文
- 审计上根本说不清这封邮件为什么进了这边
所以 Odoo 宁可直接报 ValidationError,也不放任 alias 在公司边界上串线。
为什么 alias_name 连字符集都要限制
_check_alias_is_ascii() 明确要求 local-part 只能走 ASCII 的 dot-atom 规则。
这看起来保守,但实际上很务实。
因为邮件地址本来就是边界最多、兼容性最差的输入之一。对业务入口来说,别把奇怪字符放进 local-part,本身就是降低事故率。
官方这一步的价值不是“优雅”,而是减少网关歧义。
为什么 alias_contact 是真正的入口安全阀
alias_contact 支持:
- everyone
- partners
- followers
这意味着 alias 不是“知道地址就能写进系统”。
它还要决定:
- 所有人都能进
- 只有已认证 partner 才能进
- 只有跟随该文档 / 频道的人才能进
很多团队出问题,不是 alias 没配上,而是 alias 开得太大。
尤其把高价值业务对象入口长期设成 everyone,很容易把垃圾邮件、误投邮件和不相关对话一起引进来。
为什么 alias_defaults 必须是可解析字典
源码对 alias_defaults 做 literal 校验,要求它必须是字面量 python dict。
这背后其实是两层保护:
- 让默认值配置可预测、可解析
- 防止把 alias 入口变成一段任意表达式执行点
alias 本来就是系统对外入口,如果默认值还能无限自由发挥,维护和安全都会很难收住。
为什么还要防 bounce / catchall 冲突
_check_alias_domain_clash() 会阻止 alias 名称和:
- bounce alias
- catchall alias
冲突。
因为这些地址在网关里有特殊语义:
- bounce 用于退信
- catchall 用于某些续帖 / 兜底场景
如果业务 alias 和它们撞名,整个路由语义就会开始混乱。
mail.gateway.allowed 为什么不是白名单特权,而是反循环阀门
mail.gateway.allowed 的说明非常直白:
- 系统会限制某段时间内 alias 可创建的记录数
- 目的是防止 spam 和 reply loop
- 只有被允许的可信地址,才可以跳过这类限制
这说明 Odoo 非常清楚邮件网关的老问题:
- 自动系统互相回信
- 外部机器人高频推送
- 某个 alias 被错误集成后疯狂灌入邮件
Allowed List 的设计重点不是“给 VIP 放权”,而是:
在需要接收高频自动邮件时,明确告诉系统哪些来源是可信的,别把正常集成和异常风暴混在一起。
最容易踩的误区
误区一:alias 只是地址映射,不用管公司边界
多公司环境下一定会踩雷。
误区二:高价值入口长期开 everyone
这会把最外层防线主动打开。
误区三:邮件风暴来了,只怪 SMTP
很多问题发生在进入 SMTP 之前的网关入口和回环限制层。
排错顺序
如果用户说“alias 不工作”或“邮件突然被挡”,建议查:
- alias 域名是否属于正确公司
- alias_name 是否与 catchall / bounce 冲突
- alias_contact 是否把来信人挡在外面
- alias_defaults 是否是合法字典
- 是否触发了 loop / threshold 保护,而该自动来源又没加入
mail.gateway.allowed
一句话记忆
Odoo 的邮件 alias 不是一个方便的邮箱别名而已,它是业务系统最外层的邮件入口闸门。
DISCUSSION
评论区