群管理是微信机器人需求最密集的场景,但真正开发时能卡住人的不是接口数量,而是两个地方:群成员数据结构怎么读,进群申请怎么取参数。

尤其是进群审核,很多人能成功调通获取群成员,但在审核这一步反复失败,原因往往是参数必须从回调报文原文里取,而不能自己拼装。

这篇把这两块讲透,代码片段可直接嵌入现有服务。

一、先分清:哪些群操作可以自动,哪些必须留人工确认

开发前先做一次动作分类,这个顺序错了后面会返工:

操作类型代表动作建议
只读操作拉群列表、拉成员列表、查群公告可以全自动
单向写入发送欢迎语、发群公告可以全自动,但要限频
双向确认类进群审核、踢人、拉人半自动:机器筛选、人工点确认
高风控操作批量拉人、批量踢人只做人工,不做自动

分类的依据是操作可逆性和对成员的打扰程度。拉成员列表最安全,批量踢人风险最高。进群审核属于半自动,不要让机器人无条审放行,否则群里会被广告号灌满。

二、开发前的两个准备

准备 1:拿到 appId

appId 是实例标识,控制台的“微信实例”页扫码登录后生成。如果走接口登录流程,首次调 getLoginQrCode 时 appId 传空,返回里带新生成的 appId;掉线重登时必须传原 appId,否则会生成新实例。

准备 2:配好鉴权头

import requests
接口统一走 https://wx.chuapi.com,鉴权靠两个头:

# WTAPI 接口地址:字段与参数以文档为准 weiti.apifox.cn
BASE_URL = "https://wx.chuapi.com"

HEADERS = {
    "Content-Type": "application/json",
    "X-finder-TOKEN": "<your_token>",
    "Authorization": "Bearer <your_jwt>",
}

X-finder-TOKEN 在控制台「Token回调」页取,Authorization 部分环境需要传 JWT,以实际后台为准。

三、群成员管理:getChatroomMemberList

这是群管理里调用频率最高的接口,绝大多数群功能都建立在它之上:发欢迎语要知道谁进来了、做裂变统计要知道谁邀请的、查管理员要知道权限边界。

接口基本信息

项值
路径/finder/v2/api/group/getChatroomMemberList
方法POST
参数appId、chatroomId

只有两个参数,没有分页参数,一次返回全量成员。

返回结构

data 下三个关键部分:

字段说明典型用途
memberList成员数组遍历发消息、做统计
chatroomOwner群主 wxid判断权限、@群主
adminWxid管理员 wxid 列表权限校验

memberList 里每条记录包含 wxid、nickName、displayName、headImg、inviterUserName 等字段。其中 inviterUserName 是被低估的字段——它记录了该成员是被谁拉进群的,做社群裂变归因时直接用它,不需要额外埋点。

调用代码

def list_members(app_id, chatroom_id):
    """拉取群成员列表,一次返回全量"""
    return requests.post(
        f"{BASE_URL}/finder/v2/api/group/getChatroomMemberList",
        headers=HEADERS,
        json={"appId": app_id, "chatroomId": chatroom_id},
        timeout=10,
    ).json()

三个实际用法

用法 1:群活跃度粗算
定时拉一次成员列表,和上一次的差集就是新增成员,交集数量就是留存规模。这个方法不需要消息级数据,成本极低。

用法 2:裂变邀请统计
按 inviterUserName 分组计数,能直接得出“谁拉的人最多”。做社群分销、邀请奖励时这是基础数据。

用法 3:权限校验前置
执行踢人、改群名这类写操作前,先判断操作人是否在 adminWxid 列表或等于 chatroomOwner。把权限校验放在业务层,而不是等接口报错再回滚,能少踩很多坑。

四、进群审核:从回调取参到确认放行

这一节是全文最容易出问题的地方。

为什么进群审核总失败

