在微信公众平台上,单看接口文档,遇到很多问题,有些我们可能会理解错,下面我给大家介绍下我在开发过程中遇到的问题,希望对大家有帮助。
先来看看我们要达到什么效果:
1、我们在公众号后台开通客服:添加功能插件,找到客服,开通,然后进入客服功能页面添加客服。
2、用户关注公众号后,在公众号发消息:
3、然后客服在 https://mpkf.weixin.qq.com 登录,会看到有一人待接入,点击接入,客服就可以和用户对话了。
现在我们来看具体的实现方式:
1、在微信公众号后台,找到基本配置,服务器配置url。
url是自己在后端写的接口。
比如,关注,取关等,当用户点击关注时,调用该url,进行自己的业务。当然我们要做的将消息转发到客服也要写在这个逻辑里。
2、看官网API:
根据官网解释,我们需要返回MsgType为transfer_customer_service的消息,这句刚开始没读懂意思,以为是用户在公众号发送的消息类型都是transfer_customer_service,后来根据日志看,并不是这样,用户在公众号可以发很多种普通消息,包括:text,video,voice,shortvideo,link,image等,列举的这几种都是需要转发到客服系统的,对于如:菜单点击、地理位置上报等不应转接,这个在文档里也有。
我们需要做的是将用户发的这几种消息,转成MsgType为transfer_customer_service,然后微信服务器收到响应后会把当次发送的消息转发至客服系统(这步是微信服务器做的,我们不用管)。
3、开始开发:
4、核心代码:
//消息转发到客服
if (msgType.equals(MsgUtil.MESSAGE_TYPE_TEXT) || msgType.equals(MsgUtil.MESSAGE_TYPE_IMAGE)
|| msgType.equals(MsgUtil.MESSAGE_TYPE_VOICE) || msgType.equals(MsgUtil.MESSAGE_TYPE_VIDEO)
|| msgType.equals(MsgUtil.MESSAGE_TYPE_LINK) || msgType.equals(MsgUtil.MESSAGE_TYPE_SHORT_VIDEO)){
logger.info("用户{}转发客服{}",userOpenId,wxId);
GraphicMessage message = new GraphicMessage();
message.setToUserName(userOpenId);
message.setFromUserName(wxId);
message.setMsgType(MsgUtil.EVENT_TYPE_TRANSFER);
message.setCreateTime(time);
return MsgUtil.domainToXml(message);
}
GraphicMessage:
@Data
public class GraphicMessage {
// 接收方帐号(收到的OpenID)
private String ToUserName;
// 开发者微信号
private String FromUserName;
// 消息创建时间 (整型)
private long CreateTime;
// 消息类型(text/music/news/voice/image/video)
private String MsgType;
}
MsgUtil:
/**
* 转发客服消息对象转换成xml
*
* @param domain 转发客服消息对象
* @return xml
*/
public static String domainToXml(GraphicMessage domain){
xstream.alias("xml", domain.getClass());
return xstream.toXML(domain);
}
/**
* 扩展xstream,使其支持CDATA块
*
* @date 2013-05-19
*/
private static XStream xstream = new XStream(new XppDriver() {
public HierarchicalStreamWriter createWriter(Writer out) {
return new PrettyPrintWriter(out) {
// 对所有xml节点的转换都增加CDATA标记
boolean cdata = true;
@SuppressWarnings("unchecked")
public void startNode(String name, Class clazz) {
super.startNode(name, clazz);
}
protected void writeText(QuickWriter writer, String text) {
if (cdata) {
writer.write("<![CDATA[");
writer.write(text);
writer.write("]]>");
} else {
writer.write(text);
}
}
};
}
});
5、解决的问题:测试时,向公众号发消息,报错:公众号提供服务出现故障,请稍后重试!
查了查,最终找到了原因:toUserName和fromUserName取反了,错误的以为微信里toUserName和fromUserName取得一样。
这篇博客对于“公众号提供服务出现故障,请稍后重试”问题,总结了几种原因,值得一看,请参考博客:https://blog.csdn.net/fanrenxiang/article/details/80877600
参考接口文档:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1458557405
总结:
看清文档定义,不要以为微信里的相同字段名称取值都一样。