日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

springBoot企业微信引入会话存档SDK

發布時間:2024/1/8 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 springBoot企业微信引入会话存档SDK 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一:準備工作

業務需求,需要用企業微信實現消息通信,一對一通信有接口可以直接實現,下面就說一下這群聊,
企業微信并沒有給出群聊獲取消息的接口,就需要引入會話存檔SDK來獲取群聊消息,下面說一下前期的準備工作。
先就是填一個申請表,開通會話存檔權限,這個功能是收費的,但是先一個月免費,足夠開發調試了,
能用到這個功能的,說明那些基礎的已經知道了,那就直接開始了
生成公鑰和密鑰對,地址:http://web.chacuo.net/netrsakeypair

將公鑰填寫在客戶端,注意版本,修改一個公鑰,對應的版本就需要+1

二:引入依賴

需要這樣引入依賴,不然的話有2個依賴有沖突,無法解密

<dependency><groupId>org.bouncycastle</groupId><artifactId>bcpg-jdk16</artifactId><version>1.46</version><exclusions><exclusion><groupId>org.bouncycastle</groupId><artifactId>bcprov-jdk16</artifactId></exclusion></exclusions></dependency><dependency><groupId>org.bouncycastle</groupId><artifactId>bcpkix-jdk15on</artifactId><version>1.64</version></dependency>

三:下載SDK,先說windows版本

將sdk中的.dll文件直接放入C:\Windows\System32目錄下,然后在環境變量的Path中添加該目錄。
注意:sdk中的Finace.java文件必須放入項目的com.tencent.wework目錄下

四:linux版本引入sdk,docker中部署

將下載的.so文件放在改項目的lib文件目錄下面,方便尋找,盡量不要放在系統的lib目錄下面

需要在dockerfile文件中配置動態鏈路庫,找到改.so文件
第一句是copy文件到lib下面 第二局在啟動時加入改環境變量
COPY ./lib/libWeWorkFinanceSdk_Java.so /usr/lib/libWeWorkFinanceSdk_Java.so
ENV LD_LIBRARY_PATH=/disk2/docker/qywx/lib:$LD_LIBRARY_PATH

五:初始化加載靜態代碼塊

static {if(isWindows()){System.out.println(System.getProperty("java.library.path"));System.loadLibrary("WeWorkFinanceSdk");}else {System.out.println(System.getProperty("java.library.path"));System.loadLibrary("WeWorkFinanceSdk_Java");}}public static boolean isWindows() {String osName = System.getProperties().getProperty("os.name");System.out.println("current system is " + osName);return osName.toUpperCase().indexOf("WINDOWS") != -1;}

注意區別:加載windows和linux的文件是不一樣的,仔細琢磨以下,這里可以把path打印出來看一下
如果部署到線上linux服務器,引入SDK無報錯也無反應,大概率就是這里文件沒有加載上

六:配置回調url

這里插一下如何配置回調url,需要封裝get和post兩種請求,get只用于驗證,post用于業務,這一點要仔細看文檔,通過返回的消息體,就可以解析出里面的消息內容,通過mq返回給前端

