企业微信推送suite_ticket对接

企业微信推送suite_ticket对接,由于微信文档不详细,很多地方还有错误,所以对接的时候很是痛苦。通过查阅各种文档,加上整合demo才最终对接成功,拿到了suite_ticket。

推送suite_ticket的文档说是一个POST接口,其实还有一个验证的GET接口,而且需要URL一致的。比如我的接口都是“/suite/receive”。

下面接对接通过代码展示,首先是对接参数:

    private final String sToken = "Token";private final String sCorpID = "CorpID";private final String suiteID = "SuiteID";private final String sEncodingAESKey = "EncodingAESKey";

这些参数都是可以通过企业微信管理后台拿到的,比如
在这里插入图片描述
然后是企业微信参数解析类

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.util.Arrays;
import java.util.Base64;/*** 描述:微信参数解密工具** @author 罗锅* @date 2021/9/2 11:44*/
public class WXBizMsgCrypt {byte[] aesKey;String token;String receiveId;/*** 构造函数** @param token          企业微信后台,开发者设置的token* @param encodingAesKey 企业微信后台,开发者设置的EncodingAESKey* @param receiveId,     不同场景含义不同,详见文档*/public WXBizMsgCrypt(String token, String encodingAesKey, String receiveId) {this.token = token;this.receiveId = receiveId;aesKey = Base64.getDecoder().decode(encodingAesKey + "=");}/*** 验证并获取解密后数据** @param msgSignature 签名串,对应URL参数的msg_signature* @param timeStamp    时间戳,对应URL参数的timestamp* @param nonce        随机串,对应URL参数的nonce* @param echoStr      随机串,对应URL参数的echostr* @return 解密之后的echoString* @throws Exception 执行失败,请查看该异常的错误码和具体的错误信息*/public String verifyAndGetData(String msgSignature, String timeStamp, String nonce, String echoStr)throws Exception {String signature = getSignature(token, timeStamp, nonce, echoStr);if (!signature.equals(msgSignature)) {throw new Exception("参数验签不通过");}return decrypt(echoStr);}/*** 获取参数签名** @param token* @param timestamp* @param nonce* @param encrypt* @return* @throws Exception*/private String getSignature(String token, String timestamp, String nonce, String encrypt) throws Exception {String[] array = new String[]{token, timestamp, nonce, encrypt};StringBuilder sb = new StringBuilder();// 字符串排序Arrays.sort(array);for (String s : array) {sb.append(s);}String str = sb.toString();// SHA1签名生成MessageDigest md = MessageDigest.getInstance("SHA-1");md.update(str.getBytes());byte[] digest = md.digest();StringBuilder hexStringBuilder = new StringBuilder();String shaHex;for (byte b : digest) {shaHex = Integer.toHexString(b & 0xFF);if (shaHex.length() < 2) {hexStringBuilder.append(0);}hexStringBuilder.append(shaHex);}return hexStringBuilder.toString();}/*** 对密文进行解密.** @param text 需要解密的密文* @return 解密得到的明文* @throws Exception aes解密失败*/private String decrypt(String text) throws Exception {// 设置解密模式为AES的CBC模式Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");SecretKeySpec secretKeySpec = new SecretKeySpec(aesKey, "AES");IvParameterSpec ivParameterSpec = new IvParameterSpec(Arrays.copyOfRange(aesKey, 0, 16));cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec);// 使用BASE64对密文进行解码byte[] encrypted = Base64.getDecoder().decode(text);// 解密byte[] original = cipher.doFinal(encrypted);// 去除补位字符byte[] bytes = decode(original);// 分离16位随机字符串,网络字节序和receiveIdbyte[] networkOrder = Arrays.copyOfRange(bytes, 16, 20);int xmlLength = recoverNetworkBytesOrder(networkOrder);String xmlContent = new String(Arrays.copyOfRange(bytes, 20, 20 + xmlLength), StandardCharsets.UTF_8);String fromReceiveId = new String(Arrays.copyOfRange(bytes, 20 + xmlLength, bytes.length),StandardCharsets.UTF_8);// receiveId不相同的情况if (!fromReceiveId.equals(receiveId)) {throw new Exception("receiveId不相同");}return xmlContent;}/*** 还原4个字节的网络字节序** @param orderBytes* @return*/int recoverNetworkBytesOrder(byte[] orderBytes) {int sourceNumber = 0;int length = 4;for (int i = 0; i < length; i++) {sourceNumber <<= 8;sourceNumber |= orderBytes[i] & 0xff;}return sourceNumber;}/*** 删除解密后明文的补位字符** @param decrypted 解密后的明文* @return 删除补位字符后的明文*/private byte[] decode(byte[] decrypted) {int pad = decrypted[decrypted.length - 1];int min = 1;int max = 32;if (pad < min || pad > max) {pad = 0;}return Arrays.copyOfRange(decrypted, 0, decrypted.length - pad);}
}

然后是验证接口,推送suite_ticket是这样的,要先用GET请求验证接口,验证通过了以后才可以保存并推送suite_ticket。