/finder/v2/api/group/roomAccessApplyCheckApprove 需要两个参数 newMsgId 和 msgContent。这两个值不能自己构造,必须从进群申请的回调报文里原样取出:

  • newMsgId 是这条申请消息的唯一标识,自己拼会失效
  • msgContent 必须是回调里的原文,改一个字符就对不上

很多人卡在这里,是因为把 msgContent 当成“自定义文案”传了进去。它不是文案,是校验凭据。

回调报文长什么样

Webhook 推送的是 HTTP POST JSON,核心结构:

{
  "TypeName": "AddMsg",
  "Appid": "your_appid",
  "Wxid": "机器人本号",
  "Data": {
    "MsgId": "...",
    "NewMsgId": "...",
    "FromUserName": { "string": "申请人的wxid" },
    "ToUserName": { "string": "群id@chatroom" },
    "Content": { "string": "进群申请原文" },
    "CreateTime": 1759900000
  }
}

这里有三个必须注意的点:

  1. Content.string 是嵌套对象,不是字符串,取值要写 data["Content"]["string"]
  2. NewMsgId 就是审核接口要的 newMsgId,直接透传
  3. ToUserName 以 @chatroom 结尾表示群相关消息,可用来区分单聊和群场景

回调处理:3 秒响应铁律

回调必须在 3 秒内返回,否则会触发重推。正确做法是先落队、后处理:

def on_webhook(payload):
    # 回调要求 3 秒内响应,这里只做入队,不做业务处理
    if payload.get("TypeName") != "AddMsg":
        return ""

    data = payload["Data"]
    queue.put({
        "appid": payload["Appid"],
        "new_msg_id": data["NewMsgId"],
        "msg_content": data["Content"]["string"],
        "from_wxid": data["FromUserName"]["string"],
        "chatroom_id": data["ToUserName"]["string"],
    })
    return ""      # 必须返回空串或 200

去重要做:重推会带来重复报文,去重键用 Appid + NewMsgId,落在入库层,不要靠内存去重。

审核接口

项值
路径/finder/v2/api/group/roomAccessApplyCheckApprove
参数appId、chatroomId、newMsgId、msgContent
参数来源全部取自回调原文,不可改写
def approve_join(app_id, chatroom_id, new_msg_id, msg_content):
    """确认进群:newMsgId 与 msgContent 必须取自回调原文"""
    return requests.post(
        f"{BASE_URL}/finder/v2/api/group/roomAccessApplyCheckApprove",
        headers=HEADERS,
        json={
            "appId": app_id,
            "chatroomId": chatroom_id,
            "newMsgId": new_msg_id,
            "msgContent": msg_content,
        },
        timeout=10,
    ).json()

放行策略建议

不要无条放行。常见做法是三级:

申请特征处理
有备注且备注含业务关键词自动放行
无备注、头像异常、昵称含推广词拒绝或转人工
同一 wxid 短时间重复申请直接拒绝并记录

这套策略的价值在于把机器人放在筛选位,把最终决定权留给人,既省人力又不失控。

五、两个容易踩的坑

坑 1:把 memberList 当实时数据用

成员列表是拉取时的快照。群成员变动频繁时,缓存超过 5 分钟的数据会失真。做发消息类业务时,建议每次发送前现拉或短 TTL 缓存,不要用一份旧数据跑批量。

坑 2:审核用的 newMsgId 有时效

进群申请的消息标识不是永久有效,间隔太久再调审核接口会失败。处理队列积压时要注意这一点,过期申请宁可丢弃重来,不要反复重试。

六、小结

群管理机器人的骨架其实就三块:

  1. 明确动作分级——只读全自动、写入半自动、高危只人工
  2. 用 getChatroomMemberList 打地基——成员、群主、管理员、邀请人都在一个接口里
  3. 进群审核严格走回调取参——newMsgId 和 msgContent 原样透传,不自造

三块里,第二块决定功能上限,第三块决定稳定性下限。

接口路径、参数名与返回字段以weiti.apifox.cn文档实时内容为准

Logo

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

更多推荐