@GetMapping("/message/callback")@ResponseBody()public String callback(HttpServletRequest request, @RequestParam("msg_signature") String sVerifyMsgSig, @RequestParam("timestamp") String sVerifyTimeStamp, @RequestParam("nonce") String sVerifyNonce, @RequestParam("echostr") String sVerifyEchoStr) throws Exception {String sToken = "";String sCorpID = "";String sEncodingAESKey = "";WXBizMsgCrypt wxcpt = new WXBizMsgCrypt(sToken, sEncodingAESKey, sCorpID);String sEchoStr; //需要返回的明文try {sEchoStr = wxcpt.VerifyURL(sVerifyMsgSig, sVerifyTimeStamp,sVerifyNonce, sVerifyEchoStr);return sEchoStr;// 驗證URL成功,將sEchoStr返回// HttpUtils.SetResponse(sEchoStr);} catch (Exception e) {//驗證URL失敗,錯誤原因請查看異常e.printStackTrace();}return "error";} @PostMapping("/message/callback")@ResponseBody()public void callbackData(HttpServletRequest request, @RequestBody() String sRespData, @RequestParam("msg_signature") String sVerifyMsgSig, @RequestParam("timestamp") String sReqTimeStamp, @RequestParam("nonce") String sReqNonce) throws Exception {String sToken = "";String sCorpID = "";String sEncodingAESKey = "";WXBizMsgCrypt wxcpt = new WXBizMsgCrypt(sToken, sEncodingAESKey, sCorpID);String sMsg = wxcpt.DecryptMsg(sVerifyMsgSig, sReqTimeStamp, sReqNonce, sRespData);System.out.println("解密decrypt企業微信推送的消息->sMsg:" + sMsg);DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();DocumentBuilder db = dbf.newDocumentBuilder();StringReader sr = new StringReader(sMsg);InputSource is = new InputSource(sr);Document document = db.parse(is);//獲取整個XML消息體,進行解析Element root = document.getDocumentElement();//返回消息的公共部分,內容,創建時間,消息ID,來源,去處NodeList nodelistTime = root.getElementsByTagName("CreateTime");String CreateTime = nodelistTime.item(0).getTextContent();NodeList nodelistFrom = root.getElementsByTagName("FromUserName");String fromUserName = nodelistFrom.item(0).getTextContent();NodeList nodelistTo = root.getElementsByTagName("ToUserName");String toUserName = nodelistTo.item(0).getTextContent();Map<String, String> msgMap = new HashMap<String, String>();msgMap.put("CreateTime", CreateTime);msgMap.put("fromUser", fromUserName);msgMap.put("to", toUserName);//消息類型,不同消息返回不同消息體NodeList typeNodelist = root.getElementsByTagName("MsgType");String MsgType = typeNodelist.item(0).getTextContent();msgMap.put("msgType", MsgType);//文本直接返回if (StringUtils.equals(MsgType, "text")) {NodeList nodelistMsgId = root.getElementsByTagName("MsgId");String MsgId = nodelistMsgId.item(0).getTextContent();msgMap.put("msgId", MsgId);NodeList nodelist = root.getElementsByTagName("Content");String Content = nodelist.item(0).getTextContent();msgMap.put("text", Content);//自定義返回消息類型,只支持字符串類型Map<String, Object> getMsg = new HashMap<String, Object>();getMsg.put("msg", msgMap);String message = JSONArray.toJSON(getMsg).toString();rabbitTemplate.convertAndSend("qywx_exange", null, message);//圖片返回圖片需要增加url和mediaId}}

七:開發

幾個注意的點:
1.seq是傳入的每次拉取消息索引,可以根據返回消息的長度獲取該值

Integer newSeq = (Integer) chatdata.getJSONObject(chatdata.length()-1).get("seq");System.out.println(newSeq);

2.消息解密和消息加密、
3.linux服務器上消息拉取會亂碼,用下面那種方式轉一下,不行的話,還是亂碼就是Linxu服務器不支持GBK編碼,目前我也沒解決

public static Map pullMsg(Integer seq) throws Exception {long sdk = Finance.NewSdk();Finance.Init(sdk, corpid, secret); // 初始化long ret = 0;//int seq = 0;int limit = 1000;long slice = Finance.NewSlice();List msgList = new ArrayList();Map resultMap = new HashMap();//拉取聊天記錄ret = Finance.GetChatData(sdk, seq, limit, null, null, 15, slice);if (ret != 0) {return resultMap;}//獲取切片中的內容String getchatdata = Finance.GetContentFromSlice(slice);JSONObject jo = new JSONObject(getchatdata);//聊天內容JSONArray chatdata = jo.getJSONArray("chatdata");if(chatdata.length() > 1){Integer newSeq = (Integer) chatdata.getJSONObject(chatdata.length()-1).get("seq");resultMap.put("lastSeq",newSeq);}else{resultMap.put("lastSeq",0);}System.out.println("消息數:" + chatdata.length());String msgContent = null;for (int i = 0; i < chatdata.length(); i++) {String item = chatdata.get(i).toString();JSONObject data = new JSONObject(item);//加密密鑰String encrypt_random_key = data.getString("encrypt_random_key");//加密聊天消息String encrypt_chat_msg = data.getString("encrypt_chat_msg");long msg = Finance.NewSlice();try {//解密String message = RSAEncrypt.decryptRSA(encrypt_random_key, priKey);//使用SDK獲取msg明文ret = Finance.DecryptData(sdk, message, encrypt_chat_msg, msg);System.out.println(ret);if (ret != 0) {return resultMap;}msgContent =new String(Finance.GetContentFromSlice(msg).getBytes("GBK"),"UTF-8");msgList.add(msgContent);Finance.FreeSlice(msg);} catch (Exception e) {e.printStackTrace();}}Finance.FreeSlice(slice);resultMap.put("data",msgList);return resultMap;}

八:消息加密和消息解密

這個方法拿過去就不要動了,直接就能用

public class RSAEncrypt {public static String decryptRSA(String str, String privateKey) throws Exception {Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());//此處的"RSA/ECB/PKCS1Padding", "BC"不可以改變,改變會導致解密亂碼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;} }

9,總結

最后,總結一下吧,因為這個功能是要實時獲取群聊的消息,但這個會話存檔不能做到,有點雞肋,主要是做不到實時,會話存檔嘛,有點延遲,大概6-7s吧,體驗不好,看了企微那邊的介紹,也問了客服找了案例,大多數用這個會話存檔做scrm系統

總結

以上是生活随笔為你收集整理的springBoot企业微信引入会话存档SDK的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。