springBoot企业微信引入会话存档SDK
一:準(zhǔn)備工作
業(yè)務(wù)需求,需要用企業(yè)微信實(shí)現(xiàn)消息通信,一對(duì)一通信有接口可以直接實(shí)現(xiàn),下面就說(shuō)一下這群聊,
企業(yè)微信并沒(méi)有給出群聊獲取消息的接口,就需要引入會(huì)話存檔SDK來(lái)獲取群聊消息,下面說(shuō)一下前期的準(zhǔn)備工作。
先就是填一個(gè)申請(qǐng)表,開(kāi)通會(huì)話存檔權(quán)限,這個(gè)功能是收費(fèi)的,但是先一個(gè)月免費(fèi),足夠開(kāi)發(fā)調(diào)試了,
能用到這個(gè)功能的,說(shuō)明那些基礎(chǔ)的已經(jīng)知道了,那就直接開(kāi)始了
生成公鑰和密鑰對(duì),地址:http://web.chacuo.net/netrsakeypair
將公鑰填寫在客戶端,注意版本,修改一個(gè)公鑰,對(duì)應(yīng)的版本就需要+1
二:引入依賴
需要這樣引入依賴,不然的話有2個(gè)依賴有沖突,無(wú)法解密
<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,先說(shuō)windows版本
將sdk中的.dll文件直接放入C:\Windows\System32目錄下,然后在環(huán)境變量的Path中添加該目錄。
注意:sdk中的Finace.java文件必須放入項(xiàng)目的com.tencent.wework目錄下
四:linux版本引入sdk,docker中部署
將下載的.so文件放在改項(xiàng)目的lib文件目錄下面,方便尋找,盡量不要放在系統(tǒng)的lib目錄下面
需要在dockerfile文件中配置動(dòng)態(tài)鏈路庫(kù),找到改.so文件
第一句是copy文件到lib下面 第二局在啟動(dòng)時(shí)加入改環(huán)境變量
COPY ./lib/libWeWorkFinanceSdk_Java.so /usr/lib/libWeWorkFinanceSdk_Java.so
ENV LD_LIBRARY_PATH=/disk2/docker/qywx/lib:$LD_LIBRARY_PATH
五:初始化加載靜態(tài)代碼塊
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;}注意區(qū)別:加載windows和linux的文件是不一樣的,仔細(xì)琢磨以下,這里可以把path打印出來(lái)看一下
如果部署到線上linux服務(wù)器,引入SDK無(wú)報(bào)錯(cuò)也無(wú)反應(yīng),大概率就是這里文件沒(méi)有加載上
六:配置回調(diào)url
這里插一下如何配置回調(diào)url,需要封裝get和post兩種請(qǐng)求,get只用于驗(yàn)證,post用于業(yè)務(wù),這一點(diǎn)要仔細(xì)看文檔,通過(guò)返回的消息體,就可以解析出里面的消息內(nèi)容,通過(guò)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;// 驗(yàn)證URL成功,將sEchoStr返回// HttpUtils.SetResponse(sEchoStr);} catch (Exception e) {//驗(yàn)證URL失敗,錯(cuò)誤原因請(qǐng)查看異常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企業(yè)微信推送的消息->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);//獲取整個(gè)XML消息體,進(jìn)行解析Element root = document.getDocumentElement();//返回消息的公共部分,內(nèi)容,創(chuàng)建時(shí)間,消息ID,來(lái)源,去處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}}七:開(kāi)發(fā)
幾個(gè)注意的點(diǎn):
1.seq是傳入的每次拉取消息索引,可以根據(jù)返回消息的長(zhǎng)度獲取該值
2.消息解密和消息加密、
3.linux服務(wù)器上消息拉取會(huì)亂碼,用下面那種方式轉(zhuǎn)一下,不行的話,還是亂碼就是Linxu服務(wù)器不支持GBK編碼,目前我也沒(méi)解決
八:消息加密和消息解密
這個(gè)方法拿過(guò)去就不要?jiǎng)恿?#xff0c;直接就能用
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"不可以改變,改變會(huì)導(dǎo)致解密亂碼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,總結(jié)
最后,總結(jié)一下吧,因?yàn)檫@個(gè)功能是要實(shí)時(shí)獲取群聊的消息,但這個(gè)會(huì)話存檔不能做到,有點(diǎn)雞肋,主要是做不到實(shí)時(shí),會(huì)話存檔嘛,有點(diǎn)延遲,大概6-7s吧,體驗(yàn)不好,看了企微那邊的介紹,也問(wèn)了客服找了案例,大多數(shù)用這個(gè)會(huì)話存檔做scrm系統(tǒng)
總結(jié)
以上是生活随笔為你收集整理的springBoot企业微信引入会话存档SDK的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 亚马逊个人创业这条路行的通吗?
- 下一篇: 花998购买的拍摄技巧和7天起号培训文档