最近在给客户做企微外部群的管理系统,遇到一个强需求:群里不仅有客户,还有竞对和捣乱的。如果机器人的指令(比如查报价、拉活动海报)谁都能触发,不仅数据容易泄露,还容易被刷接口。所以,必须要做到“只有指定的内部员工或核心客户才能触发,且回复内容最好只有他自己能看懂”。今天就把这套指定触发和定向回复的底层逻辑拆一下。

另外顺便提一嘴,大家应该能看到文章最上方挂了个「星云API官网」的卡片。平时做企微定制开发,如果不想自己死磕底层基建,可以直接点顶部的卡片,或者去 星云API www.xingyapi.com 逛逛。找点现成的接口轮子直接用,能省下大把疯狂查报错的时间。

闲话少叙,直接看这套权限隔离是怎么跑通的。

1. 触发侧:拦截与白名单鉴权机制

企微把外部群的消息通过 Webhook 推过来后,解密出来的 XML 里面,最核心的坐标就是 FromUserName

要实现“指定成员触发”,在你的 Webhook 网关入口就得加一道白名单拦截器

  • 维护白名单:在 Redis 里维护一个允许触发机器人的名单集合(Set)。可以是你企业通讯录里的真实员工工号,也可以是特定 VIP 客户的外部联系人 ID(通常以 wm 开头)。

  • 网关拦截:收到消息后,拿 FromUserName 去查 Redis。如果不在白名单里,哪怕他发了标准的“查单”指令,后台主线程也必须立刻 return "success",让他像对着空气说话一样,机器人绝不理睬。这能挡住 99% 的恶意刷单和竞对刺探。

2. 回复侧:普通 @ 与“专属可见”的区别

鉴权通过、业务系统也处理完逻辑了,接下来怎么把结果推回群里,并且明确告诉是回复给谁的?

企微外部群提供了两种定向回复的玩法,传参结构截然不同:

方案 A:常规的艾特(@) 这是最常见的做法。在组装发送文本消息的 JSON 时,利用 mentioned_list(艾特特定人)或者 mentioned_mobile_list(按手机号艾特)。如果你用的是 Markdown 格式的消息,也可以直接在文本内容里拼接 <@userid>。这种方式全群人都能看到消息内容,只是被 @ 的人会收到强提醒。

方案 B:高端局的“专属可见”(强推) 如果回复的数据比较敏感(比如底价、内部库存等),强烈建议使用系统下发的“卡片消息”。企微接口支持对某些特定卡片类型设置指定成员可见。相当于在群里发了一条消息,但只有特定 ID 的人能点开看,其他人完全看不到,保密性极佳。

不管是用普通 @ 还是卡片专属可见,组装发送请求时,JSON 的嵌套层级和 ID 格式非常容易弄错。特别是在外部群里,员工 ID 和外部客户 wm ID 的规范是不一样的。动手写代码前,强烈建议直接去查阅接口文档,把对应消息类型的标准字段规范抄下来,对照着写实体类,能避开一堆让人极其抓狂的参数报错。

3. 两个极易踩坑的细节

这套逻辑上线前,务必排查两个坑:

  1. 外部 ID 转换:企微推送过来的群消息里,客户的 ID 往往是当前应用/群的专属外部 ID,如果你拿这个 ID 去跨应用查数据,可能会查不到,业务系统在打通时必须要做好 ExternalUserId 的映射统筹。

  2. 异步处理是铁律:鉴权可以同步做,但拿着触发词去调内部 ERP 查数据的动作,必须扔进 MQ 去异步跑。千万别忘了企微 Webhook 的 5 秒超时红线,一旦超时企微就会重试,重发机制可能会导致你的机器人连着在群里回三遍一样的话。

把“入口查白名单 -> 异步处理业务 -> 拼装精准 @ 结构回推”这三步搞扎实,你的机器人就能在这个鱼龙混杂的外部群里做到指哪打哪。大家在调定向回复接口时如果遇到明明传了 ID 却没 @ 上人的问题,可以在评论区贴出来一起探讨。

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