一、客服消息“咨询-回复”方式
1、咨询方式
公众号:公众号主页发送各类型消息后,会在公众号后台收到用户消息。
小程序:在小程序网页中添加“客服按钮”,进入客服会话。
<button open-type="contact" bindcontact="handleContact"></button>
Page({
handleContact(e) {
console.log(e.path)
console.log(e.query)
}
})
2、常用回复方式
公众号:
方式一:公众号后台回复,登录公众号,选择“人员设置”添加长期运营者,管理员通过后。运营者可直接在公众号后台回复消息(仅PC端支持)。
方式二:绑定客服人员、通过微信公众平台客服功能登录并回复消息(仅PC端支持)。
- 成为客服:登录公众号-添加功能插件-客服功能-添加客服。
方式三:绑定客服人员,关注微信小程序“公众平台助手”(手机微信支持,推荐)。
小程序:
方式一:绑定小程序客服人员,登录微信公众平台-客服-添加,成为客服,在客服平台登录回复(仅PC端支持)。
二、客服消息接口应用
1、接口说明
微信公众号:
- 接口文档。
- 启用开发者模式:公众平台-开发-基本配置,启用服务器。
- http支持80端口,https支持443端口、可使用内网穿透域名测试消息。
- 用户发送消息后,通过接口回复消息条数超过20条后,用户未再次发送消息,接口将调用失败。
- 用户2天内未与公众号交互,无法主动发送消息给用户。
微信小程序:
- 接口文档。
- 服务器配置:公众平台-开发-开发配置-消息推送。
- 仅支持https\443端口、一个月可修改3次、域名需备案。
- 用户发送消息后,通过接口回复消息条数超过5条后,用户未再次发送消息,接口将调用失败。
- 用户发送消息后,30分钟内未回复用户,调用客服接口失败。
- 用户2天内未与公众号交互,无法主动发送消息给用户。
2、实现快速回复用户消息(以小程序客服示例)
2.1 用户发送消息,转发到配置服务器。
消息格式:
<xml>
<ToUserName><![CDATA[gh_b2a88d1]]></ToUserName>
<FromUserName><![CDATA[oi85twEuEkM7jYbLDCI]]></FromUserName>
<CreateTime>1548418010</CreateTime>
<MsgType><![CDATA[voice]]></MsgType>
<MediaId><![CDATA[wHeKlgHf0voj3aS57Vt45Ow_KhYjXrAUlPYGapSvAS1SIv543y4vApu]]></MediaId>
<Format><![CDATA[amr]]></Format>
<MsgId>6650404713487400960</MsgId>
<Recognition><![CDATA[喂喂喂喂喂喂。]]></Recognition>
</xml>
2.2 解析消息,根据openid保存用户消息,记录消息类型、内容、日期。图片可以预先下载保存到服务器。
2.3 每日首次收到某一用户(openid)消息时,启用定时器,若30分钟内(自定义一个时间)未能及时回复,系统自动回复一条消息(如提醒电话客服),避免超过30分钟无法回复消息。
@Override
public void run() {
try {
//10分钟后查询,是否回复过
Thread.sleep(1000 * 60 * 10);
List<KFMessage> list = KFConst.messageMap.get(openid);
if (list != null && !list.isEmpty()) {
boolean hasReplied = hasReplied(list);
if (!hasReplied) {
myLog.printString("reponse expire in 10 min");
String access_token = getMiniProgramToken();
KFMessageHandler.sendKf(access_token, openid, "售后客服不在线,建议您电话咨询:07**-23****07","text");
KFConst.finishMap.put(openid, true);//设置已通知过,本条消息一天发送一次就够了。
}
}
} catch(Exception e){
e.printStackTrace();
}
}
2.4 将消息通过特定方式发送给指定客服人员微信(后台记录该用户openid即可)
以下为使用服务号,发送模板消息给客服人员。
//公众号接口,发送模板消息给客服人员
/**
*
* @param kfOpenid 客服人员openid对应公众号
* @param openid 用户昵称或openid,无昵称则显示openid
* @param msgType 消息类型
* @param content 消息内容
* @param access_token 公众号access_token
* @return
*/
public static boolean sendTemplate(String kfOpenid,String openid,String msgType, String content, String access_token) {
JSONObject jsonObject = new JSONObject();
jsonObject.put("touser", kfOpenid);
jsonObject.put("template_id", KFConst.TEMPLATE_ID); //公众号模板id
jsonObject.put("url", KFConst.KFURL);//点击详情进入的H5页面
JSONObject first = new JSONObject();
first.put("value", "您有新的售后客服消息");
JSONObject keyword1 = new JSONObject();
keyword1.put("value", openid);
JSONObject keyword2 = new JSONObject();
keyword2.put("value", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
JSONObject remark = new JSONObject();
remark.put("value", "内容为: " + content);
JSONObject data = new JSONObject();
data.put("first", first);
data.put("keyword1", keyword1);
data.put("keyword2", keyword2);
data.put("remark", remark);
jsonObject.put("data", data);
String url = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" + access_token;
String doPost = HttpUtil.doPostHttps(new URL(url), data);
JSONObject jsonObject = JSONObject.fromObject(doPost);
return jsonObject.containsKey("errcode") && jsonObject.get("errcode").equals(0);
}
2.5 客服人员点击模板消息,进入服务器开发的手机版网页。网页根据openid对消息进行分类显示。
2.6 回复消息后,通过微信小程序提供的接口,直接发送文字或图片。
- 网页上传图片至微信小程序服务器,可调用公众号相同接口,文档点此查看。图片上传成功后,获取media_id。用于发送消息给用户。
/**
* 消息客服消息接口,发送消息给用户
* @param access_token //小程序access_token
* @param openid //小程序openid
* @param text 文本消息为文本内容,图片为media_id
* @param msgtype text/image
* @return
*/
public static boolean sendKf(String access_token, String openid, String text, String msgtype){
if (msgtype == null || (!msgtype.equals("text") && !msgtype.equals("image"))) {
return false;
}
String url = "https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=" + access_token;
try {
JSONObject jsonObject = new JSONObject();
jsonObject.put("touser", openid);
jsonObject.put("msgtype", msgtype);
JSONObject textObject = new JSONObject();
if (msgtype.equals("text")) {
textObject.put("content", text);
jsonObject.put("text", textObject.toString());
}else if (msgtype.equals("image")) {
textObject.put("media_id", text);
jsonObject.put("image", textObject.toString());
}
String doPost = HttpUtil.doPostHttps(new URL(url), jsonObject.toString());
System.out.println(doPost);
JSONObject fromObject = JSONObject.fromObject(doPost);
KFConst.myLog.printString("sendkf:" + doPost);
KFConst.myLog.closedBr();
if (fromObject.containsKey("errcode") && fromObject.get("errcode").equals(0)) {
//状态为0,表示客服会话发送成功。
return true;
}
} catch (Exception e) {
e.printStackTrace();
KFExceptionHandler.printException(e, "sendkf");
}
return false;
}
2.7 结果展示
3、其他关注点
3.1 为了更好的显示网页聊天效果,需要通过微信按钮组件,获取小程序用户昵称并保存。
<button class="wechat_button" openType="contact" >微信客服</button>
3.2 同时登录PC端微信和手机端微信时,手机端接收模板消息时,不会有铃声或震动提醒 。
3.3 目前小程序模板消息,需要在提交表单时或支付时预存form_id。不推荐使用。
3.4 特殊情况,需要转发客服消息至客服平台。
如有错误,请指正。