# 业务系统的重要通知，怎样自动推送到企微群和 QQ 群？

来源: https://www.likelic.com/blog/notification-api-wecom-qq.html

企业每天都在业务系统里产生大量事件。

一票订单状态变了。

客户费用已经确认。

某票货物出现异常。

报关资料还没有补齐。

某个内部任务需要相关人员及时处理。

这些信息原本已经存在于业务系统里。

但真正需要通知客户或者员工时，很多企业依然在做一件非常传统的事情：

**人工复制，再发到群里。**

业务员打开系统。

复制订单号和状态。

再打开企业微信或者 QQ。

找到对应客户群。

粘贴。

发送。

一天只有几条消息的时候，这样做似乎没有什么问题。

但当订单越来越多、客户群越来越多之后，很快就会出现：

消息忘记发。

群发错了。

同一条通知重复发。

员工下班后没人发。

系统已经产生异常，但群里过了很久才知道。

所以，立刻智能体增加了一个更加适合系统集成的能力：

**推送通知 API。**

让业务系统产生事件之后，可以直接调用接口，将消息自动送到对应的企微群或 QQ 群。

一个接口，同时支持企微群和 QQ 群
------------------

推送通知统一使用：

`POST /api/v1/notifications`

也就是说，企业自己的 ERP、TMS、货代系统、订单系统或者其他内部业务平台，不需要分别开发两套：

企业微信推送接口。

QQ 群推送接口。

业务系统只需要按照统一的数据结构，把需要发送的通知提交给立刻智能体。

之后由立刻智能体根据目标群所属渠道，完成实际消息投递。

一次典型的推送请求主要会包含几个核心信息：

`biz_msg_id`

业务消息唯一编号。

`target`

这条消息需要发给谁。

`text`

实际需要发送的通知内容。

`urgent`

是否属于紧急消息。

可以简单理解为：

> 这是哪一条业务消息？

> 要发到哪里？

> 发什么内容？

> 是不是紧急通知？

调用方只需要关心自己的业务逻辑。

至于最终是通过企业微信机器人发送，还是通过 QQ 机器人发送，则交给立刻智能体统一处理。

推送目标怎么确定？
---------

系统知道“要发送一条通知”还不够。

更重要的是：

**这条消息到底应该发到哪个群？**

立刻智能体提供了两种主要的定位方式。

### 方式一：按公司代码定位

如果企业已经建立了客户公司与群之间的关系，可以通过：

`company_code`

进行业务定位。

例如：

业务系统知道这票订单属于客户：

> CUS000128

那么推送时可以直接将这个公司代码作为目标条件。

立刻智能体再根据已经维护好的群关系，找到对应的推送群。

这种方式比较适合：

**业务系统天然以客户、供应商或公司主体作为数据中心的场景。**

调用方不需要知道具体群号是什么。

只需要知道：

**这条通知属于哪个客户。**

### 方式二：直接按群定位

另外一种方式更加直接。

可以通过：

`channel + instance_id + room_id`

指定具体群。

其中：

`channel`

表示消息渠道，例如企微或者 QQ。

`instance_id`

表示对应接入实例。

`room_id`

表示具体群标识。

这种方式适合业务系统本身已经知道目标群的场景。

例如某个项目群。

某个内部通知群。

某个固定客户服务群。

这时可以直接指定：

**消息就发到这个群。**

两种模式并不冲突。

企业可以根据自己的业务系统结构选择更合适的定位方式。

不知道有哪些群？可以先查询群清单
----------------

对于接口调用方来说，还有一个很实际的问题：

**当前到底有哪些群可以推送？**

因此，立刻智能体提供群清单接口：

`GET /api/v1/rooms`

业务系统可以通过接口获取已经接入的群信息。

同时还可以根据条件进行筛选，例如：

1.  渠道
2.  推送状态
3.  公司代码

这样，在进行系统集成或者目标匹配时，就不需要人工去后台一个个复制群 ID。

接口还会返回群当前的推送状态。

例如：

`ready`

表示当前具备正常推送条件。

`blocked`

表示该群当前无法正常推送。

`unknown`

表示当前状态暂时无法确认。

这一点非常重要。

因为：

**群存在，不代表此刻一定可以发送消息。**

机器人可能被移出群。

授权可能发生变化。

接入实例可能离线。

群本身的状态也可能变化。

所以推送系统不能只管理一个静态的“群编号”。

还需要知道：

**这个群当前能不能发。**

