上篇文章中已经开启了微信小程序的消息推送:【微信小程序】1、SpringBoot整合WxJava开启消息推送,接下来我们就对微信中用户发送的客服消息,转发到微信客服来处理回复
1、添加微信客服
登录微信公众平台,在客服模块,添加微信客服,输入客服的微信号,客服人员就会收到客服绑定通知,绑定即可,这里我已经添加了一名客服
2、消息推送配置信息
在 开发管理 --》开发设置 向下拉,找到 消息推送设置
开启微信推送,并配置相关参数
- 1、URL,即微信推送消息的时候,调用你的 api 接口地址
- 2、Token,这个为自定义 token,做参数校验使用的
- 3、EncodingAESKey,消息加密密钥,我们可以选择随机生成
- 4、消息加密方式,我们为了数据安全,推荐选择 “安全模式”
- 5、数据格式,我们选择 JSON 或 XML 都行,推荐使用 XML
对应下项目配置文件信息如下:
# 微信开发配置
wx:
# 微信小程序开发
miniapp:
appid: xxxxxxxxxxxxxxxxxxxxxx
secret: xxxxxxxxxxxxxxxxxxxxxxxxx
# 配置消息推送需要
token: xxxxxxxxxxxxxx
aes-key: xxxxxxxxxxxxxxxxxxx
msgDataFormat: XML
# 存储类型,如不配置redis相关连接信息,相会使用springboot配置的redis连接信息
config-storage:
type: redistemplate
3、接收处理微信消息
官方文档:客服消息指南
https://developers.weixin.qq.com/miniprogram/introduction/custom.html
其中,将消息转发到客服 部分截图如下:
我们可以得出,我们需要返回给微信服务器的 msgType 为 transfer_customer_service 即可将消息转发到客服,实现如下:
import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaMessage;
import cn.binarywang.wx.miniapp.constant.WxMaConstants;
import cn.binarywang.wx.miniapp.message.WxMaXmlOutMessage;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.io.IOException;
/**
* 微信小程序消息推送
*/
@Slf4j
@RestController
@RequestMapping("wx/ma/welcome")
public class WxMaMsgController {
@Autowired
private WxMaService wxMaService;
/**
* 消息校验,确定是微信发送的消息
*
* @param signature
* @param timestamp
* @param nonce
* @param echostr
* @return
* @throws Exception
*/
@GetMapping
public String doGet(String signature, String timestamp, String nonce, String echostr) {
// 消息合法
if (wxMaService.checkSignature(timestamp, nonce, signature)) {
log.info("-------------微信小程序消息验证通过");
return echostr;
}
// 消息签名不正确,说明不是公众平台发过来的消息
return null;
}
/**
* 微信小程序事件推送
*
* @return
* @throws Exception
*/
@PostMapping
public String doPost(@RequestBody String requestBody,
@RequestParam(name = "msg_signature", required = false) String msgSignature,
@RequestParam(name = "encrypt_type", required = false) String encryptType,
@RequestParam(name = "signature", required = false) String signature,
@RequestParam("timestamp") String timestamp,
@RequestParam("nonce") String nonce) throws IOException {
// 解密消息
WxMaMessage wxMaMessage = getWxMaMessage(requestBody, msgSignature, encryptType, signature, timestamp, nonce);
log.info("收到消息:{}", wxMaMessage);
// 转到客服
WxMaXmlOutMessage wxMaXmlOutMessage = new WxMaXmlOutMessage();
wxMaXmlOutMessage.setToUserName(wxMaMessage.getFromUser());
wxMaXmlOutMessage.setFromUserName(wxMaMessage.getToUser());
// 转发到客服
wxMaXmlOutMessage.setMsgType("transfer_customer_service");
wxMaXmlOutMessage.setCreateTime(System.currentTimeMillis());
return toWxMaOutMessage(wxMaXmlOutMessage, encryptType);
}
/**
* 解析消息
*
* @param requestBody
* @param msgSignature
* @param encryptType
* @param signature
* @param timestamp
* @param nonce
* @return
*/
public WxMaMessage getWxMaMessage(String requestBody, String msgSignature, String encryptType, String signature, String timestamp, String nonce) {
// 明文传输
if (StringUtils.isBlank(encryptType)) {
// json
if (WxMaConstants.MsgDataFormat.JSON.equals(wxMaService.getWxMaConfig().getMsgDataFormat())) {
return WxMaMessage.fromJson(requestBody);
} else {
return WxMaMessage.fromXml(requestBody);
}
}
// aes加密
else if ("aes".equals(encryptType)) {
// json
if (WxMaConstants.MsgDataFormat.JSON.equals(wxMaService.getWxMaConfig().getMsgDataFormat())) {
return WxMaMessage.fromEncryptedJson(requestBody, wxMaService.getWxMaConfig());
}
// xml
else {
return WxMaMessage.fromEncryptedXml(requestBody, wxMaService.getWxMaConfig(), timestamp, nonce, msgSignature);
}
}
throw new RuntimeException("不可识别的消息加密方式");
}
/**
* 返回给微信服务器的消息
*
* @param wxMaXmlOutMessage
* @param encryptType
* @return
*/
public String toWxMaOutMessage(WxMaXmlOutMessage wxMaXmlOutMessage, String encryptType) {
// 明文传输
if (StringUtils.isBlank(encryptType)) {
return wxMaXmlOutMessage.toXml();
}
// aes加密
else if ("aes".equals(encryptType)) {
return wxMaXmlOutMessage.toEncryptedXml(wxMaService.getWxMaConfig());
}
throw new RuntimeException("不可识别的消息加密方式");
}
}
- GET 请求,是用作微信服务器消息验证用的,确保消息是微信服务器下发的
- POST 请求,是用来接受微信服务器发送的具体的事件及消息的
1、当我们收到微信服务器发送的消息及事件的时候,我们都将它转发到微信客服去,这里只是为了演示,我们并不需要把所有的消息及事件都进行转发,这样只会增加微信客服的工作量,
2、将返回的消息类型设置为“transfer_customer_service”即表示转发到客服
4、使用 uniapp 调起微信客服
官方文档:
https://uniapp.dcloud.io/component/button.html
在页面放置一个按钮,设置按钮的 open-type=“contact”,即可调起微信客服,支持:微信小程序、百度小程序
5、测试
- 1、用户端
打开你开发的小程序(体验版也行)
放置了一个打开客服的按钮,就会跳转到客服页面
此时已经出现了“XXX 为您服务”,我们向客服发送消息
“小蜜蜂1号”是我在小程序管理端给客服的名字,“小蜜蜂1号”已接入,表示我们已经将消息转发到了客服
- 2、客服端
有了新的客户咨询
点击进入,打开了我们的“客服小助手”小程序
可以看到咨询的用户信息,可以点击回复
- 3、用户端
用户收到客服回复的消息
如您在阅读中发现不足,欢迎留言!!!