wework-chat
Version:
wework chat node version
166 lines (140 loc) • 6.32 kB
JavaScript
const java = require("java");
const path = require('path');
const weworkJdkPath = path.join(__dirname, "jar", "java_sdk.jar");
const rsaPath = path.join(__dirname, "jar", "rsa.jar");
java.options.push('-Djava.library.path=' + path.join(__dirname, 'lib'));
java.classpath.push(weworkJdkPath);
java.classpath.push(rsaPath);
const Finance = java.import('com.tencent.wework.Finance');
const RSAUtil = java.import('org.francislyj.RSAUtil');
const getPrivateKey = function(publickey_ver, keyMap){
return keyMap[publickey_ver];
};
class WeworkSdk {
constructor(corpid, secret){
this.corpid = corpid;
this.secret = secret;
this.initSdk();
}
initSdk() {
if(this.sdk){
Finance.DestroySdkSync(this.sdk);
}
this.sdk = Finance.NewSdkSync();
let ret = Finance.InitSync(this.sdk, this.corpid, this.secret);
if(ret != 0){
Finance.DestroySdkSync(this.sdk);
throw new Error('sdk init failed ret:' + ret);
}
}
async decryptData(encrypt_key, encrypt_chat_msg){
let msg = await this.newSlice();
let ret = Finance.DecryptDataSync(this.sdk, encrypt_key, encrypt_chat_msg, msg);
if (ret != 0) {
await this.freeSlice(msg);
throw new Error('parse content error ret' + ret);
}
const result = Finance.GetContentFromSliceSync(msg);
await this.freeSlice(msg);
return result;
};
/**
* 拉取回话内容
* params: keyMap 私钥键值对{version, privateKey} 需采用RSA PKCS1秘钥
* */
async getChatData(seq, limit, proxy, passwd, timeout, keyMap, secret) {
if(!!secret && secret != this.secret){
this.secret = secret;
this.initSdk();
}
if(!keyMap){
throw new Error("param keyMap must not be null");
}
for(let version in keyMap){
let value = keyMap[version];
if(value.indexOf("BEGIN RSA PRIVATE KEY") < 0){
throw new Error("private key must be rsa pkcs1");
}
}
seq = seq || 0;
limit = limit || 10;
timeout = timeout || 20;
//每次使用GetChatData拉取存档前需要调用NewSlice获取一个slice,在使用完slice中数据后,还需要调用FreeSlice释放。
let slice = await this.newSlice();
let ret = Finance.GetChatDataSync(this.sdk, seq, limit, proxy, passwd, timeout, slice);
if (ret != 0) {
await this.freeSlice(slice);
throw new Error('get chat data error: ret' + ret);
}
let result = Finance.GetContentFromSliceSync(slice);
await this.freeSlice(slice);
result = JSON.parse(result);
if(result.errcode == 0){
const chatdatas = result.chatdata;
for(let chatdata of chatdatas){
try{
let privateKey = getPrivateKey(chatdata.publickey_ver, keyMap);
if(!!privateKey){
let encrypt_key = await this.decryptRSA(privateKey, chatdata.encrypt_random_key);
let content = await this.decryptData(encrypt_key, chatdata.encrypt_chat_msg);
chatdata.content = JSON.parse(content);
}
}catch(error){
console.log('chat decrypt error:', error);
}
}
}
return result;
};
async decryptRSA(privateKey, ncrypt_random_key){
let privateKeyObj = RSAUtil.getPrivateKeySync(privateKey);
let str = RSAUtil.decryptRSASync(ncrypt_random_key, privateKeyObj);
return str;
};
async newSlice(){
return Finance.NewSliceSync();
};
async freeSlice(slice){
Finance.FreeSliceSync(slice);
};
async getMediaData(sdkfileid, proxy, passwd, timeout, handleBuffer, secret){
if(!!secret && secret != this.secret){
this.secret = secret;
this.initSdk();
}
//媒体文件每次拉取的最大size为512k,因此超过512k的文件需要分片拉取。若该文件未拉取完整,sdk的IsMediaDataFinish接口会返回0,同时通过GetOutIndexBuf接口返回下次拉取需要传入GetMediaData的indexbuf。
//indexbuf一般格式如右侧所示,”Range:bytes=524288-1048575“,表示这次拉取的是从524288到1048575的分片。单个文件首次拉取填写的indexbuf为空字符串,拉取后续分片时直接填入上次返回的indexbuf即可。
let indexbuf = "";
while(true){
//每次使用GetMediaData拉取存档前需要调用NewMediaData获取一个media_data,在使用完media_data中数据后,还需要调用FreeMediaData释放。
let media_data = Finance.NewMediaDataSync();
let ret = Finance.GetMediaDataSync(this.sdk, indexbuf, sdkfileid, proxy, passwd, timeout, media_data);
if(ret!=0){
Finance.FreeMediaDataSync(media_data);
throw new Error('get media data error ret' + ret);
}
console.log(`getmediadata outindex len:%d, data_len:%d, is_finis:%d`,Finance.GetIndexLenSync(media_data),Finance.GetDataLenSync(media_data), Finance.IsMediaDataFinishSync(media_data));
try {
let buffer = Finance.GetDataSync(media_data);
console.log('=======> buffer.length:', buffer.length);
// let buffer = Buffer.from(data);
let isFinish = Finance.IsMediaDataFinishSync(media_data) == 1;
await handleBuffer(buffer, isFinish);
buffer = null;
} catch (error) {
console.log('wirie file error ====>', error);
}
if(Finance.IsMediaDataFinishSync(media_data) == 1) {
//已经拉取完成最后一个分片
Finance.FreeMediaDataSync(media_data);
break;
} else {
//获取下次拉取需要使用的indexbuf
indexbuf = Finance.GetOutIndexBufSync(media_data);
Finance.FreeMediaDataSync(media_data);
}
media_data = null;
}
};
}
module.exports = WeworkSdk;