@use-services/wechatlite
Version:
```ts import * as WechatLite from "@use-services/wechatlite";
213 lines (212 loc) • 8.11 kB
JavaScript
;
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.sha1 = exports.WechatLiteBusinessError = exports.WechatLiteArgError = exports.WechatLiteRequestError = exports.init = exports.Service = void 0;
/* eslint-disable camelcase */
const use_services_1 = require("use-services");
const crypto = require("crypto");
const axios_1 = require("axios");
class Service {
constructor(option) {
this.args = option.args;
this.args.timeout = this.args.timeout || 2500;
}
wxBizDataDecrypt(sessionKeyRaw, encryptedDataRaw, ivRaw) {
const { appId } = this.args;
const sessionKey = Buffer.from(sessionKeyRaw, "base64");
const encryptedData = Buffer.from(encryptedDataRaw, "base64");
const iv = Buffer.from(ivRaw, "base64");
let decoded;
try {
const decipher = crypto.createDecipheriv("aes-128-cbc", sessionKey, iv);
decipher.setAutoPadding(true);
decoded = decipher.update(encryptedData, "binary", "utf8");
decoded += decipher.final("utf8");
decoded = JSON.parse(decoded);
}
catch (err) {
throw new WechatLiteArgError("wechatlite: biz data decrypt failed");
}
if (decoded.watermark.appid !== appId) {
throw new WechatLiteArgError("wechatlite: biz data decrypt failed");
}
return decoded;
}
code2Session(code) {
return __awaiter(this, void 0, void 0, function* () {
const { appId, secret, timeout } = this.args;
const resp = yield (0, axios_1.default)({
method: "get",
url: "https://api.weixin.qq.com/sns/jscode2session",
timeout,
params: {
appid: appId,
secret,
js_code: code,
grant_type: "authorization_code",
},
responseType: "json",
});
return resp.data;
});
}
getWXACodeUnlimit(accessToken, page, scene) {
return __awaiter(this, void 0, void 0, function* () {
const resp = yield (0, axios_1.default)({
url: "https://api.weixin.qq.com/wxa/getwxacodeunlimit",
method: "post",
timeout: this.args.timeout,
params: {
access_token: accessToken,
},
data: JSON.stringify({
scene,
page,
}),
});
return resp.data;
});
}
getAccessToken() {
return __awaiter(this, void 0, void 0, function* () {
const { appId, secret, timeout } = this.args;
const resp = yield (0, axios_1.default)({
url: "https://api.weixin.qq.com/cgi-bin/token",
timeout,
params: {
appid: appId,
secret,
grant_type: "client_credential",
},
});
return resp.data;
});
}
sendCustomerMessage(accessToken, msg) {
return __awaiter(this, void 0, void 0, function* () {
const resp = yield (0, axios_1.default)({
url: "https://api.weixin.qq.com/cgi-bin/message/custom/send",
method: "post",
timeout: this.args.timeout,
params: {
access_token: accessToken,
},
data: JSON.stringify(msg),
});
return resp.data;
});
}
sendTemplateMessage(accessToken, msg) {
return __awaiter(this, void 0, void 0, function* () {
const resp = yield (0, axios_1.default)({
url: "https://api.weixin.qq.com/cgi-bin/message/wxopen/template/send",
method: "post",
timeout: this.args.timeout,
params: {
access_token: accessToken,
},
data: JSON.stringify(msg),
});
return resp.data;
});
}
uploadTempMedia(accessToken, img, imgfile, imgtype) {
return __awaiter(this, void 0, void 0, function* () {
const resp = yield (0, axios_1.default)({
url: "https://api.weixin.qq.com/cgi-bin/media/upload",
method: "post",
timeout: this.args.timeout,
params: {
access_token: accessToken,
type: "image",
},
data: JSON.stringify({
media: {
value: img,
options: {
contentType: imgtype,
filename: imgfile,
},
},
}),
});
});
}
checkSignature(signature, timestamp, nonce) {
const { token } = this.args;
if (!token) {
throw new WechatLiteArgError("wechatlite args token is required");
}
const key = [token, timestamp, nonce].sort().join("");
return sha1(key) === signature;
}
decryptWXContact(wechatData) {
const { encodingAESKey } = this.args;
if (!encodingAESKey) {
throw new WechatLiteArgError("wechatlite args token is required");
}
const key = Buffer.from(encodingAESKey + "=", "base64");
const iv = key.slice(0, 16);
const result = decryptContact(key, iv, wechatData);
const decryptedResult = JSON.parse(result);
return decryptedResult;
}
checkError(name, err, body) {
if (err) {
return new WechatLiteRequestError(`wechatlite: ${name} request failed, err ${err.message}`);
}
if (body.errcode) {
return new WechatLiteBusinessError(`wechatlite: ${name} failed, ${body.errcode}, ${body.errmsg}`, body.errcode, body.errmsg);
}
}
}
exports.Service = Service;
exports.init = (0, use_services_1.createInitFn)(Service);
class WechatLiteRequestError extends Error {
}
exports.WechatLiteRequestError = WechatLiteRequestError;
class WechatLiteArgError extends Error {
}
exports.WechatLiteArgError = WechatLiteArgError;
class WechatLiteBusinessError extends Error {
constructor(msg, errcode, errmsg) {
super(msg);
this.errcode = errcode;
this.errmsg = errmsg;
}
}
exports.WechatLiteBusinessError = WechatLiteBusinessError;
function decryptContact(key, iv, crypted) {
const aesCipher = crypto.createDecipheriv("aes-256-cbc", key, iv);
aesCipher.setAutoPadding(false);
let decipheredBuff = Buffer.concat([
aesCipher.update(crypted, "base64"),
aesCipher.final(),
]);
decipheredBuff = decodePKCS7(decipheredBuff);
const lenNetOrderCorpid = decipheredBuff.slice(16);
const msgLen = lenNetOrderCorpid.slice(0, 4).readUInt32BE(0);
const result = lenNetOrderCorpid.slice(4, msgLen + 4).toString();
return result;
}
function decodePKCS7(buff) {
let pad = buff[buff.length - 1];
if (pad < 1 || pad > 32) {
pad = 0;
}
return buff.slice(0, buff.length - pad);
}
function sha1(data) {
const shasum = crypto.createHash("sha1");
shasum.update(data);
return shasum.digest("hex");
}
exports.sha1 = sha1;