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

您所在的位置:网站首页 微信保存功能 Java 企业微信会话内容(聊天记录)存档功能实现,并获取媒体文件

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

2024-07-17 09:02| 来源: 网络整理| 查看: 265

注:本文档是在Linux环境下进行测试的。

今天终于有空来聊聊企业微信“会话内容存档”,虽然官方有给出开发文档,但确实是有点晦涩难懂啊,对于我这种菜鸟来说。 在网上翻阅许多教程,也有点摸不着头脑,直至后面在CSDN上看到2位大神的文档,才整出个所以然。 下面就说一下我的整个开发流程: 一、申请会话内容存档接口,有1个月的试用期可申请,然后配置相关的属性。 在这里插入图片描述 这里需要注意的是“消息加密公钥”,这是用于加密和解密聊天记录的,相当重要。那个“版本号”,没更新一次,版本号就会+1,个人建议没啥必要就不要经常更换,若要更换也要把历史秘钥对保存起来。因为更新了秘钥对,之前的信息就无法解密了。 秘钥对可以通过此网站生成:http://web.chacuo.net/netrsakeypair 在这里插入图片描述 定义类RSAEncrypt做加解密处理,代码如下:

package com.tencent.wework; import org.apache.commons.codec.binary.Base64; import org.bouncycastle.openssl.PEMKeyPair; import org.bouncycastle.openssl.PEMParser; import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter; import javax.crypto.Cipher; import java.io.Reader; import java.io.StringReader; import java.security.*; public class RSAEncrypt { public static String decryptRSA(String str, String privateKey) throws Exception { Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider()); Cipher rsa = Cipher.getInstance("RSA/ECB/PKCS1Padding", "BC"); rsa.init(Cipher.DECRYPT_MODE, getPrivateKey(privateKey)); byte[] utf8 = rsa.doFinal(Base64.decodeBase64(str)); String result = new String(utf8,"UTF-8"); return result; } public static PrivateKey getPrivateKey (String privateKey) throws Exception { Reader privateKeyReader = new StringReader(privateKey); PEMParser privatePemParser = new PEMParser(privateKeyReader); Object privateObject = privatePemParser.readObject(); if (privateObject instanceof PEMKeyPair) { PEMKeyPair pemKeyPair = (PEMKeyPair) privateObject; JcaPEMKeyConverter converter = new JcaPEMKeyConverter().setProvider("BC"); PrivateKey privKey = converter.getPrivateKey(pemKeyPair.getPrivateKeyInfo()); return privKey; } return null; } }

需要添加的Maven依赖:

org.bouncycastle bcpg-jdk16 1.46 org.bouncycastle bcpkix-jdk15on 1.64

二、大致看一下官方给出的整个业务流程: 在这里插入图片描述

三、下载官方提供的SDK(小编用的是Linux环境的SDK,至于Windows的至今还没搞懂为啥报错,所以没有使用),主要是使用到libWeWorkFinanceSdk_Java.so文件,把该文件放到某目录下,可以让程序加载到就行(小编就直接放到/root/workwx/目录下了)。 项目目录结构: 在这里插入图片描述 注意:Finance类必须放在com.tencent.wework目录下,不然会报错(虽然没验证过,但很多都这样说,你们可以测试一下)

四、将官方提供的Finance类进行稍微修改:

