文章目录

  • 前言
  • 一、企业微信事件接收服务器
    • 1、配置企业微信事件接收服务器
  • 二、关联企业微信客户和小程序用户
    • 1.小程序获取unionid
    • 2.企业微信获取unionid

前言

接上文步骤,通过小程序引流到企业微信中,需要追踪小程序的用户添加企业微信管理员以及加入企业微信群的情况,本文记录了如何去关联

一、企业微信事件接收服务器

通过配置企业微信事件接收服务,当客户有添加企业微信管理员的时候,企业微信会通知导服务器,从而知道小程序引流的用户的后续动作

1、配置企业微信事件接收服务器

登录企业微信官网,打开客户联系–>客户页面,点开api按钮

a、获取Secret
b、绑定对应的微信小程序
c、配置接收事件服务器

输入接收通知url地址,token以及EncodingAESKey保存的时候,通知服务器会接收到一条验证请求,需要返回解析好的参数才能通过验证,具体代码如下:

 public class QywxController extends BaseController{@Autowiredprivate QywxService qywxService;@RequestMapping(value = "/change",method = {RequestMethod.GET, RequestMethod.POST})@ResponseBodypublic String change(@RequestParam("msg_signature") String signature, @RequestParam("timestamp") String timestamp, @RequestParam("nonce") String nonce,@RequestParam(value = "echostr") String echostr) throws Exception {return qywxService.verifyUrl(signature,timestamp,nonce,echostr);}}public class QywxService {@Value("${qywxCorpid}")private String sCorpID;@Value("${qywxMsgReplyToken}")private String token;@Value("${qywxEncodingAESKey}")private String encodingAESKey;public String verifyUrl(String signature, String timestamp, String nonce,String echostr) throws AesException {WXBizMsgCrypt wxcpt = new WXBizMsgCrypt(token, encodingAESKey, sCorpID);return wxcpt.VerifyURL(signature,timestamp,nonce,echostr);}
}

WXBizMsgCrypt 类为官方提供代码,可以自行下载
https://work.weixin.qq.com/api/doc/90000/90138/90307

验证通过后即可接收到企业微信的通知回调

二、关联企业微信客户和小程序用户

主要方式是通过用户的unionid来关联企业微信和小程序的用户

1.小程序获取unionid

登录微信开放平台,绑定小程序

绑定后微信接口中即可获取用户的unionid

2.企业微信获取unionid

当用户添加企业微信管理员后,企业微信会将事件回调给事件接收服务器,并带上用户的标识"ExternalUserID",然后再通过企业微信的获取unionid接口获取到unionid并和小程序的用户关联起来
具体代码如下

public class QywxController extends BaseController{@Autowiredprivate QywxService qywxService;@RequestMapping(value = "/change",method = {RequestMethod.GET, RequestMethod.POST})@ResponseBodypublic String change(@RequestParam("msg_signature") String signature, @RequestParam("timestamp") String timestamp, @RequestParam("nonce") String nonce,@RequestBody String body) throws Exception {qywxService.handel(signature,timestamp,nonce,body);return "success";}
}public class QywxService {@Value("${qywxCorpid}")private String sCorpID;@Value("${qywxMsgReplyToken}")private String token;@Value("${qywxEncodingAESKey}")private String encodingAESKey;@Resource(name = "qywxHandelMap")private Map<String, IQywxHandel> qywxHandelMap;public void handel(String signature, String timestamp, String nonce,String body)throws Exception {WXBizMsgCrypt wxcpt = new WXBizMsgCrypt(token, encodingAESKey, sCorpID);String sMsg = wxcpt.DecryptMsg(signature, timestamp, nonce, body);DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();DocumentBuilder db = dbf.newDocumentBuilder();StringReader sr =null;try {log.info(sMsg);sr=new StringReader(sMsg);InputSource is = new InputSource(sr);Document document = db.parse(is);Element root = document.getDocumentElement();String event=this.getNodeValue(root,"Event");String changeType=this.getNodeValue(root,"ChangeType");log.info("event:"+event+";changeType:"+changeType);IQywxHandel handel=qywxHandelMap.get(event+"_"+changeType);if(handel!=null){String externalUserID=this.getNodeValue(root,"ExternalUserID");QywxBean qywxBean=new QywxBean();qywxBean.setEvent(event);qywxBean.setChangeType(changeType);qywxBean.setExternalUserID(externalUserID);handel.handel(qywxBean);}}catch(Exception e){throw e;}finally {if(sr!=null){sr.close();}}}private String getNodeValue(Element root,String nodeName){NodeList nodelist1 = root.getElementsByTagName(nodeName);return nodelist1.item(0).getTextContent();}
}public class BaseQywxHandel implements IQywxHandel {@Autowiredprivate WxConfig wxConfig;protected String parseUnionId(String externalUserID) throws Exception {String accessToken=this.getAccessToken();String url=String.format(PushConstants.WxUrl.QYWX_GET_UNIONID_URL,accessToken,externalUserID);String response= HTTPUtils.httpGet(url);Map<String,Object> map= JsonUtil.fromJson(response,Map.class);if(map.get("errcode")!=null&&(Integer)map.get("errcode")==0){Map<String,Object> m=(Map<String, Object>)map.get("external_contact");return (String)m.get("unionid");}throw new Exception("get unionid fail!"+response);}private String getAccessToken() throws Exception {String url=String.format(PushConstants.WxUrl.QYWX_GET_TOKEN_URL,wxConfig.getQywxCorpid(),wxConfig.getQywxCorpSecret());String response= HTTPUtils.httpGet(url);Map<String,Object> map= JsonUtil.fromJson(response,Map.class);if(map.get("errcode")!=null&&(Integer)map.get("errcode")==0){return (String)map.get("access_token");}throw new Exception("get access_token fail!"+response);}}

