微信机器人开发API:客服响应质检系统搭建教程/文档
客服团队超过 5 个人,管理就会遇到一个盲区:客户消息多久被回复的?有没有人被漏回?客服有没有乱承诺?传统做法是主管每天翻聊天记录抽检,覆盖率不到 5%,而且只能事后发现——客户已经被怠慢完了。
其实质检需要的数据,微信回调里全都有。本教程用微信机器人开发 API 搭一套客服质检系统:全量消息入库 → 首响时长计算 → 漏回检测 → 敏感词合规扫描 → 每日质检日报自动推送。基于标准 HTTP + Webhook 接口实现(本文以 WTAPI 为例,Python 代码),接口均对照官方开发文档核实,可直接作为搭建文档。
一、关键认知:质检的数据从哪来
前面几篇教程都强调一个过滤技巧:回调报文里 FromUserName.string == Wxid 是本号发出的消息,做机器人时要过滤掉,避免回复自己。
做质检恰恰相反——本号发出的消息正是被检对象。
官方回调是全量推送的:客户发来的消息进回调,客服用这个微信号发出的消息同样进回调。两条数据流一配对,"客户几点问的、客服几点回的、回了什么"就全齐了。这就是整套系统的数据基础,不需要在客服手机上装任何东西。
二、接入层:全量消息入库
回调规范不变:3 秒内响应、去重键 Appid + Data.NewMsgId。区别是不再过滤任何方向的消息,按方向打标后全部入库:
import json, time
import requests
from flask import Flask, request
API_BASE = "https://wx.chuapi.com"
APP_ID = "YOUR_APPID"
HEADERS = {
"X-finder-TOKEN": "YOUR_TOKEN",
"Authorization": "Bearer YOUR_JWT",
"Content-Type": "application/json",
}
_seen = set()
app = Flask(__name__)
@app.route("/wtapi/callback", methods=["POST"])
def callback():
msg = request.get_json(silent=True) or {}
if msg.get("TypeName") != "AddMsg":
return "", 200
d = msg.get("Data", {})
key = f"{msg.get('Appid')}:{d.get('NewMsgId')}"
if key in _seen:
return "", 200
_seen.add(key)
from_user = d.get("FromUserName", {}).get("string", "")
# 质检场景:不按方向过滤,两端都存
db.save_message({
"msg_id": d.get("NewMsgId"),
# 本号发出 = 客服回复;客户发出 = 客户咨询
"direction": "out" if from_user == msg.get("Wxid") else "in",
"peer": d.get("ToUserName", {}).get("string", "") if from_user == msg.get("Wxid") else from_user,
"msg_type": d.get("MsgType"),
"content": d.get("Content", {}).get("string", ""),
"create_time": d.get("CreateTime"), # 官方字段:消息时间戳
})
return "", 200
注意 Content.string 的判定路径以官方回调速览页为准;群消息(FromUserName 以 @chatroom 结尾)里客服的发言同样可检,适合做社群运营的响应质检。
三、指标层:三个可落地的质检指标
① 首响时长——客户提问到客服第一条回复的时间差。按"客户 wxid + 会话窗口"配对:
def first_response_seconds(peer_wxid, day):
msgs = db.get_messages(peer_wxid, day) # 按 create_time 升序
waiting_since, gaps = None, []
for m in msgs:
if m["direction"] == "in" and waiting_since is None:
waiting_since = m["create_time"] # 客户提问
elif m["direction"] == "out" and waiting_since:
gaps.append(m["create_time"] - waiting_since)
waiting_since = None # 客服已回应
if waiting_since:
db.mark_unanswered(peer_wxid, waiting_since) # ② 漏回:至统计时无回复
return sum(gaps) / len(gaps) if gaps else None
② 漏回检测:客户消息发出后 N 小时(建议设 4 小时)无任何"out"方向消息,进漏回名单,质检日报里置顶——这是比"回复慢"严重一个量级的事故。
③ 敏感词扫描:客服发出的每条消息过黑名单,命中即告警:
BANNED = ["保证收益", "稳赚", "百分百", "内部渠道", "放心不会亏"]
def scan_outbound(m):
hits = [w for w in BANNED if w in m["content"]]
if hits:
db.save_violation(m["msg_id"], m["peer"], hits)
黑名单按行业配:教培禁"保过提分"、保险禁"保本稳赔"、房产禁"稳涨学区房"。图片、语音(MsgType=3/34)算"有响应"计入首响,但内容合规只能抽检,这是当前方案的边界,写日报时如实标注。
四、输出层:日报自动推给主管
质检系统的价值在"每天自动出现在主管面前"。跑完统计,直接用官方发消息接口 postText(参数仅 appId/toWxid/content)把日报推到主管微信:
def push_daily_report(boss_wxid):
r = db.build_daily_report()
post_text(boss_wxid,
f"【客服质检日报 {r['day']}】\n"
f"平均首响:{r['avg_first_response']}秒(红线 120 秒)\n"
f"超时可溯会话:{r['slow_convos']} 个\n"
f"漏回客户:{r['unanswered']} 个 ← 需今日补救\n"
f"敏感词命中:{r['violations']} 条")
def post_text(to_wxid, content):
requests.post(
f"{API_BASE}/finder/v2/api/message/postText",
headers=HEADERS,
data=json.dumps({"appId": APP_ID, "toWxid": to_wxid, "content": content}),
timeout=10,
)
五、调试与上线
调试环境:WTAPI 开发文档站 weiti.apifox.cn 提供 7 天接口调用权限,后台附带 Demo 示例可供本地调试,本文所有接口路径与字段以文档实时内容为准。建议先在控制台「微信实例」扫码拿 appId,用 toWxid=filehelper(文件传输助手)模拟收发,验证首响配对逻辑后再接真实客服号。
上线前三个提醒:
- 员工知情权:对客服账号做质检必须先告知员工并写入制度,只用于工作号、不碰私人号——这是法律红线,也是团队信任的基础;
- 先跑基线再定红线:首响红线别拍脑袋,先采集两周数据看分布,再定考核阈值;
- 质检数据就是客服培训素材库:漏回案例、违规话术脱敏后就是最好的周会教材,别只用于处罚。
合规声明:本文方案仅限企业对自有工作微信号的客服质量管理场景,须提前告知员工并遵守劳动与个人信息相关法规、微信平台运营规范,不使用任何非官方破解协议。
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐



所有评论(0)