6.4 KiB
Notifier 模块实现说明
本文档面向后端维护者,描述 notifier 模块当前的实现决策、已落地范围与后续扩展注意事项。
1. 背景与目标
项目原有的通知能力主要以企业微信机器人为主,并且配置集中在 settings.py 中,属于静态配置方案。
新的 mission 模块希望从一开始就采用:
- 独立 Django app
- task 化投递
- 后台可配置
- signal 与 notifier 动态绑定
- 为后续增加其它通知渠道预留统一接口
因此本次新增独立模块 notifier,并先将 mission 的新信号通知接入该模块。
2. 当前范围
本次实现属于 Phase 1,范围有意收敛:
- 已新增独立 app:
notifier - 已支持后台配置
Notifier - 已支持按
event_key+merchant动态匹配通知器 - 已支持 Celery task 化派发
- 已支持模板化内容渲染
- 已支持第一种渠道:企业微信机器人 webhook
- 已接入
mission的 6 个业务信号
本次没有做的内容:
- 没有改造旧模块的静态通知逻辑
- 没有引入通知订阅/端点拆表
- 没有引入通知投递明细表(如
NotificationDelivery) - 没有做数据库级别审计
- 没有提供对外 API
3. 核心模型
当前模型只有一个主模型:notifier.Notifier
字段职责如下:
merchant: 多商户隔离name: 通知器名称,仅要求在同商户内唯一event_key: 事件标识,用于和业务 signal 对接channel: 通知渠道,当前仅实现wecom_webhooktemplate_key: 模板标识,对应固定目录中的模板文件is_enabled: 启用/停用config: 渠道配置,当前主要存放企业微信 webhook key、msgtype、timeout 等description: 备注
当前将 event_key 直接放在 Notifier 上,而没有拆成“事件订阅 + 通知端点”两层,原因是现阶段追求低复杂度、可快速上线。
后续如果一个通知端点需要订阅多个事件,或者一个事件需要更复杂的启停/优先级/路由策略,再考虑拆模。
4. 目录结构
关键文件如下:
notifier/models.pynotifier/admin.pynotifier/services.pynotifier/tasks.pynotifier/backends.pynotifier/registry.pynotifier/templates/notifier/events/
模板固定目录为:
notifier/templates/notifier/events/
当前已提供的模板:
mission_created.mdmission_replied.mdmission_completed.mdmission_reply_rejected.mdmission_reopened.mdmission_cancelled.md
template_key 与模板文件名一一对应,例如:
template_key="mission_created"- 模板路径
notifier/events/mission_created.md
5. 调用链路
当前通知链路为:
mission.services在事务提交后发送业务 signalmission.handlers监听 signal- handler 将业务对象整理为纯字典 payload
- handler 调用
notifier.services.enqueue_notification_event(...) - notifier 通过 Celery task 异步执行投递
- task 内部调用
dispatch_notification_event(...) - 按
merchant_id + event_key + is_enabled=True查询匹配的Notifier - 逐个渲染模板并调用对应 backend 的
notify(...) - 写详细日志
这里有两个关键约束:
- handler 只做 payload 组装和入队,不做实际发送
- task 层才做真正的通知投递
这样可以保持业务事务与外部通知解耦。
6. 渠道抽象
当前 backend 接口约定为:
BaseNotifierBackend.notify(notifier, content, context) -> dict
当前已实现:
WeComWebhookNotifierBackend
其复用了现有工具:
api_v1.utils.wecom_webhook.send_wecom_webhook_message
这样做的原因:
- 避免重复实现 webhook 发送逻辑
- 保持旧工具可复用
- 新模块只负责“编排”和“动态配置”
7. Mission 已接入事件
当前 mission 已接入以下事件:
mission.createdmission.repliedmission.completedmission.reply_rejectedmission.reopenedmission.cancelled
对应 handler 在:
mission/handlers.py
当前 handler 不再只是打日志,而是会构造 payload 并投递到 notifier task。
8. Admin 配置方式
Notifier 已接入 Django Admin,可进行:
- 添加
- 编辑
- 删除
- 启用/停用
当前推荐的使用方式:
- 在 admin 中新建
Notifier - 选择所属商户
- 选择
event_key - 选择
channel=wecom_webhook - 填写
template_key - 在
config中填写 webhook key 等参数 - 启用
is_enabled
当前 config 示例:
{
"key": "企业微信机器人key",
"msgtype": "markdown",
"timeout_seconds": 10
}
9. 日志策略
本阶段没有引入数据库投递明细表,因此发送明细主要依赖日志。
当前日志覆盖以下节点:
- 任务入队
- backend 发送成功
- 单个 notifier 发送成功
- 单个 notifier 发送失败
- 某事件无匹配 notifier
这满足当前“先可用、后增强”的目标,也符合“暂不做数据库级审计”的约束。
10. 当前风险与注意点
10.1 配置合法性主要依赖管理规范
当前 config 是自由 JSON,没有做更强的结构化校验。
优点是灵活,缺点是后台录入错误会在发送时才暴露。
10.2 模板标识依赖文件存在
template_key 对应的模板文件如果不存在,会在发送阶段报错并记录日志。
这在当前阶段是可接受的,但后续可以考虑在 admin 或 model clean 中增加校验。
10.3 目前仍是“单对象订阅”模型
一个 Notifier 对应一个 event_key。
如果后续出现“一个群同时订阅多个事件”的强需求,可以考虑抽象出 Subscription 层。
10.4 旧通知逻辑尚未迁移
当前仅 mission 新通知走 notifier。
printing、shipment 等旧逻辑仍保留原来的静态方式,不应在本次改动中混改。
11. 后续建议
按优先级建议如下:
- 在 admin 使用中观察
config和template_key是否已足够稳定 - 若 notifier 数量增多,再决定是否拆分“通知端点”与“事件订阅”
- 若需要追踪投递历史,再增加
NotificationDelivery - 当 mission 通知稳定后,再考虑逐步迁移新业务节点到 notifier
12. 当前结论
当前方案已经满足:
- 独立模块
- admin 配置
- task 化通知
- 模板化内容
- 动态 signal -> notifier 路由
- 后续可扩展到多渠道
同时复杂度仍控制在较低水平,适合作为第一阶段正式实现。