# Notifier 管理人员配置说明 本文档面向后台管理人员,说明如何在 Django Admin 中配置 `Notifier` 与 `NotifierRoute`,让系统在指定业务事件发生时自动发送通知,并支持按任务分类分发。 ## 1. 两层结构 当前通知配置分成两层: - `Notifier`:通知器本体,负责“发到哪里、用什么模板、走什么渠道” - `NotifierRoute`:通知路由,负责“什么事件、什么任务分类,应该命中哪个 Notifier” 可以这样理解: - `Notifier` 是“发信工具” - `NotifierRoute` 是“分发规则” ## 1.1 当前文档适用范围 这份文档只描述“当前已经确认可由后台管理人员自行配置”的 `Notifier` 能力。 截至目前,已经稳定确认、并且适合由后台人员自行配置的渠道有: - `wecom_webhook` - `message_api` 注意: - `wecom_webhook` 和 `message_api` 的配置方式不同,不要混用字段。 - `message_api` 适合发企业微信应用消息,可以发文本,也可以发单篇图文。 - 当前 ERP 只是 `message_api` 的调用方,不直接管理企业微信凭据。 - 当前 `message_api` 默认仍由开发组提供模板文件,管理人员主要负责选择正确的 `template_key` 和填写 `config`。 ## 2. 当前已支持的 mission 事件 目前 `mission` 模块已接入以下事件: - `mission.created` - `mission.replied` - `mission.completed` - `mission.unreplied` - `mission.reply_rejected` - `mission.reopened` - `mission.cancelled` 所有这些事件都支持通过 `NotifierRoute` 进行分类路由。 ## 2.1 任务分类上的 payload 增强器 除 `Notifier` 和 `NotifierRoute` 以外,部分任务分类还可以额外配置 `payload 增强器`。 它的作用不是决定“发给谁”,而是在发送通知前,先对任务描述做一次固定规则的加工,再把结果交给模板使用。 当前已提供的增强器: - `structured_description_v1` 当前配套可直接使用的 `message_api` 模板: - `mission_structured_description_text` - `mission_structured_description_news` 适用场景: - 某些模板不直接消费整段 `任务描述` - 而是希望从 `任务描述` 中拆出标题、正文、链接这类结构化字段 当前 `structured_description_v1` 的处理规则: 1. 忽略任务描述第一行 2. 如果某一行以 `款式图:` 开头,则提取该行后面的图片地址为封面图字段,并且该行不再参与标题/正文内容 3. 如果最后一行里包含 `http://` 或 `https://` 链接,则提取为跳转链接字段,并且该行不再参与正文拆分 4. 之后按第一个空行拆分:空行前为标题,空行后为正文 5. 如果没有空行,则剩余内容全部作为标题,正文为空 模板可使用的新增字段: - `parsed_description_title` - `parsed_description_body` - `parsed_description_url` - `parsed_description_image_url` 如果你希望直接复用开发组已经准备好的模板,推荐: - `channel = message_api` - `template_key = mission_structured_description_text` 这个模板会把上面三个字段组织成一条可直接发送的文本消息。 如果你希望发送单篇图文消息,可以使用: - `channel = message_api` - `template_key = mission_structured_description_news` 这个模板除了依赖增强器产出的字段外,还要求在 `Notifier.config` 中填写: ```json { "agent_ids": [1000007], "image_url": "https://cdn.example.com/covers/mission-news.png" } ``` 可选地也可以填写一个兜底跳转地址: ```json { "agent_ids": [1000007], "image_url": "https://cdn.example.com/covers/mission-news.png", "url": "https://erp.example.com/missions/fallback" } ``` 说明: - 优先使用任务描述里解析出的链接作为 `news.url` - 优先使用任务描述里 `款式图:` 解析出的图片地址作为 `news.image_url` - 如果解析不出链接,则回退到 `Notifier.config.url` - 如果解析不出图片,则回退到 `Notifier.config.image_url` - 如果 `Notifier.config.image_url` 也为空,则回退到系统级默认空值图 `MESSAGE_API_DEFAULT_NEWS_IMAGE_URL` 当前默认值是: - `https://via.placeholder.com/640x360.png?text=No+Image` 如果你们后续有自己的线上空值图,建议在环境变量里覆盖这个默认值,而不是继续依赖外部占位图服务。 补充说明: - 该增强器是否启用,由任务分类决定 - 同一个模板可以被多个分类复用,但只有启用了增强器的分类才会得到这些解析字段 - `mission_id`、`category_name` 等原始审计字段仍然会照常传递 ## 3. 当前支持的分类路由能力 路由匹配规则如下: 1. 先按 `merchant + event_key + is_enabled=True` 匹配启用中的路由 2. 如果当前任务带有分类: - 优先匹配该分类的专用路由 - 同时允许匹配“任务分类为空”的通配路由 3. 如果同一个 `Notifier` 同时命中了专用路由和通配路由,只发送一次,优先使用专用路由 这意味着你可以实现: - 某个分类发到专门群 - 未单独配置的分类发到通用群 - 同一事件同时发多个群 ## 4. Admin 中的两个入口 进入 Django Admin 后,主要会看到两个对象: - `通知器` - `通知路由` 推荐的管理方式: 1. 先创建 `Notifier` 2. 再创建或维护它的 `NotifierRoute` 在 `Notifier` 详情页中,也可以直接通过 inline 管理该通知器下的路由。 如果需要启用上面的 `payload 增强器`,还需要进入 `任务分类` 管理页,在具体分类上选择对应增强器。 ## 5. Notifier 字段说明 ### 5.1 merchant 所属商户。 通知器只会服务于该商户下的路由和事件。 ### 5.2 name 通知器名称,仅用于后台识别和管理。 建议命名方式: - `任务通知-生产群` - `任务通知-售后群` - `任务通知-管理群` 同一商户下名称不能重复。 ### 5.3 channel 通知渠道。 当前可选: - `wecom_webhook` - `message_api` 补充说明: - 如果你在后台将来看到新的 channel 选项,不代表它已经进入“可自行配置”的稳定状态。 - 当前管理人员应只配置已经明确说明过的 channel。 - 如果要发送企业微信应用消息,请选 `message_api`,不要继续选 `wecom_webhook`。 ### 5.4 template_key 模板标识。 系统会根据这个字段去固定目录查找模板文件。 当前模板目录: `notifier/templates/notifier/events/` 例如: - `wecom_webhook` 渠道下:`template_key = mission_completed` - 对应模板文件:`notifier/templates/notifier/events/mission_completed.md` - `message_api` 渠道下:`template_key = mission_completed` - 对应模板文件:`notifier/templates/notifier/events/mission_completed.json` 可以把它理解为: - `.md` 模板:最后会渲染成一段文字 - `.json` 模板:最后会渲染成一组“结构化消息字段” ### 5.5 is_enabled 是否启用通知器本体。 - 勾选:该通知器可被路由命中 - 不勾选:即使路由存在,也不会发送 ### 5.6 config 渠道配置,JSON 格式。 当前企业微信机器人建议配置: ```json { "key": "你的企业微信机器人key", "msgtype": "markdown", "timeout_seconds": 10 } ``` 说明: - `key`:企业微信机器人 webhook key - `msgtype`:当前建议使用 `markdown` - `timeout_seconds`:请求超时时间,通常保持默认即可 特别提醒: - 当前不要自行在 `config` 中增加诸如 `corp_id`、`agent_id`、`secret`、`to_user`、`to_party`、`to_tag` 等字段,除非开发组已经单独通知并提供正式说明。 - 这些字段不属于当前已经确认可交付给管理人员配置的范围。 当前 `message_api` 渠道建议配置: 文本消息场景: ```json { "agent_id": 1000007, "timeout_seconds": 10 } ``` 图文消息场景: ```json { "agent_ids": [1000007, 1000008], "timeout_seconds": 10 } ``` 说明: - `agent_id`:企业微信应用 ID,适用于文本消息 - `agent_ids`:企业微信应用 ID 列表,适用于图文消息 - `timeout_seconds`:请求超时时间,通常保持默认即可 特别提醒: - `message_api` 当前不要求管理人员填写任何企业微信系统级配置。 - 对 ERP 来说,只需要知道 `message_api` 的访问地址和固定 `Authorization`。 - `message_api` 下应优先使用开发组已提供好的 `template_key`,不要自行猜测 JSON 字段名。 ### 5.7 description 备注说明,非必填。 ## 6. NotifierRoute 字段说明 ### 6.1 merchant 所属商户。 必须与关联的 `Notifier` 属于同一商户。 ### 6.2 notifier 要使用的通知器。 ### 6.3 event_key 要监听的业务事件。 例如: - `mission.created` - `mission.completed` - `mission.unreplied` ### 6.4 mission_category 任务分类路由条件。 - 为空:表示该事件的通配路由,适用于所有未被更具体路由覆盖的任务分类 - 不为空:表示只处理该任务分类下的任务事件 ### 6.5 is_enabled 是否启用该路由。 - 勾选:路由参与匹配 - 不勾选:路由不会命中 ### 6.6 description 备注说明,建议写清楚用途,例如: - `任务创建-生产分类专用路由` - `任务完成-所有分类默认路由` ## 7. 推荐配置步骤 以“任务创建时,生产分类发生产群,其他分类发管理群”为例: ### 第一步:创建两个 Notifier 1. 创建 `Notifier A` - `name = 任务通知-生产群` - `channel = wecom_webhook` - `template_key = mission_created` - `config` 填生产群机器人 key - `is_enabled = True` 2. 创建 `Notifier B` - `name = 任务通知-管理群` - `channel = wecom_webhook` - `template_key = mission_created` - `config` 填管理群机器人 key - `is_enabled = True` ### 第二步:创建路由 1. 创建 `NotifierRoute A1` - `notifier = Notifier A` - `event_key = mission.created` - `mission_category = 生产` - `is_enabled = True` 2. 创建 `NotifierRoute B1` - `notifier = Notifier B` - `event_key = mission.created` - `mission_category = 空` - `is_enabled = True` 这样配置后: - 生产分类任务创建时,优先命中生产群路由 - 其他分类任务创建时,走管理群的通配路由 ## 8. 典型配置示例 ### 8.1 示例一:所有任务完成统一发管理群 `Notifier` - `name`: `任务完成通知-管理群` - `channel`: `wecom_webhook` - `template_key`: `mission_completed` - `is_enabled`: 勾选 `NotifierRoute` - `event_key`: `mission.completed` - `mission_category`: 留空 - `is_enabled`: 勾选 ### 8.2 示例二:售后分类任务创建发售后群 `Notifier` - `name`: `任务创建通知-售后群` - `channel`: `wecom_webhook` - `template_key`: `mission_created` - `is_enabled`: 勾选 `NotifierRoute` - `event_key`: `mission.created` - `mission_category`: `售后` - `is_enabled`: 勾选 ### 8.3 示例三:同一个事件同时发多个群 例如 `mission.cancelled` 同时发客服群和管理群: - 创建两个不同的 `Notifier` - 分别为它们配置两条 `event_key = mission.cancelled` 的路由 - 两条路由都可以是 `mission_category` 为空的通配路由 系统会分别发送到两个群。 ### 8.4 示例四:任务创建时发企业微信应用文本消息 适用于: - 想发给某一个企业微信应用 - 内容以一段任务提醒文字为主 `Notifier` - `name`: `任务创建通知-企业微信应用` - `channel`: `message_api` - `template_key`: `mission_created` - `config`: ```json { "agent_id": 1000007, "timeout_seconds": 10 } ``` - `is_enabled`: 勾选 `NotifierRoute` - `event_key`: `mission.created` - `mission_category`: 留空 或 选择具体分类 - `is_enabled`: 勾选 ### 8.5 示例五:任务创建时发企业微信应用图文消息 适用于: - 想同时发到多个企业微信应用 - 希望用户在企业微信里看到标题、摘要、点击链接、封面图 `Notifier` - `name`: `任务创建图文通知-企业微信应用` - `channel`: `message_api` - `template_key`: `test_message_news` - `config`: ```json { "agent_ids": [1000007, 1000008], "timeout_seconds": 10 } ``` - `is_enabled`: 勾选 `NotifierRoute` - `event_key`: `mission.created` - `mission_category`: 留空 或 选择具体分类 - `is_enabled`: 勾选 ## 9. 模板如何对应 当前系统已内置以下模板: - `mission_created` - `mission_replied` - `mission_completed` - `mission_unreplied` - `mission_reply_rejected` - `mission_reopened` - `mission_cancelled` - `test_message_news` 管理人员通常只需要填 `template_key`,不需要改代码。 如果后续要新增模板内容或调整文案,需要由开发人员修改模板文件。 补充说明: - 当前这套 admin 配置说明默认基于“模板文件”模式。 - `wecom_webhook` 使用 `.md` 模板文件。 - `message_api` 使用 `.json` 模板文件。 - 在新的正式说明发布前,管理人员不要自行推断未文档化的模板字段。 ### 9.1 `message_api` 的 JSON 模板到底长什么样 这部分是为了帮助管理人员“看懂模板的大致样子”,不是要求你在后台手工编写模板。 可以把 JSON 模板理解为: - 它不是程序代码 - 它更像一张“字段清单” - 系统会把里面的变量替换成真正的任务内容 #### 文本消息模板示例 例如 `mission_created.json` 大致会渲染成: ```json { "msgtype": "text", "content": "任务已创建\n任务ID:123\n创建人:张三\n分类:售后\n紧急:否\n参与人:李四、王五\n说明:请跟进客户退货" } ``` 用更容易理解的话说: - `msgtype = text`:表示这是一条文本消息 - `content`:表示真正发出去的文字内容 这类模板适合: - 直接提醒 - 内容以文字为主 - 不需要点击封面图和链接 #### 图文消息模板示例 例如 `test_message_news.json` 大致会渲染成: ```json { "msgtype": "news", "title": "任务 123 通知", "description": "请跟进客户退货", "url": "https://example.com/missions/123", "image_url": "https://example.com/static/mission-cover.png" } ``` 用更容易理解的话说: - `msgtype = news`:表示这是一条单篇图文消息 - `title`:企业微信里显示的标题 - `description`:企业微信里显示的摘要 - `url`:用户点击后打开的链接 - `image_url`:封面图地址 这类模板适合: - 需要点击查看详情 - 需要更像“卡片消息”的展示 - 想同时发到多个企业微信应用 ### 9.2 管理人员最需要记住什么 对于 `message_api`,管理人员通常只要记住下面几件事: 1. 文本消息用 `agent_id` 2. 图文消息用 `agent_ids` 3. `template_key` 要和开发组给出的模板名一致 4. 不要自己修改 JSON 字段名 5. 如果不确定是文本还是图文,先问开发组,不要猜 ## 10. 未回复提醒的 admin 配置要点 `mission.unreplied` 和其它事件不同,它不是在某个瞬时动作发生时触发,而是由后台每分钟扫描一次“仍未回复的任务”后触发。 这意味着 admin 需要同时确认两件事: 1. 任务本身开启了未回复提醒 2. 通知系统中存在 `mission.unreplied` 对应的 `NotifierRoute` 如果只配置了路由,但任务没有开启提醒,则不会发送。 如果任务开启了提醒,但没有配置 `mission.unreplied` 路由,也不会发送到任何群。 ### 10.1 推荐配置方式 1. 创建一个 `Notifier` - `name = 任务未回复提醒-管理群` - `channel = wecom_webhook` - `template_key = mission_unreplied` - `is_enabled = True` 2. 创建一条 `NotifierRoute` - `event_key = mission.unreplied` - `mission_category = 留空` 或选择具体任务分类 - `is_enabled = True` ### 10.2 什么时候会持续提醒 只有满足以下条件才会持续发送 `mission.unreplied`: 1. 任务开启了“未回复提醒” 2. 任务还没完成 3. 任务还没取消 4. 当前没有任何有效回复 5. 没超过任务自身设置的最大提醒次数 ### 10.3 为什么任务开启了提醒,但还是没收到群通知 优先检查: 1. 是否已配置 `mission.unreplied` 的路由 2. 该路由是否启用 3. 对应的 `Notifier` 是否启用 4. `template_key` 是否写成 `mission_unreplied` 5. Celery worker / beat 是否都在运行 ## 11. 如何停用 ### 停用整个通知器 适用于: - 这个群临时不用 - 机器人 key 暂时不可用 - 该通知器下的所有路由都不想生效 操作方式: 1. 打开 `Notifier` 2. 取消勾选 `is_enabled` 3. 保存 ### 停用某一条路由 适用于: - 只是不想处理某个事件 - 只是不想处理某个任务分类 操作方式: 1. 打开对应 `NotifierRoute` 2. 取消勾选 `is_enabled` 3. 保存 ## 12. 常见问题 ### 11.1 为什么事件发生了,但没有收到通知 请依次检查: 1. `Notifier` 是否启用 2. `NotifierRoute` 是否启用 3. `event_key` 是否选对 4. `mission_category` 是否与实际任务分类匹配 5. `template_key` 是否对应现有模板 6. `config.key` 是否填写正确 7. Celery worker 是否已启动 ### 11.3 为什么 `message_api` 没有更多系统配置项 原因是: 1. 当前 ERP 只是 `message_api` 的调用方。 2. 企业微信真正的凭据管理和发送细节不属于 ERP 负责。 3. 因此后台管理人员只需要配置通知器自己的参数,例如 `agent_id`、`agent_ids`、`template_key`。 系统级配置由部署环境统一提供,例如: 1. `MESSAGE_API_BASE_URL` 2. `MESSAGE_API_AUTHORIZATION` 3. `MESSAGE_API_DEFAULT_NEWS_IMAGE_URL` 如果后续 `message_api` 的接口契约扩展,开发组会补充新的配置说明。 ### 11.2 为什么某个任务分类没有走专门群 常见原因: 1. 没有为该分类配置专用路由 2. 专用路由被停用 3. 该任务分类本身不是你以为的那个分类 ### 11.3 为什么同一个事件发了多次 通常是因为配置了多个不同的 `NotifierRoute`,分别绑定到了不同的 `Notifier`。 这不一定是错误,也可能是有意发往多个群。 ### 11.4 同一个通知器会不会因为“专用路由 + 通配路由”重复发送两次 不会。 系统会自动去重,并优先使用更具体的分类路由。 ## 13. 管理建议 - 先建 `Notifier`,再建 `NotifierRoute` - 通知器名称中写清楚目标群 - 路由备注中写清楚事件和分类用途 - 先停用再删除 - 先配置一条路由做验证,再批量扩展 ## 14. 最简操作结论 如果你只想快速配置一条通知,记住这 6 个关键点就够了: 1. 先创建 `Notifier` 2. 填好 `channel` 3. 填好 `template_key` 4. 在 `config` 中填好企业微信机器人 `key` 5. 再创建 `NotifierRoute` 6. 选对 `event_key` 和 `mission_category` 这样保存后,对应任务事件发生时就会自动按路由发送。