为什么一定要有 biz\_msg\_id？
---------------------

在消息推送系统里，有一个很容易被忽略的问题：

**重复发送。**

假设业务系统调用接口之后，因为网络超时，没有收到成功响应。

这时候调用方并不知道：

消息到底有没有发出去？

最常见的处理就是：

再请求一次。

但如果上一条实际上已经成功发送，那么客户群里就可能看到：

同一条订单提醒。

连续发了两遍。

甚至更多。

所以推送接口使用：

`biz_msg_id`

作为业务消息的唯一标识。

对于同一个 `biz_msg_id`，系统会进行幂等处理。

也就是说：

**同一条业务消息，不会因为重复调用而被重复投递。**

这对于系统接口来说非常重要。

因为业务系统就可以更加放心地进行：

1.  网络失败重试
2.  超时重试
3.  服务恢复后重新执行
4.  任务队列重新消费

即使服务发生重启，只要业务消息 ID 不变，就可以尽可能避免因为技术重试造成重复通知。

不是任何时间都适合给客户发消息
---------------

接口自动化以后，还有一个新的问题。

业务系统是 24 小时运行的。

但客户不一定希望：

凌晨 2 点收到普通订单通知。

晚上 11 点收到一条并不紧急的费用提醒。

所以，立刻智能体支持配置：

**消息推送时间窗口。**

例如企业可以设置：

普通通知只允许在指定时间范围内发送。

如果业务系统在窗口以外提交消息，并不代表消息一定被丢弃。

系统可以将其自动进入排期。

等到下一个允许推送的时间窗口，再继续发送。

这样业务系统仍然可以：

**事件发生时立即提交。**

而实际什么时候打扰客户，则交给推送策略控制。

真正紧急的消息，可以使用 urgent
-------------------

当然，有些消息不能等。

比如：

重要业务异常。

临时截单变化。

重大运输异常。

需要立即处理的内部事件。

这种情况下，可以通过：

`urgent`

标记紧急消息。

紧急消息可以根据实际配置绕过普通推送时间窗口的限制。

也就是说：

普通信息遵守发送时间。

紧急信息优先确保时效。

这样就不用为了照顾异常场景，把所有消息都设置成全天随时发送。

自动推送，也要有配额和限速
-------------

如果系统完全不限制自动消息，另一个风险就是：

**短时间推送过多。**

例如一次批量任务更新了几千票订单。

如果程序瞬间把几千条通知全部提交到群里，不仅客户体验不好，也可能触发平台侧的频率限制。

因此，立刻智能体会对自动推送增加相应的配额和速度控制。

例如：

**每日发送配额**

控制一定周期内可以投递的消息数量。

对于 QQ 群，还可以进一步进行：

**分钟级发送限速。**

如果短时间消息过多触发限速，并不意味着这些消息全部失败。

系统可以将部分消息延迟，并重新安排后续发送时间。

也就是说，系统会尽量把：

**“现在不能发”**

转化为：

**“稍后再发”。**

而不是简单丢弃。

系统调用成功，不等于消息一定已经送达
------------------

做接口集成时，还有一个经常出现的误区。

业务系统调用：

`POST /api/v1/notifications`

接口返回成功。

是不是就代表客户一定已经收到消息？

不一定。

因为：

**接口接收成功**

和：

**最终消息投递成功**

本身是两个不同阶段。

例如接口收到消息之后，可能发现：

目标群不存在。

群当前被阻塞。

超过当天配额。

当前不在允许推送的时间窗口。

触发 QQ 群限速。

对应机器人暂时不可用。

所以，立刻智能体还提供相应的：

**投递结果 / 回执查询能力。**

业务系统可以继续查询这条通知当前处于什么状态。

例如：

等待发送。

已经排期。

发送成功。

被跳过。

发送失败。

如果没有正常投递，系统还可以保留相应原因。

例如：

1.  群不存在
2.  当前群被阻塞
3.  超出发送配额
4.  限速等待
5.  其他推送条件不满足

这样企业自己的业务系统也可以继续判断：

这条通知是不是已经真正完成。

要不要人工处理。

要不要进入异常列表。

最常见的场景：订单状态自动通知
---------------

对于国际物流企业来说，最直接的应用就是：

**订单状态变更通知。**

比如系统中的订单从：

已订舱

变成：

已放舱

业务系统触发事件。

自动调用推送接口。

消息就可以进入对应的客户服务群：

> 【订单状态更新】

> 工作号：SH260928001

