这篇要先说清一个边界:Odoo 企业版并没有把“appointment 与 WhatsApp 预约提醒”做成一条傻瓜式硬编码链路。真正能复用的是两侧基础设施——enterprise/whatsapp/models/whatsapp_template.py 负责模板、变量与发送动作,enterprise/appointment/models/calendar_event.py 负责 booking、提醒与预约上下文。也正因为如此,企业落地时更需要看懂两边是怎么握手的。
一、WhatsApp 模板的难点不在文本,而在变量和发送资格
whatsapp.template 里最值得看的不是“支持 header/body/footer”,而是那一串校验:_check_body_variables()、_check_header_variables()、_check_buttons()、_check_phone_field()、_compute_warning_message()。这说明 Odoo 不是把 WhatsApp 当成普通即时消息,而是当成一个受模板规范严格约束的外部通道。
对预约提醒来说,这意味着:预约时间、地点、主持人、确认链接这些信息,必须能稳定映射到模板变量,否则看起来只是“差几个占位符”,实际上整条提醒链路都发不出去。
二、appointment 侧真正管理的是 reminder window 与 booking 上下文
calendar_event.py 里,预约事件会把 appointment_type_id.reminder_ids 带到 event 上;同时 booking 本身又携带 appointment_booker_id、资源、容量等上下文。你如果想把提醒切到 WhatsApp,不能只盯消息模板,还要回答两个问题:
- 这条提醒在什么时候触发,落在哪个 reminder window?
- 触发时能不能从 booking 上拿到完整变量和值?
所以标题里的“template window”其实说的是两件事同时成立:WhatsApp 有自己的模板使用窗口和变量约束,appointment 又有自己的提醒时间窗口。
三、真正的 booking handshake 是“预约对象能不能被消息模板消费”
whatsapp.template 里的 _get_send_template_vals()、_get_body_component()、_get_button_components() 负责从业务记录取值并组装发件参数。落到预约提醒时,本质是在问:calendar event 或其关联对象,能不能为模板提供电话号码、变量值和可点击动作。
这就是为什么很多团队“看起来只差一步”却总发不起来。问题不是 API 挂了,而是 appointment booking 的数据结构并没有天然等于 WhatsApp 模板的输入结构,握手层必须补齐。
四、按钮与回流动作决定提醒是不是闭环
button_create_action()、button_delete_action()、URL button 相关逻辑提示我们:WhatsApp 模板不是只能单向通知。对预约提醒来说,真正有价值的是把确认、改期、查看详情这类动作做成可回流入口。
但这里也最容易踩坑:如果你把 appointment booking 的修改动作直接暴露成一个 WhatsApp 按钮,却没有处理权限、过期时间和重复点击,就会把提醒链路变成数据污染入口。
五、实战里最容易误解的点
1. 不是 appointment 原生就带 WhatsApp 提醒
企业版给的是可拼接的基础能力,不是所有业务都自动打通。
2. 模板审核通过,不等于业务字段就对得上
变量、电话字段、按钮动作都必须跟 booking 记录对齐。
3. reminder window 不是越多越好
预约前 24 小时、2 小时、15 分钟都发,常常会把客户烦到屏蔽。
六、建议的落地顺序
- 先确定 appointment 哪些 booking 字段可直接作为 WhatsApp 模板变量;
- 再定义提醒窗口,避免同一客户重复触达;
- 最后才设计确认 / 改期按钮与回流处理。
七、结论
Odoo 企业版的 WhatsApp 预约提醒,不是“模板一发就行”,而是“提醒窗口、模板变量、电话号码与 booking 回流动作能否形成一次可信握手”。看懂这一点,你就不会再把预约提醒当成一个纯营销短信问题。
主要源码锚点:
enterprise/whatsapp/models/whatsapp_template.pyenterprise/appointment/models/calendar_event.py
DISCUSSION
评论区