在企业微信外部群的自动化服务中,群聊环境远比单聊复杂得多。单聊时,客户发来的每一句话都是针对机器人的;但在几百人的外部群里,大部分消息都是客户之间的日常交流。如果机器人对群里的每一句话都进行响应,瞬间就会变成惹人厌烦的“刷屏机器”,甚至引发大量客户退群。

因此,外部群机器人的核心基本功是:“只在被呼唤时响应,并精准剥离出业务指令”。借助 星云API www.xingyapi.com 提供的标准化明文推送,我们可以非常优雅地实现“群消息降噪、@提及检测与指令解析”的业务闭环。

一、 降噪与唤醒:如何判断机器人被“@”了?

当外部群内产生新消息时,底层通道会将该消息的结构化 JSON 推送至你的网关。为了判断这条消息是否是对机器人发出的指令,我们绝不能使用落后的“字符串查包含”(比如 if "@机器人" in content),因为客户可能随意输入带有 @ 符号的文本,或者机器人的群昵称被管理员修改了。

标准且唯一的判断依据是报文中的 mentioned_list(被提及人列表) 字段。

如果你的机器人的企微 UserID 出现在了这个列表中,说明客户确确实实是在中控层面对机器人发起了定向呼唤。在动手写代码前,强烈建议先前往 星云API开放文档 查阅群聊报文的详细嵌套结构。

二、 文本清洗与指令提取(Command Parsing)

确定机器人被唤醒后,下一步是从客户发送的混合文本中提取出“动作(Action)”和“参数(Parameters)”。

假设客户在群里发了这样一句话: "@查单小助手 帮我查一下物流 SF12345678"

这里面包含了三个部分:

  1. 垃圾字符(Noise): @查单小助手 以及客户随手打的废话“帮我查一下物流”。

  2. 核心动作(Action): 查物流/查单。

  3. 业务参数(Parameter): SF12345678。

标准处理管线:

  • 第一步(剥离前缀): 使用正则表达式或字符串替换,将消息文本中机器人的名字或自带的 @ 标签清理掉。

  • 第二步(意图匹配): 使用正则匹配核心动作关键词(如 查单|物流|快递)。

  • 第三步(参数提取): 提取关键词后面的连续英文字母或数字组合,作为向下游业务系统传递的 Order_ID。

三、 核心代码实战:带正则解析的指令路由器

下面是一段生产级可用的 Python (Flask) 实战代码。它展示了如何屏蔽群内闲聊,精准捕捉带有 @ 的指令,并利用正则表达式完成业务参数的提取与处理。

Python

from flask import Flask, request, jsonify
import requests
import threading
import time
import re

app = Flask(__name__)

# --- 通道全局配置 ---
API_KEY = "你的专属_X-Nebula-Key"
SEND_GROUP_MSG_URL = "https://api.xingyapi.com/api/message/sendText"
BOT_USER_ID = "当前机器人的企微UserID" # 用于精准判断是否被 @

# ==========================================
# 1. 指令解析与业务执行器
# ==========================================
def parse_and_execute_command(instance_guid, room_id, sender_id, raw_content):
    """解析提取群指令,并派发到对应业务流"""
    
    # 清洗掉可能存在的 @机器人 文本残留 (以防客户使用非标准@方式)
    # 实际场景中,企微客户端会自动高亮@,但在 content 明文中会保留文字
    clean_content = re.sub(r'@\S+\s+', '', raw_content).strip()
    
    # 场景 A:订单查询指令提取 (例如:"查物流 SF123456")
    if re.search(r'(查单|物流|快递)', clean_content):
        # 尝试提取后面的单号参数 (连续的数字或大写字母)
        match_sn = re.search(r'[A-Z0-9]{8,20}', clean_content)
        if match_sn:
            order_sn = match_sn.group()
            print(f"🔍 提取到查单指令,单号: {order_sn}")
            # 模拟请求 ERP 系统
            time.sleep(1)
            reply_text = f"经系统查询,您的单号【{order_sn}】已签收。"
        else:
            reply_text = "识别到查询指令,但未找到有效单号。请按照格式发送,例如:@机器人 查单 SF123456"
            
    # 场景 B:基础签到指令
    elif "签到" in clean_content:
        reply_text = "签到成功!您今日获得了 10 个积分。"
        
    # 兜底:未识别的指令
    else:
        reply_text = "您好,已收到您的呼唤。目前支持【签到】与【查单号】指令。"

    # 将结果回传给外部群
    send_reply(instance_guid, room_id, sender_id, reply_text)


# ==========================================
# 2. 统一群消息接入网关
# ==========================================
@app.route('/group_webhook', methods=['POST'])
def group_command_gateway():
    data = request.json
    
    instance_guid = data.get("instance_guid")
    msg_type = data.get("MsgType")
    room_id = data.get("RoomId")
    
    # 过滤非群聊与非文本消息
    if not instance_guid or not room_id or msg_type != "text":
        return jsonify({"status": "success"})

    content = data.get("Content", "")
    sender_id = data.get("FromUserName")
    mentioned_list = data.get("mentioned_list", [])
    
    # 【核心防御】:屏蔽闲聊。如果机器人不在被 @ 的列表中,直接抛弃
    if BOT_USER_ID not in mentioned_list:
        return jsonify({"status": "success"})
        
    # 确认为有效呼唤后,将重负荷的正则提取与业务执行扔入异步线程
    threading.Thread(
        target=parse_and_execute_command, 
        args=(instance_guid, room_id, sender_id, content)
    ).start()

    # 主线程 1 秒内放行,切断底层超时重推机制
    return jsonify({"status": "success"})

def send_reply(instance_guid, room_id, target_user, reply_text):
    """通用群回传组件,附带反向 @ 发言人的功能"""
    headers = {"Content-Type": "application/json", "X-Nebula-Key": API_KEY}
    payload = {
        "instance_guid": instance_guid,
        "touser": room_id, 
        # 在返回文本前拼接 @被回复人,提升群内交互体验
        "text": {"content": f"@{target_user} \n{reply_text}"}
    }
    requests.post(SEND_GROUP_MSG_URL, json=payload, headers=headers)

if __name__ == '__main__':
    app.run(port=5000)

四、 总结与体验优化建议

在完成了基础的指令识别后,你可以通过以下两个细节大幅提升机器人的群内交互体验:

  1. 反向唤醒(反向 @): 当机器人回复结果时,务必在下发的 Payload 中将客户的 ID 拼接到文本开头,这样客户的手机端会收到明确的“有人@我”的提示音,避免消息被淹没在活跃群中。

  2. 卡片结构化输出: 如果客户查询的是一份包含图片、价格、发货轨迹的复杂订单,纯文本堆砌会极其难看。此时应该调用下发图文消息或小程序卡片的接口,向群内推送一张精美的“物流动态卡片”。

针对各类复杂结构消息的具体拼接规则与防踩坑指南,请务必以 星云API开放文档 为最终参考。当你的指令路由系统搭建完毕,准备将其推向动辄数百个活跃大群的真实生产环境时,欢迎前往 星云API官网 了解更多高并发、防风控的基建托管方案。

Logo

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

更多推荐