JAVA企业微信事件接收相关推荐

  1. 企业微信 事件接收服务器,授权通知事件

    [TOC] 授权成功通知 从企业微信应用市场发起授权时,企业微信后台会推送授权成功通知. 从第三方服务商网站发起的应用授权流程,由于授权完成时会跳转第三方服务商管理后台,因此不会通过此接口向第三方服务 ...

  2. java企业微信消息发送工具类

    java企业微信消息发送工具类 用途 基于java实现调用企业微信发送消息,文件,图片. 实现效果 文件列表 文件名 用途 WechatUtil.java 企业微信工具类 WechatTest.jav ...

  3. Java企业微信会话存档开发(从跳坑到爬坑)

    Java企业微信会话存档开发(从跳坑到爬坑) 本文仅作为方便首次开发企业微信使用 文章目录 Java企业微信会话存档开发(从跳坑到爬坑) 前言 一.开发准备 1.企业微信后台配置 2.sdk下载 3. ...

  4. Nodejs版本的企业微信中接收消息与腾讯对接之验证URL 代码已经上传,可以去下载

    1 当我们开发企业微信中的消息推送的时候,如果要接收来自用户的信息,需要提供一个接收消息的服务器地址来对接,如果使用nodejs来开发的话,按照文档说明,你可能不会成功.下面总结下我自己的步骤,已经成 ...

  5. Java企业微信开发-企业微信所有类型消息推送封装

    企业微信开发第一步获取AccessToken,企业微信的AccessToken和公众号的不一样,企业微信所有接口调用只需要一个AccessToken,而公众号授权和jssdk是分开的 一.获取企业微信 ...

  6. Java 企业微信会话内容(聊天记录)存档功能实现,并获取媒体文件

    注:本文档是在Linux环境下进行测试的. 今天终于有空来聊聊企业微信"会话内容存档",虽然官方有给出开发文档,但确实是有点晦涩难懂啊,对于我这种菜鸟来说. 在网上翻阅许多教程,也 ...

  7. Java企业微信对接(一)企业端同步到微信端

    封装用户和部门对象 用户对象 /***@className: WeXinUserVO*@description: 企业微信用户数据同步*@author: what*@date: 2022/4/21 1 ...

  8. java企业微信发送语言_java微信企业号开发之发送消息(文本、图片、语音)

    上篇文章介绍了开启回调模式,开始回调模式后我们就要实现聊天功能了.平时使用微信聊天可以发送文本消息.语音.图片.视频等,这里只实现了其中的一些功能和大家分享. 一.与微信企业号建立连接1.企业应用调用 ...

  9. Java企业微信开发_00_源码及资源汇总贴

    一.源码 此系列教程的源码我都放在了github上,欢迎fork以及关注. 传送门:https://github.com/shirayner/WeiXin_QiYe_Demo/tree/master ...

  10. Nodejs版本的企业微信中接收消息与腾讯对接之接收消息 代码已经上传,可以去下载

    1 再经过前面的URL验证成功后,我们下面可以来写接收消息的请求了. 2 官方是这样说明的, msg_signature,timestamp,nonce参数的值还是比较好获取,接收的数据: <x ...

最新文章

  1. go语言服务器连接mysql_go语言原生连接数据库
  2. MyBatis 中的 set 元素用法(MyBatis 3.1.1)
  3. 一文读懂目标检测模型(附论文资源)
  4. python库pickle的用法
  5. UML 中各种图形重要性的排行
  6. TortoiseSVN Launch Failed Error:系统找不到指定路径
  7. 直方图尖峰python_Python系统学习 - 绘制直方图
  8. Unable to find required classes (javax.activation.DataHandler and javax.mail.internet.MimeMultipart)
  9. lwip连续发数据卡死_Mysteel:12月全球铁矿石发运量稳中微增 进口矿咋走?
  10. Javascript中常用的经典技巧
  11. 启发函数 (Heuristic Function) —Octile
  12. 【知识图谱】04RDF数据生成(使用D2RQ)
  13. hdu4489(递推)
  14. 手机备忘录里的照片怎么保存到相册里
  15. 牛客OR36 .链表的回文结构
  16. NSKeyedArchiver/unArchiver序列化自定义复合模型(模型包含模型)
  17. vcenter 起不来报错VMware ESX 找不到虚拟磁盘“vCenter Server 7.0U3_12.vmdk”。请确认路径有效并重试
  18. shell编程4-shell嵌套循环及随机数
  19. 叙述式教学方案计算机技术,叙述式教学设计方案模板(1)
  20. 雅思培训心得(1)摸底测试听力与阅读

热门文章

  1. python英文词频统计软件_英语词频统计软件功能介绍
  2. 水晶头做网线颜色排列
  3. python中isalpha()、isdigit()、isalnum()、isupper()、islower()的含义、区别和细节
  4. 如何求解最大公约数和最小公倍数
  5. 排序算法问题:稳定排序与不稳定排序
  6. 网站备案其实是服务器备案,网站备案指的是备案域名还是备案主机空间
  7. ISTQB FL初级认证考试资料(中文)
  8. 努比亚手机浏览器 安全证书失效_今日热闻 | OnePlus 8海外版发布、Redmi科幻大片第一部公布、努比亚Play 5G宣布、快播正式破产拍卖...
  9. 「缠师课后回复精选」第15课:没有趋势,没有背驰。
  10. linux qt 生成word报告_Qt 生成word、pdf文档