UNPKG

@use-services/wechatlite

Version:
213 lines (212 loc) 8.11 kB
"use strict"; 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;