    @GetMapping("/suite/receive")public String suiteReceive(@RequestParam(value = "msg_signature") String msgSignature,@RequestParam(value = "timestamp") String timestamp, @RequestParam(value = "nonce") String nonce,@RequestParam(value = "echostr") String data) {System.out.println("GET################################");System.out.println("msgSignature:" + msgSignature);System.out.println("timestamp:" + timestamp);System.out.println("nonce:" + nonce);System.out.println("data:" + data);try {WXBizMsgCrypt wxcpt = new WXBizMsgCrypt(sToken, sEncodingAESKey, sCorpID);String sEchoStr = wxcpt.verifyAndGetData(msgSignature, timestamp, nonce, data);System.out.println("aesDecode:" + sEchoStr);// 将解密后获取的参数直接返回就行return sEchoStr;} catch (Exception e) {e.printStackTrace();}}

验证通过后,就可以刷新Ticket了。

@PostMapping("/suite/receive")public String suiteReceivePost(HttpServletRequest request,@RequestParam(value = "msg_signature") String msgSignature,@RequestParam(value = "timestamp") String timestamp, @RequestParam(value = "nonce") String nonce) {System.out.println("POST################################");System.out.println("msgSignature:" + msgSignature);System.out.println("timestamp:" + timestamp);System.out.println("nonce:" + nonce);String result = null;try {String xmlString = getXMLString(request);System.out.println("data:" + xmlString);String encryptData = XML.toJSONObject(xmlString).getJSONObject("xml").getStr("Encrypt");System.out.println("encryptData:" + encryptData);WXBizMsgCrypt wxcpt = new WXBizMsgCrypt(sToken, sEncodingAESKey, suiteID);String sEchoStr = wxcpt.verifyAndGetData(msgSignature, timestamp, nonce, encryptData);;System.out.println("sEchoStr:" + sEchoStr);JSONObject jsonObject = XML.toJSONObject(sEchoStr).getJSONObject("xml");System.out.println("jsonObject:" + jsonObject.toString());String infoType = jsonObject.getStr("InfoType");System.out.println("infoType:" + infoType);// 获取到的suiteTicketString suiteTicket = jsonObject.getStr("SuiteTicket");System.out.println("suiteTicket:" + suiteTicket);} catch (Exception e) {e.printStackTrace();}// 该接口返回successreturn "success";}

可以看到,GET和POST接口的URI是一致的,不同的是参数和返回内容。验证接口是GET请求,加密内容是URL里获取的,接口直接返回解密内容就行。推送suite_ticket接口是POST请求,加密内容是在请求体里的,接口返回“success”表示成功。

推送suite_ticket接口回调成功以后,每半小时推送一次,注意保存suite_ticket后续接口调用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/56429.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java对接企业微信

java对接企业微信 一、注册企业微信 1.1 简介 企业微信与微信具有一样的体验&#xff0c;通过企业内部与外部客户的管理&#xff0c;构建出社群生态。企业微信提供丰富的api进行调用获取数据管理&#xff0c;也提供各种回调事件。 1.2 注册 登录官网&#xff0c;一键注册即可…

ChatGPT遇上WebRTC:生成式AI对实时通信意味着什么

ChatGPT正在改变计算&#xff0c;并作为一种延伸&#xff0c;改变我们与机器的互动方式。下面是它将如何影响WebRTC。 ChatGPT 成为所有互联网应用程序中增长率最高的服务&#xff0c;在推出的头两个月内就达到了 1 亿活跃用户。一些人每天都在使用它。其他人正在尝试使用它&a…

LLM应用专辑(3) — ChatGPT遇上文档搜索:ChatPDF、ChatWeb、DocumentQA等开源项目算法思想与源码解析

原文&#xff1a;LLM应用专辑(3) — ChatGPT遇上文档搜索&#xff1a;ChatPDF、ChatWeb、DocumentQA等开源项目算法思想与源码解析 - 知乎 公众号在上一篇文章中&#xff0c;我们介绍了chatgpt与nlp结合过程中的一些具体prompt生成方法&#xff0c;掌握这些可以有效地提升生产…

Android的img镜像文件打开

有时需要获取系统的一些资源&#xff0c;就需要打开img镜像文件&#xff1b;可以使用&#xff1a;ext2explore.exe.exe 此篇以打开Android API 22的system.img为例&#xff0c;system.img文件可以在sdk目录system-images文件下 eg: 相对路径&#xff1a;android-sdk-windows\s…

使用tp5写登录验证及修改密码

使用到的工具 1,thinkphp5.0自带的验证码: think-captcha 可查看&#xff1a; https://www.kancloud.cn/manual/thinkphp5/154295 2,前台页面框架: layui 3,引用到的文件: jquery.min.js layui.css 登录样式最终图形 登录的html <body style"background:#f2f2f2…

基于MATLAB的隐函数偏导与多重积分(附代码)

一. 隐函数的偏导数 给定隐函数&#xff1a; 隐函数的偏导可得&#xff1a; MATLAB格式&#xff1a; F-diff(f,xj)/diff(f,xi) 例题1 已知&#xff1a; 求&#xff1a; 解&#xff1a; MATLAB代码&#xff1a; clc;clear; syms x y; f(x^2-2*x)*exp(-x^2-y^2-x*y); prett…

Wolfram Alpha 算微积分指令集合

一、Wolfram Alpha介绍 Wolfram Alpha网址&#xff1a;https://www.wolframalpha.com/ WolframAlpha是开发计算数学应用软件的沃尔夫勒姆研究公司开发出的新一代的搜索引擎&#xff0c;能根据问题直接给出答案的网站&#xff0c;用户在搜索框键入需要查询的问题后&#xff0c…

利用MATLAB求符号微积分

文章目录 摘要1 符号函数的极限&#xff08;1&#xff09;极限&#xff08;2&#xff09;单边极限 2 符号函数的导数3 符号函数的积分&#xff08;1&#xff09;不定积分&#xff08;2&#xff09;定积分 结语 摘要 本文是《科学计算与MATLAB语言》专题七第2小节的学习笔记&am…

高等数值计算方法学习笔记第4章第一部分【数值积分(数值微分)】

高等数值计算方法学习笔记第4章第一部分【数值积分&#xff08;数值微分&#xff09;】 一、数值积分概论1.数值求积的基本思想(牛-莱公式找不到原函数&#xff0c;用矩形近似)2.代数精度的概念1.上述四个公式的代数精度&#xff08;梯形&#xff0c;左中右矩形公式&#xff09…

真的能从脑电信号识别出我的情绪吗?

关注“心仪脑”查看更多脑科学知识的分享。 提到情绪&#xff0c;我们脑海中可能会浮现出各种各样的场景&#xff0c;可能是“哭着&#xff0c;叫着&#xff0c;像个孩子在胡闹”的悲痛。 &#xff08;图片来源于网络&#xff09; 抑或是《Lie to me》中Cal Lightman深邃的一双…

读取大脑计算机软件,专访脑机接口专家Jose:读取大脑信息已成现实

腾讯科技 韩依民 11月7日报道 《生活大爆炸》中有一个经典的搞笑桥段&#xff1a;谢耳朵手摁太阳穴&#xff0c;幻想通过脑电波攻击室友。这一举动因荒诞不羁而产生喜剧效果&#xff0c;但是一种新的科学技术正在让谢耳朵的幻想部分变成现实。 利用捕捉器将人们脑子里进行的活动…

脑机接口猴子通过“意念”打游戏!马斯克:未来能让瘫痪者用意念玩手机

来源&#xff1a;新智元 它是Pager&#xff0c;一只9岁的恒河猴&#xff0c;来自Neuralink&#xff0c;最近它刚刚get了新技能——用意念玩乒乓球游戏。 6个星期前&#xff0c;Pager的脑袋里被植入了两个叫N1 Link的装置&#xff0c;工作人员用香蕉奶昔诱惑它玩游戏&#xff0c…

证明人脑细胞在体外也有感知,「盘中之脑」论文正式登Cell子刊

詹士 发自 凹非寺量子位 | 公众号 QbitAI 这有一个放在盘中的「大脑」&#xff0c;它以为自己是游戏角色&#xff0c;其活着的意义就是完成游戏任务。 有「黑客帝国」内味儿了&#xff1f;&#xff1f;&#xff1f; 现实中&#xff0c;这个盘中大脑有人做出来了&#xff0c;命名…

Hinton 最新访谈:不出五年,我们就会破解大脑的运作机制,但不是通过反向传播...

点击上方“视学算法”&#xff0c;选择加"星标"或“置顶” 重磅干货&#xff0c;第一时间送达 整理丨李梅、黄楠 来源丨AI科技评论 编辑丨极市平台 导读 过去十年&#xff0c;AI 在计算机视觉、语音识别、机器翻译、机器人、医学、计算生物学、蛋白质折叠预测等等领…

ChatGPT时代,如何训练大脑,以后不会被人工智能取代

当有一天&#xff0c;你的小孩子问我将来会不会被AI代替的时候&#xff0c;为人父母的我们应该怎么回答小孩子的问题呢&#xff1f;不知各位是否刷到一位名为浅爸谈英语的博主爸爸分享与他女儿关于AI对话的视频。 这段对话很有启发性&#xff0c;父亲的回答也很中肯。可以通过…

脑机接口照进现实:5位脑科学家带来的最新启示

大脑复杂、神秘&#xff0c;研究大脑被认为是人类终极的探索之一。作为最为复杂的科学探索领域&#xff0c;大脑的研究既令人着迷&#xff0c;也同样令人望而生畏。 脑机接口技术会使人类退化吗&#xff1f;一旦脑机接口技术得到应用&#xff0c;人类的自由意志会被他人操纵吗&…

马斯克脑机接口、BrainOS 相继发布,未来已来?

作者 | 马超 责编 | Carol 封图 | CSDN 下载自视觉中国 在北京时间的8月29日凌晨&#xff0c;钢铁侠埃隆马斯克投资1亿多美元的脑机接口初创公司公司Neuralink进行现场发布会&#xff0c;展示新一代的脑机接口设备。 这场发布会的热度可以和苹果iPhone4发布会相媲美&#xff0c…

脑科学真的可以启发AI吗?

智源导读&#xff1a;人工智能发展到当前阶段&#xff0c;大家都开始认识到脑科学和人工智能有很密切的关系&#xff0c;脑科学会对人工智能的发展产生很大帮助。反过来思考这个问题&#xff0c;脑科学对人工智能研究真的有帮助吗&#xff1f;离开脑科学之后&#xff0c;人工智…

Google员工说出了我不敢说的心里话!

前言&#xff1a;本文来自Beyond的投稿&#xff0c;码农翻身做了修改。 今天在Medium上看到一篇文章《The maze is in the mouse》&#xff0c;是一个刚从Google离职的员工写的&#xff0c;揭开了Google内部的各种问题&#xff0c;引发了很多人的共鸣&#xff0c;到目前为止&am…

RepVGG论文详解(结合代码)

目录 1.简介 2.RepVGG详情 2.1 RepVGG Block 2.2 结构重参数化 2.2.1融合Conv2d和BN&#xff0c;将三个分支上的卷积算子和BN算子都转化为卷积算子&#xff08;包括卷积核和偏置&#xff09; 2.2.2 将每个分支都扩充为一个3x3卷积核加一个偏置&#xff0c;然后进行相加融合…