活动报名后的 WhatsApp 通知,看起来像“报名成功后发条消息”这么简单,但 enterprise/whatsapp_event/models/event_mail.py 和 event_registration.py 展现的是一套更严格的消息编排逻辑:模板必须合规、手机号字段必须明确、模板要先审批通过、报名记录还要知道该由谁负责、该把用户带去哪个 portal 页面。
一、模板不是选上就能发,先看 phone field 是否合规
_check_whatsapp_template_phone_field() 会在事件邮件计划保存时校验:如果 notification_type == 'whatsapp',模板必须设置 phone_field。这说明 Odoo 不允许“先建好活动计划,发送时再看看手机号能不能取到”。
企业里这一步非常关键。活动报名数据来源复杂,手机号字段可能在报名人、联系人或扩展表单里。如果模板没明确 phone field,发送阶段就会变成不可控试错。
二、通知类型不是靠人工记忆,而是由模板模型自动识别
_compute_notification_type() 会检查 template_ref 是否是 whatsapp.template,命中后自动把通知类型设成 whatsapp。也就是说,活动通知的业务语义并不依赖运营同事“记得选对类型”,而是跟着模板对象走。
这套设计能避免后台配置和实际发送通道脱节。模板是什么模型,消息就按什么通道处理,减少了人为误配空间。
三、真正执行前还会过滤掉未审批模板
_filter_template_ref() 会把 notification_type == 'whatsapp' 但 template_ref.status != 'approved' 的计划筛出去,并写 warning 日志。这里最值得注意的是:系统不是假装发送成功,而是显式承认“模板还没通过审批,不能发”。
对活动运营来说,这比“点了发送但没人收到”健康得多。上线流程里,模板审批本来就是消息通道的一部分,而不是可有可无的行政步骤。
四、发送对象是 registration,且消息上下文要走报名记录
_execute_event_based_for_registrations() 在 WhatsApp 场景下直接调用 _send_whatsapp(registrations);后者用 whatsapp.composer,把 res_model 固定为 event.registration,并以 active_ids 形式批量发送。这意味着活动消息真正围绕的是报名记录,而不是活动本身。
这样做的好处是:每条消息都能拿到报名人自己的上下文,例如姓名、活动日期、地点、注册链接,而不是只会发一条活动级别的笼统通知。
五、portal 链接与负责人路由决定了消息是否“能落地”
event_registration.py 的 _whatsapp_get_portal_url() 会优先返回 event.website_url;_whatsapp_get_responsible() 则优先走 event_user_id。再加上 _get_whatsapp_safe_fields() 只开放活动名、组织者、日期范围、地点、负责人电话等安全字段,说明活动 WhatsApp 不是泛化营销短信,而是围绕报名落地页和责任人关系做的业务消息。
如果没有 portal URL,用户收到消息后的下一步动作会断;如果负责人解析不稳定,后续跟进也会乱。这就是为什么活动通知不是“群发一条文案”而已。
实战注意事项
- 模板审批要前置:活动上线前先确认 WhatsApp 模板已 approved。
- phone field 必须明确:不要等到发送失败才追字段。
- 消息内容围绕 registration 设计:确认短信里能承接报名后的下一步动作。
- portal 链接要稳定可访问:否则通知只能起到提醒,起不到转化作用。
新手误区
- 误以为活动 WhatsApp 只是把邮件文案换个发送渠道。
- 误以为模板审批不通过也能先测试批量发送。
- 误以为活动级别信息足够,不需要报名记录上下文。
- 误以为负责人和 portal 链接对通知效果没影响。
主要源码参考
enterprise/whatsapp_event/models/event_mail.pyenterprise/whatsapp_event/models/event_registration.py
DISCUSSION
评论区