运维群里喊"系统挂了",值班同学半小时没看见;客户群里客户问"怎么退款",群里没人应。把指定群的指定内容监听起来,命中就触发动作——告警转发值班、常见问题自动应答——群消息才不至于淹没在刷屏里。群聊监听比单聊多几个坑:机器人自己的消息、按群配置路由、同关键词刷屏防抖。这篇把这几个坑和触发链路讲清。
我们用的是Eyun 平台开放的企微 API,统一 POST+JSON,请求头带Authorization: Bearer eyk_xxxx,响应封套{code, data, detail, message, time},code 为 0 成功。
监听入口:群消息和单聊消息怎么分
消息都从 Webhook 回调进来,回调头X-Eyun-Event标 message。区分群聊还是单聊看消息体字段:群消息带 roomId(群 ID),单聊带 userId。回调处理入口先按这个分叉:
@app.route("/wx-api/webhook/", methods=["POST"]) def webhook(): data = request.json["data"] if data.get("roomId"): return group_handler(data) return dm_handler(data)群消息体的 fromUin 是发言人的 uin,roomId 是哪个群。这两个字段组合起来,才能回答"谁在哪个群里说了什么"——监听配置的粒度就是按这个设计的:按群配置规则,按发言人过滤角色。
第一道防线:过滤机器人自己的消息
群聊监听最大的坑是死循环。机器人回复触发动作,动作又产生群消息,群消息又被自己监听到,再触发动作——当年一个告警群机器人一晚上发了四千条消息,起因就是它监听的关键词包含在自己回复的文案里。
过滤很简单,回调里机器人自己发的消息带机器人身份标识,直接跳过:
def group_handler(data): if data.get("fromUin") == BOT_UIN: return "ok" # 自己的消息绝不处理 if not group_config.enabled(data["roomId"]): return "ok" # 未配置监听的群直接跳过 match_rules(data["roomId"], data["fromUin"], data["content"]) return "ok"双保险:身份过滤加内容过滤——回复文案里避开自己监听的关键词。两道防线都上,死循环才真正绝迹。
按群配置:不是所有群都监听
全量监听既浪费又容易误触发。监听按群粒度配置,一张配置表:roomId、监听关键词、触发动作、生效开关。运维群配"系统挂了""P0"触发告警转发;客户群配"退款""发票"触发应答;闲聊群干脆不监听。
配置表的好处是运营可自助——新加一个群、改一个关键词,改表就行不碰代码。match_rules 按群加载配置,逐条匹配:
def match_rules(room_id, from_uin, content): for rule in group_config.rules(room_id): if rule["keyword"] in content: debounced_trigger(rule, room_id, from_uin, content) break # 命中第一条即止,防多重触发命中即止很关键。一条消息同时含"退款"和"发票"两个关键词,两个动作都触发,客户收到两张卡片,体验混乱。按规则优先级命中第一条就停。
防抖:同关键词刷屏别连环触发
群里出事时往往一群人刷同一个词——"挂了"连刷二十条,告警转发触发二十次,值班群被二次刷屏。触发要防抖:同一群同一规则,5 分钟冷却期内只触发一次,冷却期内的重复命中记数但不执行,冷却结束把计数摘要发一次。
实现按roomId + rule_id做冷却键,缓存命中时间戳。防抖粒度到规则级不是群级——同一条消息可能命中不同规则,各防各的。
触发动作:转发和应答两类
指定内容触发后的动作就两大类。告警转发类:命中运维关键词,调 message/sendText 把消息原文、发言人、群名转发到值班群,@值班人。自动应答类:命中客户群常见问题,调 message/sendRichText 发应答卡片,卡片带问题对应的说明链接。
应答类动作要克制。客户群里机器人逢词必答会刷屏惹人烦,加两个约束:同一客户同一问题 10 分钟内只答一次;命中时先看群里最近 5 条消息(调 message/getHistoryMessageList),已有人工回复过就不再插话。这两个约束加上后,客户群里机器人的存在感从"话痨"降到"该出现时才出现"。
监听运行时看什么数据
三个指标判断监听系统健不健康:触发量按群按规则分布(哪条规则触发最多)、冷却拦截量(防抖拦了多少重复触发)、误触发数(人工标记的误报)。误触发多的规则要么关键词太宽——"挂了"会匹配"别挂了"——要么该挪到要求 @机器人 的精确匹配。规则是养出来的,每周看一次数据调一轮,监听才越用越准。
监听系统的三条命门
群聊监听做稳就靠三条:过滤自己的消息防死循环、按群配置控制监听范围、防抖防止刷屏连锁。条条都是事故换来的经验——四千条告警消息那晚之后,这三条写进了团队的开发守则,新功能上线前逐条过一遍。