package com.tencent.wework; public class Finance { public native static long NewSdk(); /** * 初始化函数 * Return值=0表示该API调用成功 * * @param [in] sdk NewSdk返回的sdk指针 * @param [in] corpid 调用企业的企业id,例如:wwd08c8exxxx5ab44d,可以在企业微信管理端--我的企业--企业信息查看 * @param [in] secret 聊天内容存档的Secret,可以在企业微信管理端--管理工具--聊天内容存档查看 * * @return 返回是否初始化成功 * 0 - 成功 * !=0 - 失败 */ public native static int Init(long sdk, String corpid, String secret); /** * 拉取聊天记录函数 * Return值=0表示该API调用成功 * * * @param [in] sdk NewSdk返回的sdk指针 * @param [in] seq 从指定的seq开始拉取消息,注意的是返回的消息从seq+1开始返回,seq为之前接口返回的最大seq值。首次使用请使用seq:0 * @param [in] limit 一次拉取的消息条数,最大值1000条,超过1000条会返回错误 * @param [in] proxy 使用代理的请求,需要传入代理的链接。如:socks5://10.0.0.1:8081 或者 http://10.0.0.1:8081 * @param [in] passwd 代理账号密码,需要传入代理的账号密码。如 user_name:passwd_123 * @param [out] chatDatas 返回本次拉取消息的数据,slice结构体.内容包括errcode/errmsg,以及每条消息内容。 * * @return 返回是否调用成功 * 0 - 成功 * !=0 - 失败 */ public native static int GetChatData(long sdk, long seq, long limit, String proxy, String passwd, long timeout, long chatData); /** * 拉取媒体消息函数 * Return值=0表示该API调用成功 * * * @param [in] sdk NewSdk返回的sdk指针 * @param [in] sdkFileid 从GetChatData返回的聊天消息中,媒体消息包括的sdkfileid * @param [in] proxy 使用代理的请求,需要传入代理的链接。如:socks5://10.0.0.1:8081 或者 http://10.0.0.1:8081 * @param [in] passwd 代理账号密码,需要传入代理的账号密码。如 user_name:passwd_123 * @param [in] indexbuf 媒体消息分片拉取,需要填入每次拉取的索引信息。首次不需要填写,默认拉取512k,后续每次调用只需要将上次调用返回的outindexbuf填入即可。 * @param [out] media_data 返回本次拉取的媒体数据.MediaData结构体.内容包括data(数据内容)/outindexbuf(下次索引)/is_finish(拉取完成标记) * * @return 返回是否调用成功 * 0 - 成功 * !=0 - 失败 */ public native static int GetMediaData(long sdk, String indexbuf, String sdkField, String proxy, String passwd, long timeout, long mediaData); /** * @brief 解析密文 * @param [in] encrypt_key, getchatdata返回的encrypt_key * @param [in] encrypt_msg, getchatdata返回的content * @param [out] msg, 解密的消息明文 * @return 返回是否调用成功 * 0 - 成功 * !=0 - 失败 */ public native static int DecryptData(long sdk, String encrypt_key, String encrypt_msg, long msg); public native static void DestroySdk(long sdk); public native static long NewSlice(); /** * @brief 释放slice,和NewSlice成对使用 * @return */ public native static void FreeSlice(long slice); /** * @brief 获取slice内容 * @return 内容 */ public native static String GetContentFromSlice(long slice); /** * @brief 获取slice内容长度 * @return 内容 */ public native static int GetSliceLen(long slice); public native static long NewMediaData(); public native static void FreeMediaData(long mediaData); /** * @brief 获取mediadata outindex * @return outindex */ public native static String GetOutIndexBuf(long mediaData); /** * @brief 获取mediadata data数据 * @return data */ public native static byte[] GetData(long mediaData); public native static int GetIndexLen(long mediaData); public native static int GetDataLen(long mediaData); /** * @brief 判断mediadata是否结束 * @return 1完成、0未完成 */ public native static int IsMediaDataFinish(long mediaData); static { System.load("/root/workwx/libWeWorkFinanceSdk_Java.so"); } }

五、主要业务代码:

package com.tencent.wework; import java.io.File; import java.io.FileOutputStream; import java.util.Arrays; import java.util.List; import org.json.JSONArray; import org.json.JSONObject; public class FinanceDemo { private static String priKey = "-----BEGIN RSA PRIVATE KEY-----\n" + "..." + "-----END RSA PRIVATE KEY-----"; public void demo() { long sdk = Finance.NewSdk(); Finance.Init(sdk, "corpid", "secret"); // 初始化 long ret = 0; int seq = 0; // 从指定的seq开始拉取消息,注意的是返回的消息从seq+1开始返回,seq为之前接口返回的最大seq值。首次使用请使用seq:0(这个值需要记录下来,以便下一次的拉去) int limit = 60; long slice = Finance.NewSlice(); ret = Finance.GetChatData(sdk, seq, limit, null, null, 3, slice); if (ret != 0) { System.out.println("getchatdata ret " + ret); return; } String getchatdata = Finance.GetContentFromSlice(slice); System.out.println(seq + ",拉去的聊天记录密文结果:" + getchatdata); JSONObject jo = new JSONObject(getchatdata); JSONArray chatdata = jo.getJSONArray("chatdata"); System.out.println("消息数:" + chatdata.length()); for (int i = 0; i


【本文地址】


今日新闻


推荐新闻


    CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3