700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > 微信公众号自动回复及多客服功能实现

微信公众号自动回复及多客服功能实现

时间:2023-04-01 11:37:22

相关推荐

微信公众号自动回复及多客服功能实现

目录

前期准备1、微信公众平台基本设置2、开发所需参数功能步骤1、填写服务器配置2、验证服务器地址的有效性3、依据接口文档实现业务逻辑具体实现1、微信接入2、自定义回复及多客服接入

默认微信公众平台对公众号的自动回复、多客服等功能都是可以直接使用的。

但是由于一些因素(扫码登录)开放了微信公众号接口,导致以上功能需要自己对接,无法直接使用平台提供的功能。

以下是我对公众号自动回复和多客服实现的一些心得。

效果:

前期准备

1、微信公众平台基本设置

公众号官网:https://mp.

公众号客服系统地址:https://mpkf./

登录前需公众号管理员设置客服账号:

基本配置:

AppSecret:自动生成

IP白名单:服务器外网ip(调用“获取access_token”接口,返回结果。如非白名单IP调用,将返回错误码:40164)

服务器地址:备案的域名下的某个可访问路径

Token令牌: 自定义

消息加密密钥:自动生成即可

消息加密解密方式:安全模式

2、开发所需参数

开发者ID(AppID)

开发者密码(AppSecret)

服务器令牌(Token)

消息加解密密钥(EncodingAESKey)

功能步骤

1、填写服务器配置
2、验证服务器地址的有效性

开发者提交信息后,微信服务器将发送GET请求到填写的服务器地址URL上,GET请求携带参数如下表所示:

开发者通过检验signature对请求进行校验(下面有校验方式)。若确认此次GET请求来自微信服务器,请原样返回echostr参数内容,则接入生效,成为开发者成功,否则接入失败。加密/校验流程如下:

1)将token、timestamp、nonce三个参数进行字典序排序

2)将三个参数字符串拼接成一个字符串进行sha1加密

3)开发者获得加密后的字符串可与signature对比,标识该请求来源于微信

3、依据接口文档实现业务逻辑

具体实现

全局常量:

//@Value("${DNBX_TOKEN}")private String DNBX_TOKEN = 服务器令牌token;

1、微信接入

接入地址需要和配置中的服务器地址匹配

/*** 微信接入* 必须为get方式获取接口参数并验证* @return* @throws IOException*/@RequestMapping(value = "/connect", method = RequestMethod.GET)public void connectWeixin(HttpServletRequest request, HttpServletResponse response) throws IOException {PrintWriter print;//获取微信接口参数String signature = request.getParameter("signature");String timestamp = request.getParameter("timestamp");String nonce = request.getParameter("nonce");String echostr = request.getParameter("echostr");LOGGER.info("\n[signature=" + signature+ "][timestamp=" + timestamp+ "][nonce=" + nonce+ "][echostr=" + echostr+ "][token=" + DNBX_TOKEN + "]");// 通过检验signature对请求进行校验,若校验成功则原样返回echostr,表示接入成功,否则接入失败if (signature != null && WeChatUtil.checkSignature(signature, DNBX_TOKEN, timestamp, nonce)) {try {print = response.getWriter();print.write(echostr);print.flush();print.close();LOGGER.info("wechat auth success...");} catch (IOException e) {e.printStackTrace();}} else {LOGGER.info("wechat auth failure...");}}

2、自定义回复及多客服接入

@RequestMapping(value = "/connect", method = RequestMethod.POST, produces = "application/xml;charset=UTF-8")public void wechatPost(HttpServletRequest request, HttpServletResponse response) throws IOException {request.setCharacterEncoding("UTF-8");response.setCharacterEncoding("UTF-8");LOGGER.info("wechat post request start...");PrintWriter print = response.getWriter();String reqStr = IOUtils.toString(request.getInputStream());LOGGER.info("解密请求消息:");try {//对消息加密,相关工具类官方已提供WXBizMsgCrypt pc = new WXBizMsgCrypt(DNBX_TOKEN, 消息加解密密钥EncodingAESKey, 开发者AppID);String timeStamp = String.valueOf(System.currentTimeMillis()); // 时间戳String nonce = DateUtil.format(new Date(), "yyyyMMddHHmmss"); // 随机字符串print = response.getWriter();String msgSignature = request.getParameter("msg_signature");System.out.println("msgSignature = " + msgSignature);String timestamp = request.getParameter("timestamp");String urlnonce = request.getParameter("nonce");System.out.println("urlnonce = " + urlnonce);String openid = request.getParameter("openid");String encrypt_type = request.getParameter("encrypt_type");String decryptStr = pc.decryptMsg(msgSignature, timestamp, urlnonce, reqStr);System.out.println("decryptStr = " + decryptStr);//LOGGER.info("解密后的请求消息:" + decryptStr);//XmlAndMap是自己封装的xml转map的工具类,此处是自动解析decryptStr为xml然后转map,如过不爱自己写可以留下邮箱索要Map<String, String> req = XmlAndMap.xmlToMap(decryptStr);Map<String, String> rsp = new HashMap<String, String>();//获取解密后的数据并封装Maprsp.put("ToUserName", req.get("FromUserName"));rsp.put("FromUserName", req.get("ToUserName"));rsp.put("CreateTime", req.get("CreateTime"));String replymsg = "";//判断返回的数据类型是否是事件if (req.get("Event") != null) {if (req.get("Event").equals("subscribe")) {//判断当前事件是关注事件rsp.put("MsgType", "Text");rsp.put("Content", "自定义的欢迎语句内容");}} else {//此处为消息类型Map replyMap = new HashMap();replyMap.put("人工客服", "正在为您链接到客服人员,请耐心等候……");//加载关键词及其回复内容List<KeyWordReply> keyWordReplies = keyWordService.selectKeyWords();for (KeyWordReply keyword : keyWordReplies) {String[] split = keyword.getKeyWord().split(",");for (String item : split) {replyMap.put(item.trim(), keyword.getText());}}//用户输入词汇与自定义的关键词匹配if (replymsg != null && replyMap.containsKey(req.get("Content").trim())) {if ("人工客服".equals(req.get("Content"))) {LOGGER.info("人工客服===================");//人工客服对接MsgType类型为transfer_customer_servicersp.put("MsgType", "transfer_customer_service");rsp.put("Content", replymsg);} else {LOGGER.info("自动回复===================");replymsg = (String) replyMap.get(req.get("Content"));rsp.put("MsgType", "Text");rsp.put("Content", replymsg);}} else {用户输入词汇与自定义的关键词匹配失败自动回复内容replymsg = "您好!如有问题,请输入【人工客服】寻求帮助。";rsp.put("MsgType", "Text");rsp.put("Content", replymsg);}//LOGGER.info("加密前响应报文:\n" + XmlAndMap.mapToXml2(rsp));}//回复内容加密并输出String miwen = pc.encryptMsg(XmlAndMap.mapToXml2(rsp), timestamp, urlnonce);print.write(miwen);//LOGGER.info("加密后响应报文:\n" + miwen);print.flush();print.close();} catch (IOException e) {e.printStackTrace();} catch (AesException e) {e.printStackTrace();}}

1)、代码中提到的消息类型及数据结构参考:官方文档

2)、对消息加密,加密工具类官方提供:官方代码

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。