> 当前状态：已放舱

> 船名航次：XXX / V.028E

整个过程不再需要业务员：

复制。

打开 QQ。

找群。

粘贴。

发送。

系统产生业务变化的同时，就可以触发对应客户通知。

费用确认，也可以直接进入客户群
---------------

另外一个常见场景是：

**费用确认。**

例如系统生成了一份待确认账单。

过去可能需要财务或者客服手工把信息发到客户群。

现在可以由业务系统自动提交通知：

> 【费用确认提醒】

> 工作号：SH260928001

> 本票费用已生成，请及时确认。

如果后续还有客户查询链接，也可以一起组合到通知内容里。

这样：

**账单产生**

和：

**通知客户**

就可以形成一条自动化链路。

异常预警，更适合使用自动推送
--------------

相比普通状态通知，异常类消息对及时性的要求通常更高。

例如：

货物状态异常。

报关资料缺失。

车辆长时间停留。

订单关键节点超时。

某项业务出现风险。

业务系统本身可能已经能够识别这些异常。

但如果异常只停留在系统后台，没有人及时看到，那么预警本身的价值就会大幅降低。

通过推送通知 API，可以把：

**系统发现异常**

继续连接到：

**立即通知相关人员。**

对于非常紧急的情况，还可以结合 `urgent` 使用。

这样异常不再只是后台的一条红色记录。

而可以真正主动找到需要处理的人。

内部通知也可以使用同一套接口
--------------

推送 API 不一定只能用于客户群。

企业内部群同样适用。

比如：

1.  当日重点订单提醒
2.  财务未核销提醒
3.  操作异常
4.  系统维护通知
5.  重要内部公告
6.  待处理任务

业务系统可以直接指定内部 QQ 群或者企微群。

也就是说，这套接口本质上解决的是：

**业务系统如何把一条重要事件，可靠地送到一个群里。**

至于这个群是：

客户群。

供应商群。

项目群。

还是公司内部群。

由企业自己决定。

为什么要同时支持企业微信和 QQ？
-----------------

现实里，很多企业并不是只使用一种沟通工具。

有些客户习惯企业微信。

有些老客户一直使用 QQ。

公司内部又可能使用另外一套群。

如果每一个渠道都由业务系统单独开发接口，会带来很多重复工作。

开发需要分别维护。

异常处理逻辑不同。

限速规则不同。

推送记录也分散。

立刻智能体希望把这些差异放在统一的推送层处理。

业务系统只提交：

**我要发什么。**

**我要发给谁。**

至于最后通过：

**企微群还是 QQ 群**

完成投递，由立刻智能体继续处理。

这样未来企业再增加新的消息场景时，不需要为每一个业务功能重新开发一遍渠道逻辑。

使用推送通知 API，需要什么条件？
------------------

要使用推送通知 API，首先需要开通对应的接口及推送权限。

同时，不同渠道需要完成相应的机器人接入。

如果要向企业微信群推送：

**需要对应的企微机器人具备正常发送条件。**

如果要向 QQ 群推送：

**需要完成 QQ 机器人接入，并保证目标群当前具备推送条件。**

需要特别注意：

**群的推送状态并不是永久不变的。**

机器人可能离线。

群关系可能发生变化。

授权可能失效。

发送条件也可能随着平台状态发生变化。

因此，更稳妥的集成方式是：

业务系统在需要时查询群清单和推送状态。

发送后再结合投递结果确认最终状态。

而不是认为：

**只要曾经绑定成功，这个群以后就永远可以发送。**

从“系统里发生了什么”，到“相关的人马上知道”
-----------------------

企业做信息化以后，很多业务动作其实早就已经数字化了。

订单状态。

账单。

异常。

节点。

任务。

都已经存在系统里。

但如果这些信息最终还需要员工：

**看到 → 复制 → 找群 → 粘贴 → 发送**

那么业务系统和客户沟通之间，实际上仍然存在一段人工断点。

推送通知 API 做的事情，就是把这段连接起来。

业务事件发生。

↓

系统调用通知接口。

↓

立刻智能体定位目标群。

↓

根据时间窗口、配额和限速规则进行调度。

↓

通过企微机器人或 QQ 机器人完成发送。

↓

业务系统再查询实际投递结果。

于是原来依赖人工完成的一条消息，开始变成一条真正可自动运行的业务流程。

**让重要业务通知不再等人转发，而是在应该出现的时候，自动出现在应该出现的群里。**
