wechatmenu

This commit is contained in:
qsc 2023-09-22 11:12:40 +08:00
parent e3d5443248
commit e9079ace46
25 changed files with 1665 additions and 1464 deletions

View File

@ -52,6 +52,12 @@ export declare class WechatPublicInstance {
gender: string | undefined; gender: string | undefined;
avatar: string; avatar: string;
}>; }>;
getTags(): Promise<any>;
getCurrentMenu(): Promise<any>;
getMenu(): Promise<any>;
createMenu(menuConfig: any): Promise<any>;
createConditionalMenu(menuConfig: any): Promise<any>;
deleteConditionalMenu(menuid: number): Promise<any>;
private refreshAccessToken; private refreshAccessToken;
decryptData(sessionKey: string, encryptedData: string, iv: string, signature: string): any; decryptData(sessionKey: string, encryptedData: string, iv: string, signature: string): any;
getQrCode(options: { getQrCode(options: {
@ -81,6 +87,23 @@ export declare class WechatPublicInstance {
count: number; count: number;
noContent?: 0 | 1; noContent?: 0 | 1;
}): Promise<any>; }): Promise<any>;
getArticle(options: {
article_id: string;
}): Promise<any>;
createMaterial(options: {
type: 'image' | 'voice' | 'video' | 'thumb';
media: FormData;
description?: FormData;
}): Promise<any>;
batchGetMaterialList(options: {
type: 'image' | 'video' | 'voice' | 'news';
offset?: number;
count: number;
}): Promise<any>;
getMaterial(options: {
type: 'image' | 'video' | 'voice' | 'news';
media_id: string;
}): Promise<any>;
getTicket(): Promise<string>; getTicket(): Promise<string>;
private randomString; private randomString;
signatureJsSDK(options: { signatureJsSDK(options: {

View File

@ -1,6 +1,7 @@
require('../../fetch'); require('../../fetch');
import crypto from 'crypto'; import crypto from 'crypto';
import { Buffer } from 'buffer'; import { Buffer } from 'buffer';
import URL from 'url';
export class WechatPublicInstance { export class WechatPublicInstance {
appId; appId;
appSecret; appSecret;
@ -30,7 +31,7 @@ export class WechatPublicInstance {
} }
} }
async access(url, mockData, init) { async access(url, mockData, init) {
if (process.env.NODE_ENV === 'development') { if (process.env.NODE_ENV === 'development' && mockData) {
return mockData; return mockData;
} }
const response = await global.fetch(url, init); const response = await global.fetch(url, init);
@ -61,15 +62,7 @@ export class WechatPublicInstance {
return response; return response;
} }
async code2Session(code) { async code2Session(code) {
const result = await this.access(`https://api.weixin.qq.com/sns/oauth2/access_token?appid=${this.appId}&secret=${this.appSecret}&code=${code}&grant_type=authorization_code`, { const result = await this.access(`https://api.weixin.qq.com/sns/oauth2/access_token?appid=${this.appId}&secret=${this.appSecret}&code=${code}&grant_type=authorization_code`);
access_token: 'aaa',
openid: code,
unionid: code,
refresh_token: 'aaa',
is_snapshotuser: false,
expires_in: 30,
scope: 'userinfo',
});
const { access_token, openid, unionid, scope, refresh_token, is_snapshotuser, expires_in, } = typeof result === 'string' ? JSON.parse(result) : result; // 这里微信返回的数据有时候竟然是text/plain const { access_token, openid, unionid, scope, refresh_token, is_snapshotuser, expires_in, } = typeof result === 'string' ? JSON.parse(result) : result; // 这里微信返回的数据有时候竟然是text/plain
return { return {
accessToken: access_token, accessToken: access_token,
@ -83,12 +76,7 @@ export class WechatPublicInstance {
}; };
} }
async refreshUserAccessToken(refreshToken) { async refreshUserAccessToken(refreshToken) {
const result = await this.access(`https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=${this.appId}&grant_type=refresh_token&refresh_token=${refreshToken}`, { const result = await this.access(`https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=${this.appId}&grant_type=refresh_token&refresh_token=${refreshToken}`);
access_token: 'aaa',
refresh_token: 'aaa',
expires_in: 30,
scope: 'userinfo',
});
const { access_token, refresh_token, expires_in, scope } = result; const { access_token, refresh_token, expires_in, scope } = result;
return { return {
accessToken: access_token, accessToken: access_token,
@ -98,11 +86,7 @@ export class WechatPublicInstance {
}; };
} }
async getUserInfo(accessToken, openId) { async getUserInfo(accessToken, openId) {
const result = await this.access(`https://api.weixin.qq.com/sns/userinfo?access_token=${accessToken}&openid=${openId}&lang=zh_CN`, { const result = await this.access(`https://api.weixin.qq.com/sns/userinfo?access_token=${accessToken}&openid=${openId}&lang=zh_CN`);
nickname: '码农哥',
sex: 1,
headimgurl: 'https://www.ertongzy.com/uploads/allimg/161005/2021233Y7-0.jpg',
});
const { nickname, sex, headimgurl } = result; const { nickname, sex, headimgurl } = result;
return { return {
nickname: nickname, nickname: nickname,
@ -110,10 +94,93 @@ export class WechatPublicInstance {
avatar: headimgurl, avatar: headimgurl,
}; };
} }
async getTags() {
const myInit = {
method: 'GET',
headers: {
'Content-Type': 'application/json',
},
};
const token = await this.getAccessToken();
const result = await this.access(`https://api.weixin.qq.com/cgi-bin/tags/get?access_token=${token}`, undefined, myInit);
return result;
}
async getCurrentMenu() {
const myInit = {
method: 'GET',
headers: {
'Content-Type': 'application/json',
},
};
const token = await this.getAccessToken();
const result = await this.access(`https://api.weixin.qq.com/cgi-bin/get_current_selfmenu_info?access_token=${token}`, undefined, myInit);
return result;
}
async getMenu() {
const myInit = {
method: 'GET',
headers: {
'Content-Type': 'application/json',
},
};
const token = await this.getAccessToken();
const result = await this.access(`https://api.weixin.qq.com/cgi-bin/menu/get?access_token=${token}`, undefined, myInit);
return result;
}
async createMenu(menuConfig) {
const myInit = {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(menuConfig),
};
const token = await this.getAccessToken();
const result = await this.access(`https://api.weixin.qq.com/cgi-bin/menu/create?access_token=${token}`, undefined, myInit);
const { errcode } = result;
if (errcode === 0) {
return Object.assign({ success: true }, result);
}
return Object.assign({ success: false }, result);
}
async createConditionalMenu(menuConfig) {
const myInit = {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(menuConfig),
};
const token = await this.getAccessToken();
const result = await this.access(`https://api.weixin.qq.com/cgi-bin/menu/addconditional?access_token=${token}`, undefined, myInit);
const { errcode } = result;
if (errcode === 0) {
return Object.assign({ success: true }, result);
}
return Object.assign({ success: false }, result);
}
async deleteConditionalMenu(menuid) {
const myInit = {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
menuid
}),
};
const token = await this.getAccessToken();
const result = await this.access(`https://api.weixin.qq.com/cgi-bin/menu/delconditional?access_token=${token}`, undefined, myInit);
const { errcode } = result;
if (errcode === 0) {
return Object.assign({ success: true }, result);
}
return Object.assign({ success: false }, result);
}
async refreshAccessToken(url, init) { async refreshAccessToken(url, init) {
const result = this.externalRefreshFn const result = this.externalRefreshFn
? await this.externalRefreshFn(this.appId) ? await this.externalRefreshFn(this.appId)
: await this.access(`https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=${this.appId}&secret=${this.appSecret}`, { access_token: 'mockToken', expires_in: 600 }); : await this.access(`https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=${this.appId}&secret=${this.appSecret}`);
const { access_token, expires_in } = result; const { access_token, expires_in } = result;
this.accessToken = access_token; this.accessToken = access_token;
// 生成下次刷新的定时器 // 生成下次刷新的定时器
@ -122,7 +189,9 @@ export class WechatPublicInstance {
this.refreshAccessToken(); this.refreshAccessToken();
}, (expires_in - 10) * 1000); }, (expires_in - 10) * 1000);
if (url) { if (url) {
return this.access(url, {}, init); const url2 = new URL.URL(url);
url2.searchParams.set('access_token', access_token);
return this.access(url2.toString(), {}, init);
} }
} }
decryptData(sessionKey, encryptedData, iv, signature) { decryptData(sessionKey, encryptedData, iv, signature) {
@ -182,11 +251,13 @@ export class WechatPublicInstance {
}; };
} }
const token = await this.getAccessToken(); const token = await this.getAccessToken();
const result = await this.access(`https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=${token}`, { const result = await this.access(`https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=${token}`,
ticket: `ticket${Date.now()}`, // {
url: `http://mock/q/${sceneId ? sceneId : sceneStr}`, // ticket: `ticket${Date.now()}`,
expireSeconds: expireSeconds, // url: `http://mock/q/${sceneId ? sceneId : sceneStr}`,
}, myInit); // expireSeconds: expireSeconds,
// },
myInit);
return { return {
ticket: result.ticket, ticket: result.ticket,
url: result.url, url: result.url,
@ -210,11 +281,13 @@ export class WechatPublicInstance {
}), }),
}; };
const token = await this.getAccessToken(); const token = await this.getAccessToken();
const result = await this.access(`https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=${token}`, { const result = await this.access(`https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=${token}`,
errcode: 0, // {
errmsg: 'ok', // errcode: 0,
msgid: Date.now(), // errmsg: 'ok',
}, myInit); // msgid: Date.now(),
// },
myInit);
const { errcode } = result; const { errcode } = result;
if (errcode === 0) { if (errcode === 0) {
return Object.assign({ success: true }, result); return Object.assign({ success: true }, result);
@ -281,10 +354,12 @@ export class WechatPublicInstance {
} }
} }
const token = await this.getAccessToken(); const token = await this.getAccessToken();
const result = await this.access(`https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=${token}`, { const result = await this.access(`https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=${token}`,
errcode: 0, // {
errmsg: 'ok', // errcode: 0,
}, myInit); // errmsg: 'ok',
// },
myInit);
const { errcode } = result; const { errcode } = result;
if (errcode === 0) { if (errcode === 0) {
return Object.assign({ success: true }, result); return Object.assign({ success: true }, result);
@ -305,39 +380,108 @@ export class WechatPublicInstance {
}), }),
}; };
const token = await this.getAccessToken(); const token = await this.getAccessToken();
const result = await this.access(`https://api.weixin.qq.com/cgi-bin/freepublish/batchget?access_token=${token}`, { const result = await this.access(`https://api.weixin.qq.com/cgi-bin/freepublish/batchget?access_token=${token}`, undefined, myInit);
total_count: 1,
item_count: 1,
item: [
{
article_id: 'test',
content: {
news_item: [
{
title: '测试文章',
author: '测试作者',
digest: '测试摘要',
content: '测试内容',
content_source_url: '',
thumb_media_id: 'TEST_MEDIA_ID',
show_cover_pic: 1,
need_open_comment: 0,
only_fans_can_comment: 0,
url: 'TEST_ARTICLE_URL',
is_deleted: false,
},
],
},
update_time: Date.now(),
},
],
}, myInit);
const { errcode } = result; const { errcode } = result;
if (!errcode) { if (!errcode) {
return result; return result;
} }
throw new Error(JSON.stringify(result)); throw new Error(JSON.stringify(result));
} }
async getArticle(options) {
const { article_id } = options;
const myInit = {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
article_id,
}),
};
const token = await this.getAccessToken();
const result = await this.access(`https://api.weixin.qq.com/cgi-bin/freepublish/getarticle?access_token=${token}`, undefined, myInit);
const { errcode } = result;
if (!errcode) {
return result;
}
throw new Error(JSON.stringify(result));
}
async createMaterial(options) {
const { type, media, description } = options;
const myInit = {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
};
if (type === 'video') {
Object.assign(myInit, {
body: JSON.stringify({
type,
media,
description,
}),
});
}
else {
Object.assign(myInit, {
body: JSON.stringify({
type,
media,
}),
});
}
;
const token = await this.getAccessToken();
const result = await this.access(`https://api.weixin.qq.com/cgi-bin/material/add_material?access_token=${token}`, undefined, myInit);
const { errcode } = result;
if (!errcode) {
return result;
}
throw new Error(JSON.stringify(result));
}
async batchGetMaterialList(options) {
const { offset, count, type } = options;
const myInit = {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
type,
offset,
count,
}),
};
const token = await this.getAccessToken();
const result = await this.access(`https://api.weixin.qq.com/cgi-bin/material/batchget_material?access_token=${token}`, undefined, myInit);
const { errcode } = result;
if (!errcode) {
return result;
}
throw new Error(JSON.stringify(result));
}
async getMaterial(options) {
const { type, media_id } = options;
const myInit = {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
media_id
}),
};
let imgFile;
const token = await this.getAccessToken();
const result = await this.access(`https://api.weixin.qq.com/cgi-bin/material/get_material?access_token=${token}`, undefined, myInit);
if ('errcode' in result) {
throw new Error(JSON.stringify(result));
}
else {
return result;
}
}
async getTicket() { async getTicket() {
const myInit = { const myInit = {
method: 'GET', method: 'GET',
@ -346,10 +490,12 @@ export class WechatPublicInstance {
}, },
}; };
const token = await this.getAccessToken(); const token = await this.getAccessToken();
const result = (await this.access(`https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=${token}&type=jsapi`, { const result = (await this.access(`https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=${token}&type=jsapi`,
ticket: `ticket${Date.now()}`, // {
expires_in: 30, // ticket: `ticket${Date.now()}`,
}, myInit)); // expires_in: 30,
// },
myInit));
const { ticket } = result; const { ticket } = result;
return ticket; return ticket;
} }

View File

@ -1,22 +1,21 @@
"use strict"; "use strict";
Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "__esModule", { value: true });
var Amap_1 = require("./service/amap/Amap"); const Amap_1 = require("./service/amap/Amap");
var AmapSDK = /** @class */ (function () { class AmapSDK {
function AmapSDK() { webKeyMap;
constructor() {
this.webKeyMap = {}; this.webKeyMap = {};
} }
AmapSDK.prototype.getInstance = function (key) { getInstance(key) {
var _a;
if (this.webKeyMap[key]) { if (this.webKeyMap[key]) {
return this.webKeyMap[key]; return this.webKeyMap[key];
} }
var instance = new Amap_1.AmapInstance(key); const instance = new Amap_1.AmapInstance(key);
Object.assign(this.webKeyMap, (_a = {}, Object.assign(this.webKeyMap, {
_a[key] = instance, [key]: instance,
_a)); });
return instance; return instance;
}; }
return AmapSDK; }
}()); const SDK = new AmapSDK();
var SDK = new AmapSDK();
exports.default = SDK; exports.default = SDK;

View File

@ -1,24 +1,23 @@
"use strict"; "use strict";
Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "__esModule", { value: true });
exports.QiniuCloudInstance = void 0; exports.QiniuCloudInstance = void 0;
var QiniuCloud_1 = require("./service/qiniu/QiniuCloud"); const QiniuCloud_1 = require("./service/qiniu/QiniuCloud");
Object.defineProperty(exports, "QiniuCloudInstance", { enumerable: true, get: function () { return QiniuCloud_1.QiniuCloudInstance; } }); Object.defineProperty(exports, "QiniuCloudInstance", { enumerable: true, get: function () { return QiniuCloud_1.QiniuCloudInstance; } });
var QiniuSDK = /** @class */ (function () { class QiniuSDK {
function QiniuSDK() { qiniuMap;
constructor() {
this.qiniuMap = {}; this.qiniuMap = {};
} }
QiniuSDK.prototype.getInstance = function (accessKey, accessSecret) { getInstance(accessKey, accessSecret) {
var _a;
if (this.qiniuMap[accessKey]) { if (this.qiniuMap[accessKey]) {
return this.qiniuMap[accessKey]; return this.qiniuMap[accessKey];
} }
var instance = new QiniuCloud_1.QiniuCloudInstance(accessKey, accessSecret); const instance = new QiniuCloud_1.QiniuCloudInstance(accessKey, accessSecret);
Object.assign(this.qiniuMap, (_a = {}, Object.assign(this.qiniuMap, {
_a[accessKey] = instance, [accessKey]: instance,
_a)); });
return instance; return instance;
}; }
return QiniuSDK; }
}()); const SDK = new QiniuSDK();
var SDK = new QiniuSDK();
exports.default = SDK; exports.default = SDK;

View File

@ -1,26 +1,27 @@
"use strict"; "use strict";
Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "__esModule", { value: true });
exports.AliSmsInstance = exports.TencentSmsInstance = void 0; exports.AliSmsInstance = exports.TencentSmsInstance = void 0;
var Sms_1 = require("./service/tencent/Sms"); const Sms_1 = require("./service/tencent/Sms");
Object.defineProperty(exports, "TencentSmsInstance", { enumerable: true, get: function () { return Sms_1.TencentSmsInstance; } }); Object.defineProperty(exports, "TencentSmsInstance", { enumerable: true, get: function () { return Sms_1.TencentSmsInstance; } });
var Sms_2 = require("./service/ali/Sms"); const Sms_2 = require("./service/ali/Sms");
Object.defineProperty(exports, "AliSmsInstance", { enumerable: true, get: function () { return Sms_2.AliSmsInstance; } }); Object.defineProperty(exports, "AliSmsInstance", { enumerable: true, get: function () { return Sms_2.AliSmsInstance; } });
var SmsSDK = /** @class */ (function () { class SmsSDK {
function SmsSDK() { tencentMap;
aliMap;
constructor() {
this.tencentMap = {}; this.tencentMap = {};
this.aliMap = {}; this.aliMap = {};
} }
SmsSDK.prototype.getInstance = function (origin, accessKey, accessSecret, region, endpoint, apiVersion //阿里云独有 getInstance(origin, accessKey, accessSecret, region, endpoint, apiVersion //阿里云独有
) { ) {
var _a, _b;
if (origin === 'tencent') { if (origin === 'tencent') {
if (this.tencentMap[accessKey]) { if (this.tencentMap[accessKey]) {
return this.tencentMap[accessKey]; return this.tencentMap[accessKey];
} }
var instance = new Sms_1.TencentSmsInstance(accessKey, accessSecret, region, endpoint); const instance = new Sms_1.TencentSmsInstance(accessKey, accessSecret, region, endpoint);
Object.assign(this.tencentMap, (_a = {}, Object.assign(this.tencentMap, {
_a[accessKey] = instance, [accessKey]: instance,
_a)); });
return instance; return instance;
} }
else if (origin === 'ali') { else if (origin === 'ali') {
@ -30,17 +31,16 @@ var SmsSDK = /** @class */ (function () {
if (this.aliMap[accessKey]) { if (this.aliMap[accessKey]) {
return this.aliMap[accessKey]; return this.aliMap[accessKey];
} }
var instance = new Sms_2.AliSmsInstance(accessKey, accessSecret, region, endpoint, apiVersion); const instance = new Sms_2.AliSmsInstance(accessKey, accessSecret, region, endpoint, apiVersion);
Object.assign(this.aliMap, (_b = {}, Object.assign(this.aliMap, {
_b[accessKey] = instance, [accessKey]: instance,
_b)); });
return instance; return instance;
} }
else { else {
throw new Error("".concat(origin, " not implemented")); throw new Error(`${origin} not implemented`);
} }
}; }
return SmsSDK; }
}()); const SDK = new SmsSDK();
var SDK = new SmsSDK();
exports.default = SDK; exports.default = SDK;

View File

@ -1,103 +1,98 @@
"use strict"; "use strict";
Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "__esModule", { value: true });
exports.WechatPublicInstance = exports.WechatWebInstance = exports.WechatMpInstance = void 0; exports.WechatPublicInstance = exports.WechatWebInstance = exports.WechatMpInstance = void 0;
var tslib_1 = require("tslib"); const WechatMp_1 = require("./service/wechat/WechatMp");
var WechatMp_1 = require("./service/wechat/WechatMp");
Object.defineProperty(exports, "WechatMpInstance", { enumerable: true, get: function () { return WechatMp_1.WechatMpInstance; } }); Object.defineProperty(exports, "WechatMpInstance", { enumerable: true, get: function () { return WechatMp_1.WechatMpInstance; } });
var WechatPublic_1 = require("./service/wechat/WechatPublic"); const WechatPublic_1 = require("./service/wechat/WechatPublic");
Object.defineProperty(exports, "WechatPublicInstance", { enumerable: true, get: function () { return WechatPublic_1.WechatPublicInstance; } }); Object.defineProperty(exports, "WechatPublicInstance", { enumerable: true, get: function () { return WechatPublic_1.WechatPublicInstance; } });
var WechatWeb_1 = require("./service/wechat/WechatWeb"); const WechatWeb_1 = require("./service/wechat/WechatWeb");
Object.defineProperty(exports, "WechatWebInstance", { enumerable: true, get: function () { return WechatWeb_1.WechatWebInstance; } }); Object.defineProperty(exports, "WechatWebInstance", { enumerable: true, get: function () { return WechatWeb_1.WechatWebInstance; } });
var cheerio_1 = require("./utils/cheerio"); const cheerio_1 = require("./utils/cheerio");
var WechatSDK = /** @class */ (function () { class WechatSDK {
function WechatSDK() { mpMap;
publicMap;
webMap;
constructor() {
this.mpMap = {}; this.mpMap = {};
this.publicMap = {}; this.publicMap = {};
this.webMap = {}; this.webMap = {};
} }
WechatSDK.prototype.getInstance = function (appId, type, appSecret, accessToken, externalRefreshFn) { getInstance(appId, type, appSecret, accessToken, externalRefreshFn) {
var _a, _b, _c;
// type 支持web网站扫码登录 // type 支持web网站扫码登录
if (type === 'wechatMp') { if (type === 'wechatMp') {
if (this.mpMap[appId]) { if (this.mpMap[appId]) {
return this.mpMap[appId]; return this.mpMap[appId];
} }
var instance = new WechatMp_1.WechatMpInstance(appId, appSecret, accessToken, externalRefreshFn); const instance = new WechatMp_1.WechatMpInstance(appId, appSecret, accessToken, externalRefreshFn);
Object.assign(this.mpMap, (_a = {}, Object.assign(this.mpMap, {
_a[appId] = instance, [appId]: instance,
_a)); });
return instance; return instance;
} }
else if (type === 'wechatPublic') { else if (type === 'wechatPublic') {
if (this.publicMap[appId]) { if (this.publicMap[appId]) {
return this.publicMap[appId]; return this.publicMap[appId];
} }
var instance = new WechatPublic_1.WechatPublicInstance(appId, appSecret, accessToken, externalRefreshFn); const instance = new WechatPublic_1.WechatPublicInstance(appId, appSecret, accessToken, externalRefreshFn);
Object.assign(this.publicMap, (_b = {}, Object.assign(this.publicMap, {
_b[appId] = instance, [appId]: instance,
_b)); });
return instance; return instance;
} }
else if (type === 'web') { else if (type === 'web') {
if (this.webMap[appId]) { if (this.webMap[appId]) {
return this.webMap[appId]; return this.webMap[appId];
} }
var instance = new WechatWeb_1.WechatWebInstance(appId, appSecret, accessToken, externalRefreshFn); const instance = new WechatWeb_1.WechatWebInstance(appId, appSecret, accessToken, externalRefreshFn);
Object.assign(this.webMap, (_c = {}, Object.assign(this.webMap, {
_c[appId] = instance, [appId]: instance,
_c)); });
return instance; return instance;
} }
else { else {
throw new Error("".concat(type, " not implemented")); throw new Error(`${type} not implemented`);
}
} }
};
/** /**
* 解析微信公众号文章内容 * 解析微信公众号文章内容
* @param url 微信公众号链接 * @param url 微信公众号链接
* @returns html * @returns html
*/ */
WechatSDK.prototype.analyzePublicArticle = function (url) { async analyzePublicArticle(url) {
var _a; const response = await fetch(url);
return tslib_1.__awaiter(this, void 0, void 0, function () { const html = await response.text();
var response, html, $, title, ems, imgsElement, imageList, i, src, publishDate, lines, i, timeStr; const $ = (0, cheerio_1.load)(html);
return tslib_1.__generator(this, function (_b) { const title = $('#activity-name') ? $('#activity-name').text()?.trim().replace(/\n/g, '') : '';
switch (_b.label) { const ems = $('em');
case 0: return [4 /*yield*/, fetch(url)]; const imgsElement = $('img');
case 1: const imageList = [];
response = _b.sent(); for (let i = 0; i < imgsElement.length; i++) {
return [4 /*yield*/, response.text()]; // 把 img 元素中的 src 内容提取出来,加入到数组中
case 2: const src = imgsElement[i].attribs['data-src'];
html = _b.sent();
$ = (0, cheerio_1.load)(html);
title = $('#activity-name') ? (_a = $('#activity-name').text()) === null || _a === void 0 ? void 0 : _a.trim().replace(/\n/g, '') : '';
ems = $('em');
imgsElement = $('img');
imageList = [];
for (i = 0; i < imgsElement.length; i++) {
src = imgsElement[i].attribs['data-src'];
if (src && (src.includes('http') || src.includes('https'))) { if (src && (src.includes('http') || src.includes('https'))) {
imageList.push(src); imageList.push(src);
} }
} }
lines = html.split('\n'); let publishDate;
for (i = 0; i < lines.length; i++) { // $('em').toArray().forEach((element, index) => {
// if (index === 0) {
// publishDate = $(element).text();
// }
// });
const lines = html.split('\n');
for (let i = 0; i < lines.length; i++) {
if (lines[i].includes('var ct =')) { if (lines[i].includes('var ct =')) {
timeStr = lines[i].split('"')[1] + '000'; const timeStr = lines[i].split('"')[1] + '000';
publishDate = Number(timeStr); publishDate = Number(timeStr);
break; break;
} }
} }
return [2 /*return*/, { return {
title: title, title,
publishDate: publishDate, publishDate,
imageList: imageList, imageList,
}];
}
});
});
}; };
return WechatSDK; }
}()); }
var SDK = new WechatSDK(); const SDK = new WechatSDK();
exports.default = SDK; exports.default = SDK;

View File

@ -1,18 +1,18 @@
"use strict"; "use strict";
Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "__esModule", { value: true });
exports.AliSmsInstance = exports.TencentSmsInstance = exports.SmsSdk = exports.QiniuCloudInstance = exports.WechatWebInstance = exports.WechatPublicInstance = exports.WechatMpInstance = exports.WechatSDK = exports.QiniuSDK = exports.AmapSDK = void 0; exports.AliSmsInstance = exports.TencentSmsInstance = exports.SmsSdk = exports.QiniuCloudInstance = exports.WechatWebInstance = exports.WechatPublicInstance = exports.WechatMpInstance = exports.WechatSDK = exports.QiniuSDK = exports.AmapSDK = void 0;
var tslib_1 = require("tslib"); const tslib_1 = require("tslib");
var WechatSDK_1 = tslib_1.__importStar(require("./WechatSDK")); const WechatSDK_1 = tslib_1.__importStar(require("./WechatSDK"));
exports.WechatSDK = WechatSDK_1.default; exports.WechatSDK = WechatSDK_1.default;
Object.defineProperty(exports, "WechatMpInstance", { enumerable: true, get: function () { return WechatSDK_1.WechatMpInstance; } }); Object.defineProperty(exports, "WechatMpInstance", { enumerable: true, get: function () { return WechatSDK_1.WechatMpInstance; } });
Object.defineProperty(exports, "WechatPublicInstance", { enumerable: true, get: function () { return WechatSDK_1.WechatPublicInstance; } }); Object.defineProperty(exports, "WechatPublicInstance", { enumerable: true, get: function () { return WechatSDK_1.WechatPublicInstance; } });
Object.defineProperty(exports, "WechatWebInstance", { enumerable: true, get: function () { return WechatSDK_1.WechatWebInstance; } }); Object.defineProperty(exports, "WechatWebInstance", { enumerable: true, get: function () { return WechatSDK_1.WechatWebInstance; } });
var AmapSDK_1 = tslib_1.__importDefault(require("./AmapSDK")); const AmapSDK_1 = tslib_1.__importDefault(require("./AmapSDK"));
exports.AmapSDK = AmapSDK_1.default; exports.AmapSDK = AmapSDK_1.default;
var QiniuSDK_1 = tslib_1.__importStar(require("./QiniuSDK")); const QiniuSDK_1 = tslib_1.__importStar(require("./QiniuSDK"));
exports.QiniuSDK = QiniuSDK_1.default; exports.QiniuSDK = QiniuSDK_1.default;
Object.defineProperty(exports, "QiniuCloudInstance", { enumerable: true, get: function () { return QiniuSDK_1.QiniuCloudInstance; } }); Object.defineProperty(exports, "QiniuCloudInstance", { enumerable: true, get: function () { return QiniuSDK_1.QiniuCloudInstance; } });
var SmsSdk_1 = tslib_1.__importStar(require("./SmsSdk")); const SmsSdk_1 = tslib_1.__importStar(require("./SmsSdk"));
exports.SmsSdk = SmsSdk_1.default; exports.SmsSdk = SmsSdk_1.default;
Object.defineProperty(exports, "TencentSmsInstance", { enumerable: true, get: function () { return SmsSdk_1.TencentSmsInstance; } }); Object.defineProperty(exports, "TencentSmsInstance", { enumerable: true, get: function () { return SmsSdk_1.TencentSmsInstance; } });
Object.defineProperty(exports, "AliSmsInstance", { enumerable: true, get: function () { return SmsSdk_1.AliSmsInstance; } }); Object.defineProperty(exports, "AliSmsInstance", { enumerable: true, get: function () { return SmsSdk_1.AliSmsInstance; } });

View File

@ -1,10 +1,16 @@
"use strict"; "use strict";
Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "__esModule", { value: true });
exports.AliSmsInstance = void 0; exports.AliSmsInstance = void 0;
var tslib_1 = require("tslib"); const tslib_1 = require("tslib");
var rpc_1 = tslib_1.__importDefault(require("@alicloud/pop-core/lib/rpc")); const rpc_1 = tslib_1.__importDefault(require("@alicloud/pop-core/lib/rpc"));
var AliSmsInstance = /** @class */ (function () { class AliSmsInstance {
function AliSmsInstance(accessKeyId, accessKeySecret, regionId, endpoint, apiVersion) { accessKeyId;
accessKeySecret;
regionId;
endpoint;
apiVersion;
client;
constructor(accessKeyId, accessKeySecret, regionId, endpoint, apiVersion) {
this.accessKeyId = accessKeyId; this.accessKeyId = accessKeyId;
this.accessKeySecret = accessKeySecret; this.accessKeySecret = accessKeySecret;
this.regionId = regionId; this.regionId = regionId;
@ -17,12 +23,9 @@ var AliSmsInstance = /** @class */ (function () {
apiVersion: this.apiVersion, apiVersion: this.apiVersion,
}); });
} }
AliSmsInstance.prototype.sendSms = function (params) { async sendSms(params) {
return tslib_1.__awaiter(this, void 0, void 0, function () { const { PhoneNumbers, TemplateParam = {}, TemplateCode, SignName, } = params;
var PhoneNumbers, _a, TemplateParam, TemplateCode, SignName, param; const param = Object.assign({
return tslib_1.__generator(this, function (_b) {
PhoneNumbers = params.PhoneNumbers, _a = params.TemplateParam, TemplateParam = _a === void 0 ? {} : _a, TemplateCode = params.TemplateCode, SignName = params.SignName;
param = Object.assign({
regionId: this.regionId, regionId: this.regionId,
}, { }, {
PhoneNumbers: PhoneNumbers.join(','), PhoneNumbers: PhoneNumbers.join(','),
@ -44,10 +47,6 @@ var AliSmsInstance = /** @class */ (function () {
console.error(err); console.error(err);
throw err; throw err;
} }
return [2 /*return*/]; }
}); }
});
};
return AliSmsInstance;
}());
exports.AliSmsInstance = AliSmsInstance; exports.AliSmsInstance = AliSmsInstance;

View File

@ -1,14 +1,18 @@
"use strict"; "use strict";
Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "__esModule", { value: true });
exports.AliSmsInstance = void 0; exports.AliSmsInstance = void 0;
var tslib_1 = require("tslib"); class AliSmsInstance {
var AliSmsInstance = /** @class */ (function () { secretId;
function AliSmsInstance(secretId, secretKey, region, endpoint) { secretKey;
region;
endpoint;
client;
constructor(secretId, secretKey, region, endpoint) {
this.secretId = secretId; this.secretId = secretId;
this.secretKey = secretKey; this.secretKey = secretKey;
this.region = region; this.region = region;
this.endpoint = endpoint; this.endpoint = endpoint;
var clientConfig = { const clientConfig = {
credential: { credential: {
secretId: this.secretId, secretId: this.secretId,
secretKey: this.secretKey, secretKey: this.secretKey,
@ -21,14 +25,9 @@ var AliSmsInstance = /** @class */ (function () {
}, },
}; };
} }
AliSmsInstance.prototype.sendSms = function (params) { async sendSms(params) {
return tslib_1.__awaiter(this, void 0, void 0, function () {
return tslib_1.__generator(this, function (_a) {
console.log('mp走不到这里'); console.log('mp走不到这里');
return [2 /*return*/, {}]; return {};
}); }
}); }
};
return AliSmsInstance;
}());
exports.AliSmsInstance = AliSmsInstance; exports.AliSmsInstance = AliSmsInstance;

View File

@ -1,14 +1,18 @@
"use strict"; "use strict";
Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "__esModule", { value: true });
exports.AliSmsInstance = void 0; exports.AliSmsInstance = void 0;
var tslib_1 = require("tslib"); class AliSmsInstance {
var AliSmsInstance = /** @class */ (function () { secretId;
function AliSmsInstance(secretId, secretKey, region, endpoint) { secretKey;
region;
endpoint;
client;
constructor(secretId, secretKey, region, endpoint) {
this.secretId = secretId; this.secretId = secretId;
this.secretKey = secretKey; this.secretKey = secretKey;
this.region = region; this.region = region;
this.endpoint = endpoint; this.endpoint = endpoint;
var clientConfig = { const clientConfig = {
credential: { credential: {
secretId: this.secretId, secretId: this.secretId,
secretKey: this.secretKey, secretKey: this.secretKey,
@ -21,14 +25,9 @@ var AliSmsInstance = /** @class */ (function () {
}, },
}; };
} }
AliSmsInstance.prototype.sendSms = function (params) { async sendSms(params) {
return tslib_1.__awaiter(this, void 0, void 0, function () {
return tslib_1.__generator(this, function (_a) {
console.log('web走不到这里'); console.log('web走不到这里');
return [2 /*return*/, {}]; return {};
}); }
}); }
};
return AliSmsInstance;
}());
exports.AliSmsInstance = AliSmsInstance; exports.AliSmsInstance = AliSmsInstance;

View File

@ -1,121 +1,60 @@
"use strict"; "use strict";
Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "__esModule", { value: true });
exports.AmapInstance = void 0; exports.AmapInstance = void 0;
var tslib_1 = require("tslib");
require('../../fetch'); require('../../fetch');
var AmapInstance = /** @class */ (function () { class AmapInstance {
function AmapInstance(key) { key;
constructor(key) {
this.key = key; this.key = key;
} }
AmapInstance.prototype.getDrivingPath = function (data) { async getDrivingPath(data) {
return tslib_1.__awaiter(this, void 0, void 0, function () { const { from, to } = data;
var from, to, url, result, jsonData; const url = `http://restapi.amap.com/v3/direction/driving?origin=${from[0].toFixed(6)},${from[1].toFixed(6)}&destination=${to[0].toFixed(6)},${to[1].toFixed(6)}&strategy=10&key=${this.key}`;
return tslib_1.__generator(this, function (_a) { const result = await global.fetch(url);
switch (_a.label) { const jsonData = await result.json();
case 0:
from = data.from, to = data.to;
url = "http://restapi.amap.com/v3/direction/driving?origin=".concat(from[0].toFixed(6), ",").concat(from[1].toFixed(6), "&destination=").concat(to[0].toFixed(6), ",").concat(to[1].toFixed(6), "&strategy=10&key=").concat(this.key);
return [4 /*yield*/, global.fetch(url)];
case 1:
result = _a.sent();
return [4 /*yield*/, result.json()];
case 2:
jsonData = _a.sent();
if (jsonData.status !== '1') { if (jsonData.status !== '1') {
throw new Error(JSON.stringify(jsonData)); throw new Error(JSON.stringify(jsonData));
} }
return [2 /*return*/, Promise.resolve(jsonData)]; return Promise.resolve(jsonData);
} }
}); async regeo(data) {
}); const { longitude, latitude } = data;
}; const result = await global.fetch(`https://restapi.amap.com/v3/geocode/regeo?location=${longitude},${latitude}&key=${this.key}`);
AmapInstance.prototype.regeo = function (data) { const jsonData = await result.json();
return tslib_1.__awaiter(this, void 0, void 0, function () {
var longitude, latitude, result, jsonData;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
longitude = data.longitude, latitude = data.latitude;
return [4 /*yield*/, global.fetch("https://restapi.amap.com/v3/geocode/regeo?location=".concat(longitude, ",").concat(latitude, "&key=").concat(this.key))];
case 1:
result = _a.sent();
return [4 /*yield*/, result.json()];
case 2:
jsonData = _a.sent();
if (jsonData.status !== '1') { if (jsonData.status !== '1') {
throw new Error(JSON.stringify(jsonData)); throw new Error(JSON.stringify(jsonData));
} }
return [2 /*return*/, Promise.resolve(jsonData)]; return Promise.resolve(jsonData);
} }
}); async ipLoc(data) {
}); const { ip } = data;
}; const url = `https://restapi.amap.com/v3/ip?key=${this.key}&ip=${ip}`;
AmapInstance.prototype.ipLoc = function (data) { const result = await global.fetch(url);
return tslib_1.__awaiter(this, void 0, void 0, function () { const jsonData = await result.json();
var ip, url, result, jsonData;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
ip = data.ip;
url = "https://restapi.amap.com/v3/ip?key=".concat(this.key, "&ip=").concat(ip);
return [4 /*yield*/, global.fetch(url)];
case 1:
result = _a.sent();
return [4 /*yield*/, result.json()];
case 2:
jsonData = _a.sent();
if (jsonData.status !== '1') { if (jsonData.status !== '1') {
throw new Error(JSON.stringify(jsonData)); throw new Error(JSON.stringify(jsonData));
} }
return [2 /*return*/, Promise.resolve(jsonData)]; return Promise.resolve(jsonData);
} }
}); async getDistrict(data) {
}); const { keywords, subdistrict } = data;
}; const url = `https://restapi.amap.com/v3/config/district?keywords=${keywords}&subdistrict=${subdistrict}&key=${this.key}`;
AmapInstance.prototype.getDistrict = function (data) { const result = await global.fetch(url);
return tslib_1.__awaiter(this, void 0, void 0, function () { const jsonData = await result.json();
var keywords, subdistrict, url, result, jsonData;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
keywords = data.keywords, subdistrict = data.subdistrict;
url = "https://restapi.amap.com/v3/config/district?keywords=".concat(keywords, "&subdistrict=").concat(subdistrict, "&key=").concat(this.key);
return [4 /*yield*/, global.fetch(url)];
case 1:
result = _a.sent();
return [4 /*yield*/, result.json()];
case 2:
jsonData = _a.sent();
if (jsonData.status !== '1') { if (jsonData.status !== '1') {
throw new Error(JSON.stringify(jsonData)); throw new Error(JSON.stringify(jsonData));
} }
return [2 /*return*/, Promise.resolve(jsonData)]; return Promise.resolve(jsonData);
} }
}); async geocode(data) {
}); const { address } = data;
}; const url = `https://restapi.amap.com/v3/geocode/geo?address=${address}&key=${this.key}`;
AmapInstance.prototype.geocode = function (data) { const result = await global.fetch(url);
return tslib_1.__awaiter(this, void 0, void 0, function () { const jsonData = await result.json();
var address, url, result, jsonData;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
address = data.address;
url = "https://restapi.amap.com/v3/geocode/geo?address=".concat(address, "&key=").concat(this.key);
return [4 /*yield*/, global.fetch(url)];
case 1:
result = _a.sent();
return [4 /*yield*/, result.json()];
case 2:
jsonData = _a.sent();
if (jsonData.status !== '1') { if (jsonData.status !== '1') {
throw new Error(JSON.stringify(jsonData)); throw new Error(JSON.stringify(jsonData));
} }
return [2 /*return*/, Promise.resolve(jsonData)]; return Promise.resolve(jsonData);
}
} }
});
});
};
return AmapInstance;
}());
exports.AmapInstance = AmapInstance; exports.AmapInstance = AmapInstance;

View File

@ -1,13 +1,15 @@
"use strict"; "use strict";
Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "__esModule", { value: true });
exports.QiniuCloudInstance = void 0; exports.QiniuCloudInstance = void 0;
var tslib_1 = require("tslib"); const tslib_1 = require("tslib");
require('../../fetch'); require('../../fetch');
var crypto_1 = tslib_1.__importDefault(require("crypto")); const crypto_1 = tslib_1.__importDefault(require("crypto"));
var ts_md5_1 = require("ts-md5"); const ts_md5_1 = require("ts-md5");
var buffer_1 = require("buffer"); const buffer_1 = require("buffer");
var QiniuCloudInstance = /** @class */ (function () { class QiniuCloudInstance {
function QiniuCloudInstance(accessKey, secretKey) { accessKey;
secretKey;
constructor(accessKey, secretKey) {
this.accessKey = accessKey; this.accessKey = accessKey;
this.secretKey = secretKey; this.secretKey = secretKey;
} }
@ -19,21 +21,21 @@ var QiniuCloudInstance = /** @class */ (function () {
* @param key * @param key
* @returns * @returns
*/ */
QiniuCloudInstance.prototype.getUploadInfo = function (uploadHost, bucket, key) { getUploadInfo(uploadHost, bucket, key) {
try { try {
var scope = key ? "".concat(bucket, ":").concat(key) : bucket; const scope = key ? `${bucket}:${key}` : bucket;
var uploadToken = this.getToken(scope); const uploadToken = this.getToken(scope);
return { return {
key: key, key,
uploadToken: uploadToken, uploadToken,
uploadHost: uploadHost, uploadHost,
bucket: bucket, bucket,
}; };
} }
catch (err) { catch (err) {
throw err; throw err;
} }
}; }
/** /**
* 计算直播需要的token * 计算直播需要的token
* @param method * @param method
@ -44,15 +46,15 @@ var QiniuCloudInstance = /** @class */ (function () {
* @param bodyStr * @param bodyStr
* @returns * @returns
*/ */
QiniuCloudInstance.prototype.getLiveToken = function (method, path, host, rawQuery, contentType, bodyStr) { getLiveToken(method, path, host, rawQuery, contentType, bodyStr) {
// 1. 添加 Path // 1. 添加 Path
var data = "".concat(method, " ").concat(path); let data = `${method} ${path}`;
if (rawQuery) { if (rawQuery) {
data += "?".concat(rawQuery); data += `?${rawQuery}`;
} }
data += "\nHost: ".concat(host); data += `\nHost: ${host}`;
if (contentType) { if (contentType) {
data += "\nContent-Type: ".concat(contentType); data += `\nContent-Type: ${contentType}`;
} }
data += '\n\n'; data += '\n\n';
if (bodyStr && if (bodyStr &&
@ -60,29 +62,26 @@ var QiniuCloudInstance = /** @class */ (function () {
contentType !== 'application/octet-stream') { contentType !== 'application/octet-stream') {
data += bodyStr; data += bodyStr;
} }
var sign = this.hmacSha1(data, this.secretKey); const sign = this.hmacSha1(data, this.secretKey);
var encodedSign = this.base64ToUrlSafe(sign); const encodedSign = this.base64ToUrlSafe(sign);
var toke = 'Qiniu ' + this.accessKey + ':' + encodedSign; const toke = 'Qiniu ' + this.accessKey + ':' + encodedSign;
return toke; return toke;
};
QiniuCloudInstance.prototype.getLiveStream = function (hub, method, streamTitle, host, publishDomain, playDomain, publishKey, playKey, expireAt) {
return tslib_1.__awaiter(this, void 0, void 0, function () {
var path, key, bodyStr, contentType, token, url, obj;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
path = "/v2/hubs/".concat(hub, "/streams");
key = streamTitle;
if (!key) {
key = "class".concat(new Date().getTime());
} }
bodyStr = JSON.stringify({ async getLiveStream(hub, method, streamTitle, host, publishDomain, playDomain, publishKey, playKey, expireAt) {
key: key, // 七牛创建直播流接口路径
const path = `/v2/hubs/${hub}/streams`;
// 如果用户没给streamTitle那么随机生成一个
let key = streamTitle;
if (!key) {
key = `class${new Date().getTime()}`;
}
const bodyStr = JSON.stringify({
key,
}); });
contentType = 'application/json'; const contentType = 'application/json';
token = this.getLiveToken(method, path, host); const token = this.getLiveToken(method, path, host);
url = "https://pili.qiniuapi.com/v2/hubs/".concat(hub, "/streams"); const url = `https://pili.qiniuapi.com/v2/hubs/${hub}/streams`;
return [4 /*yield*/, global.fetch(url, { await global.fetch(url, {
method: 'POST', method: 'POST',
headers: { headers: {
Authorization: token, Authorization: token,
@ -90,15 +89,10 @@ var QiniuCloudInstance = /** @class */ (function () {
}, },
body: bodyStr, body: bodyStr,
mode: 'no-cors', mode: 'no-cors',
})]; });
case 1: const obj = this.getStreamObj(publishDomain, playDomain, hub, publishKey, playKey, streamTitle, expireAt);
_a.sent(); return obj;
obj = this.getStreamObj(publishDomain, playDomain, hub, publishKey, playKey, streamTitle, expireAt);
return [2 /*return*/, obj];
} }
});
});
};
/** /**
* 计算直播流地址相关信息 * 计算直播流地址相关信息
* @param publishDomain * @param publishDomain
@ -110,47 +104,42 @@ var QiniuCloudInstance = /** @class */ (function () {
* @param expireAt * @param expireAt
* @returns * @returns
*/ */
QiniuCloudInstance.prototype.getStreamObj = function (publishDomain, playDomain, hub, publishKey, playKey, streamTitle, expireAt) { getStreamObj(publishDomain, playDomain, hub, publishKey, playKey, streamTitle, expireAt) {
var signStr = "/".concat(hub, "/").concat(streamTitle, "?expire=").concat(expireAt); const signStr = `/${hub}/${streamTitle}?expire=${expireAt}`;
var sourcePath = "/".concat(hub, "/").concat(streamTitle); const sourcePath = `/${hub}/${streamTitle}`;
var token = this.base64ToUrlSafe(this.hmacSha1(signStr, publishKey)); const token = this.base64ToUrlSafe(this.hmacSha1(signStr, publishKey));
var rtmpPushUrl = "rtmp://".concat(publishDomain).concat(signStr, "&token=").concat(token); const rtmpPushUrl = `rtmp://${publishDomain}${signStr}&token=${token}`;
// 生成播放地址 // 生成播放地址
var t = expireAt.toString(16).toLowerCase(); const t = expireAt.toString(16).toLowerCase();
var playSign = ts_md5_1.Md5.hashStr(playKey + sourcePath + t) const playSign = ts_md5_1.Md5.hashStr(playKey + sourcePath + t)
.toString() .toString()
.toLowerCase(); .toLowerCase();
var rtmpPlayUrl = "https://".concat(playDomain).concat(sourcePath, ".m3u8?sign=").concat(playSign, "&t=").concat(t); const rtmpPlayUrl = `https://${playDomain}${sourcePath}.m3u8?sign=${playSign}&t=${t}`;
// obs推流需要的地址和串流密钥 // obs推流需要的地址和串流密钥
var pcPushUrl = "rtmp://".concat(publishDomain, "/").concat(hub, "/"); const pcPushUrl = `rtmp://${publishDomain}/${hub}/`;
var streamKey = "".concat(streamTitle, "?expire=").concat(expireAt, "&token=").concat(token); const streamKey = `${streamTitle}?expire=${expireAt}&token=${token}`;
return { return {
streamTitle: streamTitle, streamTitle,
hub: hub, hub,
rtmpPushUrl: rtmpPushUrl, rtmpPushUrl,
rtmpPlayUrl: rtmpPlayUrl, rtmpPlayUrl,
pcPushUrl: pcPushUrl, pcPushUrl,
streamKey: streamKey, streamKey,
expireAt: expireAt, expireAt,
}; };
}; }
QiniuCloudInstance.prototype.getPlayBackUrl = function (hub, playBackDomain, streamTitle, start, end, method, host, rawQuery) { async getPlayBackUrl(hub, playBackDomain, streamTitle, start, end, method, host, rawQuery) {
return tslib_1.__awaiter(this, void 0, void 0, function () { const encodeStreamTitle = this.base64ToUrlSafe(streamTitle);
var encodeStreamTitle, path, bodyStr, contentType, token, url; const path = `/v2/hubs/${hub}/streams/${encodeStreamTitle}/saveas`;
return tslib_1.__generator(this, function (_a) { const bodyStr = JSON.stringify({
switch (_a.label) {
case 0:
encodeStreamTitle = this.base64ToUrlSafe(streamTitle);
path = "/v2/hubs/".concat(hub, "/streams/").concat(encodeStreamTitle, "/saveas");
bodyStr = JSON.stringify({
fname: streamTitle, fname: streamTitle,
start: start, start,
end: end, end,
}); });
contentType = 'application/json'; const contentType = 'application/json';
token = this.getLiveToken(method, path, host, rawQuery, contentType, bodyStr); const token = this.getLiveToken(method, path, host, rawQuery, contentType, bodyStr);
url = "https://pili.qiniuapi.com".concat(path); const url = `https://pili.qiniuapi.com${path}`;
return [4 /*yield*/, global.fetch(url, { await global.fetch(url, {
method: 'POST', method: 'POST',
headers: { headers: {
Authorization: token, Authorization: token,
@ -158,39 +147,33 @@ var QiniuCloudInstance = /** @class */ (function () {
}, },
body: bodyStr, body: bodyStr,
mode: 'no-cors', mode: 'no-cors',
})]; });
case 1: return `https://${playBackDomain}/${streamTitle}.m3u8`;
_a.sent();
return [2 /*return*/, "https://".concat(playBackDomain, "/").concat(streamTitle, ".m3u8")];
} }
}); getToken(scope) {
});
};
QiniuCloudInstance.prototype.getToken = function (scope) {
// 构造策略 // 构造策略
var putPolicy = { const putPolicy = {
scope: scope, scope: scope,
deadline: 3600 + Math.floor(Date.now() / 1000), deadline: 3600 + Math.floor(Date.now() / 1000),
}; };
// 构造凭证 // 构造凭证
var encodedFlags = this.urlSafeBase64Encode(JSON.stringify(putPolicy)); const encodedFlags = this.urlSafeBase64Encode(JSON.stringify(putPolicy));
var encoded = this.hmacSha1(encodedFlags, this.secretKey); const encoded = this.hmacSha1(encodedFlags, this.secretKey);
var encodedSign = this.base64ToUrlSafe(encoded); const encodedSign = this.base64ToUrlSafe(encoded);
var uploadToken = this.accessKey + ':' + encodedSign + ':' + encodedFlags; const uploadToken = this.accessKey + ':' + encodedSign + ':' + encodedFlags;
return uploadToken; return uploadToken;
}; }
QiniuCloudInstance.prototype.base64ToUrlSafe = function (v) { base64ToUrlSafe(v) {
return v.replace(/\//g, '_').replace(/\+/g, '-'); return v.replace(/\//g, '_').replace(/\+/g, '-');
}; }
QiniuCloudInstance.prototype.hmacSha1 = function (encodedFlags, secretKey) { hmacSha1(encodedFlags, secretKey) {
var hmac = crypto_1.default.createHmac('sha1', secretKey); const hmac = crypto_1.default.createHmac('sha1', secretKey);
hmac.update(encodedFlags); hmac.update(encodedFlags);
return hmac.digest('base64'); return hmac.digest('base64');
}; }
QiniuCloudInstance.prototype.urlSafeBase64Encode = function (jsonFlags) { urlSafeBase64Encode(jsonFlags) {
var encoded = buffer_1.Buffer.from(jsonFlags).toString('base64'); const encoded = buffer_1.Buffer.from(jsonFlags).toString('base64');
return this.base64ToUrlSafe(encoded); return this.base64ToUrlSafe(encoded);
}; }
return QiniuCloudInstance; }
}());
exports.QiniuCloudInstance = QiniuCloudInstance; exports.QiniuCloudInstance = QiniuCloudInstance;

View File

@ -1,16 +1,20 @@
"use strict"; "use strict";
Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "__esModule", { value: true });
exports.TencentSmsInstance = void 0; exports.TencentSmsInstance = void 0;
var tslib_1 = require("tslib"); const sms_client_1 = require("tencentcloud-sdk-nodejs/tencentcloud/services/sms/v20210111/sms_client");
var sms_client_1 = require("tencentcloud-sdk-nodejs/tencentcloud/services/sms/v20210111/sms_client"); const SmsClient = sms_client_1.Client;
var SmsClient = sms_client_1.Client; class TencentSmsInstance {
var TencentSmsInstance = /** @class */ (function () { secretId;
function TencentSmsInstance(secretId, secretKey, region, endpoint) { secretKey;
region;
endpoint;
client;
constructor(secretId, secretKey, region, endpoint) {
this.secretId = secretId; this.secretId = secretId;
this.secretKey = secretKey; this.secretKey = secretKey;
this.region = region; this.region = region;
this.endpoint = endpoint; this.endpoint = endpoint;
var clientConfig = { const clientConfig = {
credential: { credential: {
secretId: this.secretId, secretId: this.secretId,
secretKey: this.secretKey, secretKey: this.secretKey,
@ -25,26 +29,21 @@ var TencentSmsInstance = /** @class */ (function () {
// 实例化要请求产品的client对象,clientProfile是可选的 // 实例化要请求产品的client对象,clientProfile是可选的
this.client = new SmsClient(clientConfig); this.client = new SmsClient(clientConfig);
} }
TencentSmsInstance.prototype.sendSms = function (params) { async sendSms(params) {
return tslib_1.__awaiter(this, void 0, void 0, function () { // const params: SendSmsRequest = {
var data, err_1; // PhoneNumberSet: [],
return tslib_1.__generator(this, function (_a) { // TemplateParamSet: [],
switch (_a.label) { // SmsSdkAppId: '',
case 0: // TemplateId: '',
_a.trys.push([0, 2, , 3]); // };
return [4 /*yield*/, this.client.SendSms(params)]; try {
case 1: const data = await this.client.SendSms(params);
data = _a.sent(); return data;
return [2 /*return*/, data]; }
case 2: catch (err) {
err_1 = _a.sent(); console.error(err);
console.error(err_1); throw err;
throw err_1; }
case 3: return [2 /*return*/]; }
} }
});
});
};
return TencentSmsInstance;
}());
exports.TencentSmsInstance = TencentSmsInstance; exports.TencentSmsInstance = TencentSmsInstance;

View File

@ -1,14 +1,18 @@
"use strict"; "use strict";
Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "__esModule", { value: true });
exports.TencentSmsInstance = void 0; exports.TencentSmsInstance = void 0;
var tslib_1 = require("tslib"); class TencentSmsInstance {
var TencentSmsInstance = /** @class */ (function () { secretId;
function TencentSmsInstance(secretId, secretKey, region, endpoint) { secretKey;
region;
endpoint;
client;
constructor(secretId, secretKey, region, endpoint) {
this.secretId = secretId; this.secretId = secretId;
this.secretKey = secretKey; this.secretKey = secretKey;
this.region = region; this.region = region;
this.endpoint = endpoint; this.endpoint = endpoint;
var clientConfig = { const clientConfig = {
credential: { credential: {
secretId: this.secretId, secretId: this.secretId,
secretKey: this.secretKey, secretKey: this.secretKey,
@ -21,14 +25,9 @@ var TencentSmsInstance = /** @class */ (function () {
}, },
}; };
} }
TencentSmsInstance.prototype.sendSms = function (params) { async sendSms(params) {
return tslib_1.__awaiter(this, void 0, void 0, function () {
return tslib_1.__generator(this, function (_a) {
console.log('mp走不到这里'); console.log('mp走不到这里');
return [2 /*return*/, {}]; return {};
}); }
}); }
};
return TencentSmsInstance;
}());
exports.TencentSmsInstance = TencentSmsInstance; exports.TencentSmsInstance = TencentSmsInstance;

View File

@ -1,14 +1,18 @@
"use strict"; "use strict";
Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "__esModule", { value: true });
exports.TencentSmsInstance = void 0; exports.TencentSmsInstance = void 0;
var tslib_1 = require("tslib"); class TencentSmsInstance {
var TencentSmsInstance = /** @class */ (function () { secretId;
function TencentSmsInstance(secretId, secretKey, region, endpoint) { secretKey;
region;
endpoint;
client;
constructor(secretId, secretKey, region, endpoint) {
this.secretId = secretId; this.secretId = secretId;
this.secretKey = secretKey; this.secretKey = secretKey;
this.region = region; this.region = region;
this.endpoint = endpoint; this.endpoint = endpoint;
var clientConfig = { const clientConfig = {
credential: { credential: {
secretId: this.secretId, secretId: this.secretId,
secretKey: this.secretKey, secretKey: this.secretKey,
@ -21,14 +25,9 @@ var TencentSmsInstance = /** @class */ (function () {
}, },
}; };
} }
TencentSmsInstance.prototype.sendSms = function (params) { async sendSms(params) {
return tslib_1.__awaiter(this, void 0, void 0, function () {
return tslib_1.__generator(this, function (_a) {
console.log('web走不到这里'); console.log('web走不到这里');
return [2 /*return*/, {}]; return {};
}); }
}); }
};
return TencentSmsInstance;
}());
exports.TencentSmsInstance = TencentSmsInstance; exports.TencentSmsInstance = TencentSmsInstance;

View File

@ -1,12 +1,17 @@
"use strict"; "use strict";
Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "__esModule", { value: true });
exports.WechatMpInstance = void 0; exports.WechatMpInstance = void 0;
var tslib_1 = require("tslib"); const tslib_1 = require("tslib");
require('../../fetch'); require('../../fetch');
var crypto_1 = tslib_1.__importDefault(require("crypto")); const crypto_1 = tslib_1.__importDefault(require("crypto"));
var buffer_1 = require("buffer"); const buffer_1 = require("buffer");
var WechatMpInstance = /** @class */ (function () { class WechatMpInstance {
function WechatMpInstance(appId, appSecret, accessToken, externalRefreshFn) { appId;
appSecret;
accessToken;
refreshAccessTokenHandler;
externalRefreshFn;
constructor(appId, appSecret, accessToken, externalRefreshFn) {
this.appId = appId; this.appId = appId;
this.appSecret = appSecret; this.appSecret = appSecret;
this.externalRefreshFn = externalRefreshFn; this.externalRefreshFn = externalRefreshFn;
@ -20,147 +25,90 @@ var WechatMpInstance = /** @class */ (function () {
this.refreshAccessToken(); this.refreshAccessToken();
} }
} }
WechatMpInstance.prototype.getAccessToken = function () { async getAccessToken() {
return tslib_1.__awaiter(this, void 0, void 0, function () { while (true) {
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
if (!true) return [3 /*break*/, 2];
if (this.accessToken) { if (this.accessToken) {
return [2 /*return*/, this.accessToken]; return this.accessToken;
} }
return [4 /*yield*/, new Promise(function (resolve) { return setTimeout(function () { return resolve(0); }, 500); })]; await new Promise((resolve) => setTimeout(() => resolve(0), 500));
case 1:
_a.sent();
return [3 /*break*/, 0];
case 2: return [2 /*return*/];
} }
}); }
}); async access(url, init, fresh) {
}; const response = await global.fetch(url, init);
WechatMpInstance.prototype.access = function (url, init, fresh) { const { headers, status } = response;
return tslib_1.__awaiter(this, void 0, void 0, function () {
var response, headers, status, contentType, json, data;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, global.fetch(url, init)];
case 1:
response = _a.sent();
headers = response.headers, status = response.status;
if (![200, 201].includes(status)) { if (![200, 201].includes(status)) {
throw new Error("\u5FAE\u4FE1\u670D\u52A1\u5668\u8FD4\u56DE\u4E0D\u6B63\u786E\u5E94\u7B54\uFF1A".concat(status)); throw new Error(`微信服务器返回不正确应答:${status}`);
} }
contentType = headers['Content-Type'] || headers.get('Content-Type'); const contentType = headers['Content-Type'] || headers.get('Content-Type');
if (!contentType.includes('application/json')) return [3 /*break*/, 3]; if (contentType.includes('application/json')) {
return [4 /*yield*/, response.json()]; const json = await response.json();
case 2:
json = _a.sent();
if (typeof json.errcode === 'number' && json.errcode !== 0) { if (typeof json.errcode === 'number' && json.errcode !== 0) {
if ([42001, 40001].includes(json.errcode)) { if ([42001, 40001].includes(json.errcode)) {
if (fresh) { if (fresh) {
throw new Error('刚刷新的token不可能马上过期请检查是否有并发刷新token的逻辑'); throw new Error('刚刷新的token不可能马上过期请检查是否有并发刷新token的逻辑');
} }
console.log(JSON.stringify(json)); console.log(JSON.stringify(json));
return [2 /*return*/, this.refreshAccessToken(url, init)]; return this.refreshAccessToken(url, init);
} }
throw new Error("\u8C03\u7528\u5FAE\u4FE1\u63A5\u53E3\u8FD4\u56DE\u51FA\u9519\uFF0Ccode\u662F".concat(json.errcode, "\uFF0C\u4FE1\u606F\u662F").concat(json.errmsg)); throw new Error(`调用微信接口返回出错code是${json.errcode},信息是${json.errmsg}`);
} }
return [2 /*return*/, json]; return json;
case 3: }
if (!(contentType.includes('text') || if (contentType.includes('text') ||
contentType.includes('xml') || contentType.includes('xml') ||
contentType.includes('html'))) return [3 /*break*/, 5]; contentType.includes('html')) {
return [4 /*yield*/, response.text()]; const data = await response.text();
case 4: return data;
data = _a.sent();
return [2 /*return*/, data];
case 5:
if (!contentType.includes('application/octet-stream')) return [3 /*break*/, 7];
return [4 /*yield*/, response.arrayBuffer()];
case 6: return [2 /*return*/, _a.sent()];
case 7: return [2 /*return*/, response];
} }
}); if (contentType.includes('application/octet-stream')) {
}); return await response.arrayBuffer();
}; }
WechatMpInstance.prototype.code2Session = function (code) { return response;
return tslib_1.__awaiter(this, void 0, void 0, function () { }
var result, _a, session_key, openid, unionid; async code2Session(code) {
return tslib_1.__generator(this, function (_b) { const result = await this.access(`https://api.weixin.qq.com/sns/jscode2session?appid=${this.appId}&secret=${this.appSecret}&js_code=${code}&grant_type=authorization_code`);
switch (_b.label) { const { session_key, openid, unionid } = JSON.parse(result); // 这里微信返回的数据竟然是text/plain
case 0: return [4 /*yield*/, this.access("https://api.weixin.qq.com/sns/jscode2session?appid=".concat(this.appId, "&secret=").concat(this.appSecret, "&js_code=").concat(code, "&grant_type=authorization_code"))]; return {
case 1:
result = _b.sent();
_a = JSON.parse(result), session_key = _a.session_key, openid = _a.openid, unionid = _a.unionid;
return [2 /*return*/, {
sessionKey: session_key, sessionKey: session_key,
openId: openid, openId: openid,
unionId: unionid, unionId: unionid,
}];
}
});
});
}; };
WechatMpInstance.prototype.refreshAccessToken = function (url, init) { }
return tslib_1.__awaiter(this, void 0, void 0, function () { async refreshAccessToken(url, init) {
var result, _a, access_token, expires_in; const result = this.externalRefreshFn
var _this = this; ? await this.externalRefreshFn(this.appId)
return tslib_1.__generator(this, function (_b) { : await this.access(`https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=${this.appId}&secret=${this.appSecret}`);
switch (_b.label) { const { access_token, expires_in } = result;
case 0:
if (!this.externalRefreshFn) return [3 /*break*/, 2];
return [4 /*yield*/, this.externalRefreshFn(this.appId)];
case 1:
_a = _b.sent();
return [3 /*break*/, 4];
case 2: return [4 /*yield*/, this.access("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=".concat(this.appId, "&secret=").concat(this.appSecret))];
case 3:
_a = _b.sent();
_b.label = 4;
case 4:
result = _a;
access_token = result.access_token, expires_in = result.expires_in;
this.accessToken = access_token; this.accessToken = access_token;
if (process.env.NODE_ENV === 'development') { if (process.env.NODE_ENV === 'development') {
console.log("\u5C0F\u7A0B\u5E8F\u83B7\u5F97\u65B0\u7684accessToken\u3002appId:[".concat(this.appId, "], token: [").concat(access_token, "]")); console.log(`小程序获得新的accessToken。appId:[${this.appId}], token: [${access_token}]`);
} }
// 生成下次刷新的定时器 // 生成下次刷新的定时器
this.refreshAccessTokenHandler = setTimeout(function () { this.refreshAccessTokenHandler = setTimeout(() => {
_this.refreshAccessToken(); this.refreshAccessToken();
}, (expires_in - 10) * 1000); }, (expires_in - 10) * 1000);
if (url) { if (url) {
return [2 /*return*/, this.access(url, init, true)]; return this.access(url, init, true);
} }
return [2 /*return*/];
} }
}); decryptData(sessionKey, encryptedData, iv, signature) {
}); const skBuf = buffer_1.Buffer.from(sessionKey, 'base64');
};
WechatMpInstance.prototype.decryptData = function (sessionKey, encryptedData, iv, signature) {
var skBuf = buffer_1.Buffer.from(sessionKey, 'base64');
// const edBuf = Buffer.from(encryptedData, 'base64'); // const edBuf = Buffer.from(encryptedData, 'base64');
var ivBuf = buffer_1.Buffer.from(iv, 'base64'); const ivBuf = buffer_1.Buffer.from(iv, 'base64');
var decipher = crypto_1.default.createDecipheriv('aes-128-cbc', skBuf, ivBuf); const decipher = crypto_1.default.createDecipheriv('aes-128-cbc', skBuf, ivBuf);
// 设置自动 padding 为 true删除填充补位 // 设置自动 padding 为 true删除填充补位
decipher.setAutoPadding(true); decipher.setAutoPadding(true);
var decoded = decipher.update(encryptedData, 'base64', 'utf8'); let decoded = decipher.update(encryptedData, 'base64', 'utf8');
decoded += decipher.final('utf8'); decoded += decipher.final('utf8');
var data = JSON.parse(decoded); const data = JSON.parse(decoded);
if (data.watermark.appid !== this.appId) { if (data.watermark.appid !== this.appId) {
throw new Error('Illegal Buffer'); throw new Error('Illegal Buffer');
} }
return data; return data;
}; }
WechatMpInstance.prototype.getMpUnlimitWxaCode = function (_a) { async getMpUnlimitWxaCode({ scene, page, envVersion = 'release', width, autoColor, lineColor, isHyaline, }) {
var scene = _a.scene, page = _a.page, _b = _a.envVersion, envVersion = _b === void 0 ? 'release' : _b, width = _a.width, autoColor = _a.autoColor, lineColor = _a.lineColor, isHyaline = _a.isHyaline; const token = await this.getAccessToken();
return tslib_1.__awaiter(this, void 0, void 0, function () { const result = await this.access(`https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=${token}`, {
var token, result;
return tslib_1.__generator(this, function (_c) {
switch (_c.label) {
case 0: return [4 /*yield*/, this.getAccessToken()];
case 1:
token = _c.sent();
return [4 /*yield*/, this.access("https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=".concat(token), {
method: 'POST', method: 'POST',
headers: { headers: {
'Content-type': 'application/json', 'Content-type': 'application/json',
@ -168,80 +116,52 @@ var WechatMpInstance = /** @class */ (function () {
}, },
body: JSON.stringify({ body: JSON.stringify({
// access_token: this.accessToken, // access_token: this.accessToken,
scene: scene, scene,
page: page, page,
env_version: envVersion, env_version: envVersion,
width: width, width,
auto_color: autoColor, auto_color: autoColor,
line_color: lineColor, line_color: lineColor,
is_hyaline: isHyaline, is_hyaline: isHyaline,
}), }),
})]; });
case 2: return (await result.arrayBuffer());
result = _c.sent();
return [4 /*yield*/, result.arrayBuffer()];
case 3: return [2 /*return*/, (_c.sent())];
} }
}); async getUserPhoneNumber(code) {
}); const token = await this.getAccessToken();
}; const result = (await this.access(`https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=${token}`, {
WechatMpInstance.prototype.getUserPhoneNumber = function (code) {
return tslib_1.__awaiter(this, void 0, void 0, function () {
var token, result;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, this.getAccessToken()];
case 1:
token = _a.sent();
return [4 /*yield*/, this.access("https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=".concat(token), {
method: 'POST', method: 'POST',
headers: { headers: {
'Content-type': 'application/json', 'Content-type': 'application/json',
}, },
body: JSON.stringify({ body: JSON.stringify({
code: code, code,
}), }),
})]; }));
case 2: return result.phone_info;
result = (_a.sent());
return [2 /*return*/, result.phone_info];
} }
});
});
};
/** /**
* 发送订阅消息 * 发送订阅消息
* @param param0 * @param param0
* @returns * @returns
* https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/mp-message-management/subscribe-message/sendMessage.html * https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/mp-message-management/subscribe-message/sendMessage.html
*/ */
WechatMpInstance.prototype.sendSubscribedMessage = function (_a) { async sendSubscribedMessage({ templateId, page, openId, data, state, lang, }) {
var templateId = _a.templateId, page = _a.page, openId = _a.openId, data = _a.data, state = _a.state, lang = _a.lang; const token = await this.getAccessToken();
return tslib_1.__awaiter(this, void 0, void 0, function () {
var token;
return tslib_1.__generator(this, function (_b) {
switch (_b.label) {
case 0: return [4 /*yield*/, this.getAccessToken()];
case 1:
token = _b.sent();
/** /**
* 实测若用户未订阅会抛出errcode: 43101, errmsg: user refuse to accept the msg * 实测若用户未订阅会抛出errcode: 43101, errmsg: user refuse to accept the msg
*/ */
return [2 /*return*/, this.access("https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=".concat(token), { return this.access(`https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=${token}`, {
body: JSON.stringify({ body: JSON.stringify({
template_id: templateId, template_id: templateId,
page: page, page,
touser: openId, touser: openId,
data: data, data,
miniprogram_state: state || 'formal', miniprogram_state: state || 'formal',
lang: lang || 'zh_CN', lang: lang || 'zh_CN',
}), }),
method: 'post', method: 'post',
})]; });
}
} }
});
});
};
return WechatMpInstance;
}());
exports.WechatMpInstance = WechatMpInstance; exports.WechatMpInstance = WechatMpInstance;

View File

@ -52,6 +52,12 @@ export declare class WechatPublicInstance {
gender: string | undefined; gender: string | undefined;
avatar: string; avatar: string;
}>; }>;
getTags(): Promise<any>;
getCurrentMenu(): Promise<any>;
getMenu(): Promise<any>;
createMenu(menuConfig: any): Promise<any>;
createConditionalMenu(menuConfig: any): Promise<any>;
deleteConditionalMenu(menuid: number): Promise<any>;
private refreshAccessToken; private refreshAccessToken;
decryptData(sessionKey: string, encryptedData: string, iv: string, signature: string): any; decryptData(sessionKey: string, encryptedData: string, iv: string, signature: string): any;
getQrCode(options: { getQrCode(options: {
@ -81,6 +87,23 @@ export declare class WechatPublicInstance {
count: number; count: number;
noContent?: 0 | 1; noContent?: 0 | 1;
}): Promise<any>; }): Promise<any>;
getArticle(options: {
article_id: string;
}): Promise<any>;
createMaterial(options: {
type: 'image' | 'voice' | 'video' | 'thumb';
media: FormData;
description?: FormData;
}): Promise<any>;
batchGetMaterialList(options: {
type: 'image' | 'video' | 'voice' | 'news';
offset?: number;
count: number;
}): Promise<any>;
getMaterial(options: {
type: 'image' | 'video' | 'voice' | 'news';
media_id: string;
}): Promise<any>;
getTicket(): Promise<string>; getTicket(): Promise<string>;
private randomString; private randomString;
signatureJsSDK(options: { signatureJsSDK(options: {

View File

@ -1,12 +1,18 @@
"use strict"; "use strict";
Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "__esModule", { value: true });
exports.WechatPublicInstance = void 0; exports.WechatPublicInstance = void 0;
var tslib_1 = require("tslib"); const tslib_1 = require("tslib");
require('../../fetch'); require('../../fetch');
var crypto_1 = tslib_1.__importDefault(require("crypto")); const crypto_1 = tslib_1.__importDefault(require("crypto"));
var buffer_1 = require("buffer"); const buffer_1 = require("buffer");
var WechatPublicInstance = /** @class */ (function () { const url_1 = tslib_1.__importDefault(require("url"));
function WechatPublicInstance(appId, appSecret, accessToken, externalRefreshFn) { class WechatPublicInstance {
appId;
appSecret;
accessToken;
refreshAccessTokenHandler;
externalRefreshFn;
constructor(appId, appSecret, accessToken, externalRefreshFn) {
this.appId = appId; this.appId = appId;
this.appSecret = appSecret; this.appSecret = appSecret;
this.externalRefreshFn = externalRefreshFn; this.externalRefreshFn = externalRefreshFn;
@ -20,87 +26,49 @@ var WechatPublicInstance = /** @class */ (function () {
this.refreshAccessToken(); this.refreshAccessToken();
} }
} }
WechatPublicInstance.prototype.getAccessToken = function () { async getAccessToken() {
return tslib_1.__awaiter(this, void 0, void 0, function () { while (true) {
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
if (!true) return [3 /*break*/, 2];
if (this.accessToken) { if (this.accessToken) {
return [2 /*return*/, this.accessToken]; return this.accessToken;
} }
return [4 /*yield*/, new Promise(function (resolve) { return setTimeout(function () { return resolve(0); }, 500); })]; await new Promise((resolve) => setTimeout(() => resolve(0), 500));
case 1:
_a.sent();
return [3 /*break*/, 0];
case 2: return [2 /*return*/];
} }
});
});
};
WechatPublicInstance.prototype.access = function (url, mockData, init) {
return tslib_1.__awaiter(this, void 0, void 0, function () {
var response, headers, status, contentType, json, data;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
if (process.env.NODE_ENV === 'development') {
return [2 /*return*/, mockData];
} }
return [4 /*yield*/, global.fetch(url, init)]; async access(url, mockData, init) {
case 1: if (process.env.NODE_ENV === 'development' && mockData) {
response = _a.sent(); return mockData;
headers = response.headers, status = response.status; }
const response = await global.fetch(url, init);
const { headers, status } = response;
if (![200, 201].includes(status)) { if (![200, 201].includes(status)) {
throw new Error("\u5FAE\u4FE1\u670D\u52A1\u5668\u8FD4\u56DE\u4E0D\u6B63\u786E\u5E94\u7B54\uFF1A".concat(status)); throw new Error(`微信服务器返回不正确应答:${status}`);
} }
contentType = headers['Content-Type'] || headers.get('Content-Type'); const contentType = headers['Content-Type'] || headers.get('Content-Type');
if (!contentType.includes('application/json')) return [3 /*break*/, 3]; if (contentType.includes('application/json')) {
return [4 /*yield*/, response.json()]; const json = await response.json();
case 2:
json = _a.sent();
if (typeof json.errcode === 'number' && json.errcode !== 0) { if (typeof json.errcode === 'number' && json.errcode !== 0) {
if ([40001, 42001].includes(json.errcode)) { if ([40001, 42001].includes(json.errcode)) {
return [2 /*return*/, this.refreshAccessToken(url, init)]; return this.refreshAccessToken(url, init);
} }
throw new Error("\u8C03\u7528\u5FAE\u4FE1\u63A5\u53E3\u8FD4\u56DE\u51FA\u9519\uFF0Ccode\u662F".concat(json.errcode, "\uFF0C\u4FE1\u606F\u662F").concat(json.errmsg)); throw new Error(`调用微信接口返回出错code是${json.errcode},信息是${json.errmsg}`);
} }
return [2 /*return*/, json]; return json;
case 3: }
if (!(contentType.includes('text') || if (contentType.includes('text') ||
contentType.includes('xml') || contentType.includes('xml') ||
contentType.includes('html'))) return [3 /*break*/, 5]; contentType.includes('html')) {
return [4 /*yield*/, response.text()]; const data = await response.text();
case 4: return data;
data = _a.sent();
return [2 /*return*/, data];
case 5:
if (!contentType.includes('application/octet-stream')) return [3 /*break*/, 7];
return [4 /*yield*/, response.arrayBuffer()];
case 6: return [2 /*return*/, _a.sent()];
case 7: return [2 /*return*/, response];
} }
}); if (contentType.includes('application/octet-stream')) {
}); return await response.arrayBuffer();
}; }
WechatPublicInstance.prototype.code2Session = function (code) { return response;
return tslib_1.__awaiter(this, void 0, void 0, function () { }
var result, _a, access_token, openid, unionid, scope, refresh_token, is_snapshotuser, expires_in; async code2Session(code) {
return tslib_1.__generator(this, function (_b) { const result = await this.access(`https://api.weixin.qq.com/sns/oauth2/access_token?appid=${this.appId}&secret=${this.appSecret}&code=${code}&grant_type=authorization_code`);
switch (_b.label) { const { access_token, openid, unionid, scope, refresh_token, is_snapshotuser, expires_in, } = typeof result === 'string' ? JSON.parse(result) : result; // 这里微信返回的数据有时候竟然是text/plain
case 0: return [4 /*yield*/, this.access("https://api.weixin.qq.com/sns/oauth2/access_token?appid=".concat(this.appId, "&secret=").concat(this.appSecret, "&code=").concat(code, "&grant_type=authorization_code"), { return {
access_token: 'aaa',
openid: code,
unionid: code,
refresh_token: 'aaa',
is_snapshotuser: false,
expires_in: 30,
scope: 'userinfo',
})];
case 1:
result = _b.sent();
_a = typeof result === 'string' ? JSON.parse(result) : result, access_token = _a.access_token, openid = _a.openid, unionid = _a.unionid, scope = _a.scope, refresh_token = _a.refresh_token, is_snapshotuser = _a.is_snapshotuser, expires_in = _a.expires_in;
return [2 /*return*/, {
accessToken: access_token, accessToken: access_token,
openId: openid, openId: openid,
unionId: unionid, unionId: unionid,
@ -109,124 +77,156 @@ var WechatPublicInstance = /** @class */ (function () {
isSnapshotUser: !!is_snapshotuser, isSnapshotUser: !!is_snapshotuser,
atExpiredAt: Date.now() + expires_in * 1000, atExpiredAt: Date.now() + expires_in * 1000,
rtExpiredAt: Date.now() + 30 * 86400 * 1000, rtExpiredAt: Date.now() + 30 * 86400 * 1000,
}];
}
});
});
}; };
WechatPublicInstance.prototype.refreshUserAccessToken = function (refreshToken) { }
return tslib_1.__awaiter(this, void 0, void 0, function () { async refreshUserAccessToken(refreshToken) {
var result, access_token, refresh_token, expires_in, scope; const result = await this.access(`https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=${this.appId}&grant_type=refresh_token&refresh_token=${refreshToken}`);
return tslib_1.__generator(this, function (_a) { const { access_token, refresh_token, expires_in, scope } = result;
switch (_a.label) { return {
case 0: return [4 /*yield*/, this.access("https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=".concat(this.appId, "&grant_type=refresh_token&refresh_token=").concat(refreshToken), {
access_token: 'aaa',
refresh_token: 'aaa',
expires_in: 30,
scope: 'userinfo',
})];
case 1:
result = _a.sent();
access_token = result.access_token, refresh_token = result.refresh_token, expires_in = result.expires_in, scope = result.scope;
return [2 /*return*/, {
accessToken: access_token, accessToken: access_token,
refreshToken: refresh_token, refreshToken: refresh_token,
atExpiredAt: Date.now() + expires_in * 1000, atExpiredAt: Date.now() + expires_in * 1000,
scope: scope, scope: scope,
}];
}
});
});
}; };
WechatPublicInstance.prototype.getUserInfo = function (accessToken, openId) { }
return tslib_1.__awaiter(this, void 0, void 0, function () { async getUserInfo(accessToken, openId) {
var result, nickname, sex, headimgurl; const result = await this.access(`https://api.weixin.qq.com/sns/userinfo?access_token=${accessToken}&openid=${openId}&lang=zh_CN`);
return tslib_1.__generator(this, function (_a) { const { nickname, sex, headimgurl } = result;
switch (_a.label) { return {
case 0: return [4 /*yield*/, this.access("https://api.weixin.qq.com/sns/userinfo?access_token=".concat(accessToken, "&openid=").concat(openId, "&lang=zh_CN"), {
nickname: '码农哥',
sex: 1,
headimgurl: 'https://www.ertongzy.com/uploads/allimg/161005/2021233Y7-0.jpg',
})];
case 1:
result = _a.sent();
nickname = result.nickname, sex = result.sex, headimgurl = result.headimgurl;
return [2 /*return*/, {
nickname: nickname, nickname: nickname,
gender: sex === 1 ? 'male' : sex === 2 ? 'female' : undefined, gender: sex === 1 ? 'male' : sex === 2 ? 'female' : undefined,
avatar: headimgurl, avatar: headimgurl,
}];
}
});
});
}; };
WechatPublicInstance.prototype.refreshAccessToken = function (url, init) { }
return tslib_1.__awaiter(this, void 0, void 0, function () { async getTags() {
var result, _a, access_token, expires_in; const myInit = {
var _this = this; method: 'GET',
return tslib_1.__generator(this, function (_b) { headers: {
switch (_b.label) { 'Content-Type': 'application/json',
case 0: },
if (!this.externalRefreshFn) return [3 /*break*/, 2]; };
return [4 /*yield*/, this.externalRefreshFn(this.appId)]; const token = await this.getAccessToken();
case 1: const result = await this.access(`https://api.weixin.qq.com/cgi-bin/tags/get?access_token=${token}`, undefined, myInit);
_a = _b.sent(); return result;
return [3 /*break*/, 4]; }
case 2: return [4 /*yield*/, this.access("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=".concat(this.appId, "&secret=").concat(this.appSecret), { access_token: 'mockToken', expires_in: 600 })]; async getCurrentMenu() {
case 3: const myInit = {
_a = _b.sent(); method: 'GET',
_b.label = 4; headers: {
case 4: 'Content-Type': 'application/json',
result = _a; },
access_token = result.access_token, expires_in = result.expires_in; };
const token = await this.getAccessToken();
const result = await this.access(`https://api.weixin.qq.com/cgi-bin/get_current_selfmenu_info?access_token=${token}`, undefined, myInit);
return result;
}
async getMenu() {
const myInit = {
method: 'GET',
headers: {
'Content-Type': 'application/json',
},
};
const token = await this.getAccessToken();
const result = await this.access(`https://api.weixin.qq.com/cgi-bin/menu/get?access_token=${token}`, undefined, myInit);
return result;
}
async createMenu(menuConfig) {
const myInit = {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(menuConfig),
};
const token = await this.getAccessToken();
const result = await this.access(`https://api.weixin.qq.com/cgi-bin/menu/create?access_token=${token}`, undefined, myInit);
const { errcode } = result;
if (errcode === 0) {
return Object.assign({ success: true }, result);
}
return Object.assign({ success: false }, result);
}
async createConditionalMenu(menuConfig) {
const myInit = {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(menuConfig),
};
const token = await this.getAccessToken();
const result = await this.access(`https://api.weixin.qq.com/cgi-bin/menu/addconditional?access_token=${token}`, undefined, myInit);
const { errcode } = result;
if (errcode === 0) {
return Object.assign({ success: true }, result);
}
return Object.assign({ success: false }, result);
}
async deleteConditionalMenu(menuid) {
const myInit = {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
menuid
}),
};
const token = await this.getAccessToken();
const result = await this.access(`https://api.weixin.qq.com/cgi-bin/menu/delconditional?access_token=${token}`, undefined, myInit);
const { errcode } = result;
if (errcode === 0) {
return Object.assign({ success: true }, result);
}
return Object.assign({ success: false }, result);
}
async refreshAccessToken(url, init) {
const result = this.externalRefreshFn
? await this.externalRefreshFn(this.appId)
: await this.access(`https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=${this.appId}&secret=${this.appSecret}`);
const { access_token, expires_in } = result;
this.accessToken = access_token; this.accessToken = access_token;
// 生成下次刷新的定时器 // 生成下次刷新的定时器
console.log((expires_in - 10) * 1000); console.log((expires_in - 10) * 1000);
this.refreshAccessTokenHandler = setTimeout(function () { this.refreshAccessTokenHandler = setTimeout(() => {
_this.refreshAccessToken(); this.refreshAccessToken();
}, (expires_in - 10) * 1000); }, (expires_in - 10) * 1000);
if (url) { if (url) {
return [2 /*return*/, this.access(url, {}, init)]; const url2 = new url_1.default.URL(url);
url2.searchParams.set('access_token', access_token);
return this.access(url2.toString(), {}, init);
} }
return [2 /*return*/];
} }
}); decryptData(sessionKey, encryptedData, iv, signature) {
}); const skBuf = buffer_1.Buffer.from(sessionKey, 'base64');
};
WechatPublicInstance.prototype.decryptData = function (sessionKey, encryptedData, iv, signature) {
var skBuf = buffer_1.Buffer.from(sessionKey, 'base64');
// const edBuf = Buffer.from(encryptedData, 'base64'); // const edBuf = Buffer.from(encryptedData, 'base64');
var ivBuf = buffer_1.Buffer.from(iv, 'base64'); const ivBuf = buffer_1.Buffer.from(iv, 'base64');
var decipher = crypto_1.default.createDecipheriv('aes-128-cbc', skBuf, ivBuf); const decipher = crypto_1.default.createDecipheriv('aes-128-cbc', skBuf, ivBuf);
// 设置自动 padding 为 true删除填充补位 // 设置自动 padding 为 true删除填充补位
decipher.setAutoPadding(true); decipher.setAutoPadding(true);
var decoded = decipher.update(encryptedData, 'base64', 'utf8'); let decoded = decipher.update(encryptedData, 'base64', 'utf8');
decoded += decipher.final('utf8'); decoded += decipher.final('utf8');
var data = JSON.parse(decoded); const data = JSON.parse(decoded);
if (data.watermark.appid !== this.appId) { if (data.watermark.appid !== this.appId) {
throw new Error('Illegal Buffer'); throw new Error('Illegal Buffer');
} }
return data; return data;
}; }
WechatPublicInstance.prototype.getQrCode = function (options) { async getQrCode(options) {
return tslib_1.__awaiter(this, void 0, void 0, function () { const { sceneId, sceneStr, expireSeconds, isPermanent } = options;
var sceneId, sceneStr, expireSeconds, isPermanent, scene, actionName, myInit, token, result;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
sceneId = options.sceneId, sceneStr = options.sceneStr, expireSeconds = options.expireSeconds, isPermanent = options.isPermanent;
if (!sceneId && !sceneStr) { if (!sceneId && !sceneStr) {
throw new Error('Missing sceneId or sceneStr'); throw new Error('Missing sceneId or sceneStr');
} }
scene = sceneId const scene = sceneId
? { ? {
scene_id: sceneId, scene_id: sceneId,
} }
: { : {
scene_str: sceneStr, scene_str: sceneStr,
}; };
actionName = sceneId ? 'QR_SCENE' : 'QR_STR_SCENE'; let actionName = sceneId ? 'QR_SCENE' : 'QR_STR_SCENE';
myInit = { let myInit = {
method: 'POST', method: 'POST',
headers: { headers: {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
@ -235,7 +235,7 @@ var WechatPublicInstance = /** @class */ (function () {
expire_seconds: expireSeconds, expire_seconds: expireSeconds,
action_name: actionName, action_name: actionName,
action_info: { action_info: {
scene: scene, scene,
}, },
}), }),
}; };
@ -249,38 +249,28 @@ var WechatPublicInstance = /** @class */ (function () {
body: JSON.stringify({ body: JSON.stringify({
action_name: actionName, action_name: actionName,
action_info: { action_info: {
scene: scene, scene,
}, },
}), }),
}; };
} }
return [4 /*yield*/, this.getAccessToken()]; const token = await this.getAccessToken();
case 1: const result = await this.access(`https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=${token}`,
token = _a.sent(); // {
return [4 /*yield*/, this.access("https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=".concat(token), { // ticket: `ticket${Date.now()}`,
ticket: "ticket".concat(Date.now()), // url: `http://mock/q/${sceneId ? sceneId : sceneStr}`,
url: "http://mock/q/".concat(sceneId ? sceneId : sceneStr), // expireSeconds: expireSeconds,
expireSeconds: expireSeconds, // },
}, myInit)]; myInit);
case 2: return {
result = _a.sent();
return [2 /*return*/, {
ticket: result.ticket, ticket: result.ticket,
url: result.url, url: result.url,
expireSeconds: result.expire_seconds, expireSeconds: result.expire_seconds,
}];
}
});
});
}; };
WechatPublicInstance.prototype.sendTemplateMessage = function (options) { }
return tslib_1.__awaiter(this, void 0, void 0, function () { async sendTemplateMessage(options) {
var openId, templateId, url, data, miniProgram, clientMsgId, myInit, token, result, errcode; const { openId, templateId, url, data, miniProgram, clientMsgId } = options;
return tslib_1.__generator(this, function (_a) { const myInit = {
switch (_a.label) {
case 0:
openId = options.openId, templateId = options.templateId, url = options.url, data = options.data, miniProgram = options.miniProgram, clientMsgId = options.clientMsgId;
myInit = {
method: 'POST', method: 'POST',
headers: { headers: {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
@ -288,39 +278,29 @@ var WechatPublicInstance = /** @class */ (function () {
body: JSON.stringify({ body: JSON.stringify({
touser: openId, touser: openId,
template_id: templateId, template_id: templateId,
url: url, url,
miniProgram: miniProgram, miniProgram,
client_msg_id: clientMsgId, client_msg_id: clientMsgId,
data: data, data,
}), }),
}; };
return [4 /*yield*/, this.getAccessToken()]; const token = await this.getAccessToken();
case 1: const result = await this.access(`https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=${token}`,
token = _a.sent(); // {
return [4 /*yield*/, this.access("https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=".concat(token), { // errcode: 0,
errcode: 0, // errmsg: 'ok',
errmsg: 'ok', // msgid: Date.now(),
msgid: Date.now(), // },
}, myInit)]; myInit);
case 2: const { errcode } = result;
result = _a.sent();
errcode = result.errcode;
if (errcode === 0) { if (errcode === 0) {
return [2 /*return*/, Object.assign({ success: true }, result)]; return Object.assign({ success: true }, result);
} }
return [2 /*return*/, Object.assign({ success: false }, result)]; return Object.assign({ success: false }, result);
} }
}); async sendServeMessage(options) {
}); const { openId, type } = options;
}; const myInit = {
WechatPublicInstance.prototype.sendServeMessage = function (options) {
return tslib_1.__awaiter(this, void 0, void 0, function () {
var openId, type, myInit, token, result, errcode;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
openId = options.openId, type = options.type;
myInit = {
method: 'POST', method: 'POST',
headers: { headers: {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
@ -377,143 +357,178 @@ var WechatPublicInstance = /** @class */ (function () {
throw new Error('当前消息类型暂不支持'); throw new Error('当前消息类型暂不支持');
} }
} }
return [4 /*yield*/, this.getAccessToken()]; const token = await this.getAccessToken();
case 1: const result = await this.access(`https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=${token}`,
token = _a.sent(); // {
return [4 /*yield*/, this.access("https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=".concat(token), { // errcode: 0,
errcode: 0, // errmsg: 'ok',
errmsg: 'ok', // },
}, myInit)]; myInit);
case 2: const { errcode } = result;
result = _a.sent();
errcode = result.errcode;
if (errcode === 0) { if (errcode === 0) {
return [2 /*return*/, Object.assign({ success: true }, result)]; return Object.assign({ success: true }, result);
} }
return [2 /*return*/, Object.assign({ success: false }, result)]; return Object.assign({ success: false }, result);
} }
}); async batchGetArticle(options) {
}); const { offset, count, noContent } = options;
}; const myInit = {
WechatPublicInstance.prototype.batchGetArticle = function (options) {
return tslib_1.__awaiter(this, void 0, void 0, function () {
var offset, count, noContent, myInit, token, result, errcode;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
offset = options.offset, count = options.count, noContent = options.noContent;
myInit = {
method: 'POST', method: 'POST',
headers: { headers: {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
}, },
body: JSON.stringify({ body: JSON.stringify({
offset: offset, offset,
count: count, count,
no_content: noContent, no_content: noContent,
}), }),
}; };
return [4 /*yield*/, this.getAccessToken()]; const token = await this.getAccessToken();
case 1: const result = await this.access(`https://api.weixin.qq.com/cgi-bin/freepublish/batchget?access_token=${token}`, undefined, myInit);
token = _a.sent(); const { errcode } = result;
return [4 /*yield*/, this.access("https://api.weixin.qq.com/cgi-bin/freepublish/batchget?access_token=".concat(token), {
total_count: 1,
item_count: 1,
item: [
{
article_id: 'test',
content: {
news_item: [
{
title: '测试文章',
author: '测试作者',
digest: '测试摘要',
content: '测试内容',
content_source_url: '',
thumb_media_id: 'TEST_MEDIA_ID',
show_cover_pic: 1,
need_open_comment: 0,
only_fans_can_comment: 0,
url: 'TEST_ARTICLE_URL',
is_deleted: false,
},
],
},
update_time: Date.now(),
},
],
}, myInit)];
case 2:
result = _a.sent();
errcode = result.errcode;
if (!errcode) { if (!errcode) {
return [2 /*return*/, result]; return result;
} }
throw new Error(JSON.stringify(result)); throw new Error(JSON.stringify(result));
} }
}); async getArticle(options) {
}); const { article_id } = options;
const myInit = {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
article_id,
}),
}; };
WechatPublicInstance.prototype.getTicket = function () { const token = await this.getAccessToken();
return tslib_1.__awaiter(this, void 0, void 0, function () { const result = await this.access(`https://api.weixin.qq.com/cgi-bin/freepublish/getarticle?access_token=${token}`, undefined, myInit);
var myInit, token, result, ticket; const { errcode } = result;
return tslib_1.__generator(this, function (_a) { if (!errcode) {
switch (_a.label) { return result;
case 0: }
myInit = { throw new Error(JSON.stringify(result));
}
async createMaterial(options) {
const { type, media, description } = options;
const myInit = {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
};
if (type === 'video') {
Object.assign(myInit, {
body: JSON.stringify({
type,
media,
description,
}),
});
}
else {
Object.assign(myInit, {
body: JSON.stringify({
type,
media,
}),
});
}
;
const token = await this.getAccessToken();
const result = await this.access(`https://api.weixin.qq.com/cgi-bin/material/add_material?access_token=${token}`, undefined, myInit);
const { errcode } = result;
if (!errcode) {
return result;
}
throw new Error(JSON.stringify(result));
}
async batchGetMaterialList(options) {
const { offset, count, type } = options;
const myInit = {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
type,
offset,
count,
}),
};
const token = await this.getAccessToken();
const result = await this.access(`https://api.weixin.qq.com/cgi-bin/material/batchget_material?access_token=${token}`, undefined, myInit);
const { errcode } = result;
if (!errcode) {
return result;
}
throw new Error(JSON.stringify(result));
}
async getMaterial(options) {
const { type, media_id } = options;
const myInit = {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
media_id
}),
};
let imgFile;
const token = await this.getAccessToken();
const result = await this.access(`https://api.weixin.qq.com/cgi-bin/material/get_material?access_token=${token}`, undefined, myInit);
if ('errcode' in result) {
throw new Error(JSON.stringify(result));
}
else {
return result;
}
}
async getTicket() {
const myInit = {
method: 'GET', method: 'GET',
headers: { headers: {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
}, },
}; };
return [4 /*yield*/, this.getAccessToken()]; const token = await this.getAccessToken();
case 1: const result = (await this.access(`https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=${token}&type=jsapi`,
token = _a.sent(); // {
return [4 /*yield*/, this.access("https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=".concat(token, "&type=jsapi"), { // ticket: `ticket${Date.now()}`,
ticket: "ticket".concat(Date.now()), // expires_in: 30,
expires_in: 30, // },
}, myInit)]; myInit));
case 2: const { ticket } = result;
result = (_a.sent()); return ticket;
ticket = result.ticket;
return [2 /*return*/, ticket];
} }
}); randomString() {
}); let len = 16;
}; let $chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678';
WechatPublicInstance.prototype.randomString = function () {
var len = 16;
var $chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678';
/** **默认去掉了容易混淆的字符oOLl,9gq,Vv,Uu,I1****/ /** **默认去掉了容易混淆的字符oOLl,9gq,Vv,Uu,I1****/
var maxPos = $chars.length; let maxPos = $chars.length;
var pwd = ''; let pwd = '';
for (var i = 0; i < len; i++) { for (let i = 0; i < len; i++) {
pwd += $chars.charAt(Math.floor(Math.random() * maxPos)); pwd += $chars.charAt(Math.floor(Math.random() * maxPos));
} }
return pwd; return pwd;
}
async signatureJsSDK(options) {
const url = options.url;
const noncestr = this.randomString();
const timestamp = parseInt((Date.now() / 1000).toString(), 10);
const jsapi_ticket = await this.getTicket();
const contentArray = {
noncestr,
jsapi_ticket,
timestamp,
url,
}; };
WechatPublicInstance.prototype.signatureJsSDK = function (options) { let zhimaString = '';
return tslib_1.__awaiter(this, void 0, void 0, function () {
var url, noncestr, timestamp, jsapi_ticket, contentArray, zhimaString;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
url = options.url;
noncestr = this.randomString();
timestamp = parseInt((Date.now() / 1000).toString(), 10);
return [4 /*yield*/, this.getTicket()];
case 1:
jsapi_ticket = _a.sent();
contentArray = {
noncestr: noncestr,
jsapi_ticket: jsapi_ticket,
timestamp: timestamp,
url: url,
};
zhimaString = '';
Object.keys(contentArray) Object.keys(contentArray)
.sort() .sort()
.forEach(function (ele, idx) { .forEach((ele, idx) => {
if (idx > 0) { if (idx > 0) {
zhimaString += '&'; zhimaString += '&';
} }
@ -521,19 +536,15 @@ var WechatPublicInstance = /** @class */ (function () {
zhimaString += '='; zhimaString += '=';
zhimaString += contentArray[ele]; zhimaString += contentArray[ele];
}); });
return [2 /*return*/, { return {
signature: crypto_1.default signature: crypto_1.default
.createHash('sha1') .createHash('sha1')
.update(zhimaString) .update(zhimaString)
.digest('hex'), .digest('hex'),
noncestr: noncestr, noncestr,
timestamp: timestamp, timestamp,
appId: this.appId, appId: this.appId,
}];
}
});
});
}; };
return WechatPublicInstance; }
}()); }
exports.WechatPublicInstance = WechatPublicInstance; exports.WechatPublicInstance = WechatPublicInstance;

View File

@ -1,12 +1,17 @@
"use strict"; "use strict";
Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "__esModule", { value: true });
exports.WechatWebInstance = void 0; exports.WechatWebInstance = void 0;
var tslib_1 = require("tslib"); const tslib_1 = require("tslib");
require('../../fetch'); require('../../fetch');
var crypto_1 = tslib_1.__importDefault(require("crypto")); const crypto_1 = tslib_1.__importDefault(require("crypto"));
var buffer_1 = require("buffer"); const buffer_1 = require("buffer");
var WechatWebInstance = /** @class */ (function () { class WechatWebInstance {
function WechatWebInstance(appId, appSecret, accessToken, externalRefreshFn) { appId;
appSecret;
accessToken;
refreshAccessTokenHandler;
externalRefreshFn;
constructor(appId, appSecret, accessToken, externalRefreshFn) {
this.appId = appId; this.appId = appId;
this.appSecret = appSecret; this.appSecret = appSecret;
this.externalRefreshFn = externalRefreshFn; this.externalRefreshFn = externalRefreshFn;
@ -20,134 +25,80 @@ var WechatWebInstance = /** @class */ (function () {
this.refreshAccessToken(); this.refreshAccessToken();
} }
} }
WechatWebInstance.prototype.getAccessToken = function () { async getAccessToken() {
return tslib_1.__awaiter(this, void 0, void 0, function () { while (true) {
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
if (!true) return [3 /*break*/, 2];
if (this.accessToken) { if (this.accessToken) {
return [2 /*return*/, this.accessToken]; return this.accessToken;
} }
return [4 /*yield*/, new Promise(function (resolve) { return setTimeout(function () { return resolve(0); }, 500); })]; await new Promise((resolve) => setTimeout(() => resolve(0), 500));
case 1:
_a.sent();
return [3 /*break*/, 0];
case 2: return [2 /*return*/];
} }
}); }
}); async access(url, mockData, init) {
};
WechatWebInstance.prototype.access = function (url, mockData, init) {
return tslib_1.__awaiter(this, void 0, void 0, function () {
var response, headers, status, contentType, json, data;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
if (process.env.NODE_ENV === 'development') { if (process.env.NODE_ENV === 'development') {
return [2 /*return*/, mockData]; return mockData;
} }
return [4 /*yield*/, global.fetch(url, init)]; const response = await global.fetch(url, init);
case 1: const { headers, status } = response;
response = _a.sent();
headers = response.headers, status = response.status;
if (![200, 201].includes(status)) { if (![200, 201].includes(status)) {
throw new Error("\u5FAE\u4FE1\u670D\u52A1\u5668\u8FD4\u56DE\u4E0D\u6B63\u786E\u5E94\u7B54\uFF1A".concat(status)); throw new Error(`微信服务器返回不正确应答:${status}`);
} }
contentType = headers['Content-Type'] || headers.get('Content-Type'); const contentType = headers['Content-Type'] || headers.get('Content-Type');
if (!contentType.includes('application/json')) return [3 /*break*/, 3]; if (contentType.includes('application/json')) {
return [4 /*yield*/, response.json()]; const json = await response.json();
case 2:
json = _a.sent();
if (typeof json.errcode === 'number' && json.errcode !== 0) { if (typeof json.errcode === 'number' && json.errcode !== 0) {
if ([40001, 42001].includes(json.errcode)) { if ([40001, 42001].includes(json.errcode)) {
return [2 /*return*/, this.refreshAccessToken()]; return this.refreshAccessToken();
} }
throw new Error("\u8C03\u7528\u5FAE\u4FE1\u63A5\u53E3\u8FD4\u56DE\u51FA\u9519\uFF0Ccode\u662F".concat(json.errcode, "\uFF0C\u4FE1\u606F\u662F").concat(json.errmsg)); throw new Error(`调用微信接口返回出错code是${json.errcode},信息是${json.errmsg}`);
} }
return [2 /*return*/, json]; return json;
case 3: }
if (!(contentType.includes('text') || if (contentType.includes('text') ||
contentType.includes('xml') || contentType.includes('xml') ||
contentType.includes('html'))) return [3 /*break*/, 5]; contentType.includes('html')) {
return [4 /*yield*/, response.text()]; const data = await response.text();
case 4: return data;
data = _a.sent();
return [2 /*return*/, data];
case 5:
if (!contentType.includes('application/octet-stream')) return [3 /*break*/, 7];
return [4 /*yield*/, response.arrayBuffer()];
case 6: return [2 /*return*/, _a.sent()];
case 7: return [2 /*return*/, response];
} }
}); if (contentType.includes('application/octet-stream')) {
}); return await response.arrayBuffer();
}; }
WechatWebInstance.prototype.code2Session = function (code) { return response;
return tslib_1.__awaiter(this, void 0, void 0, function () { }
var result, _a, session_key, openid, unionid; async code2Session(code) {
return tslib_1.__generator(this, function (_b) { const result = await this.access(`https://api.weixin.qq.com/sns/oauth2/access_token?appid=${this.appId}&secret=${this.appSecret}&code=${code}&grant_type=authorization_code`, { session_key: 'aaa', openid: code, unionid: code });
switch (_b.label) { const { session_key, openid, unionid } = typeof result === 'string' ? JSON.parse(result) : result; // 这里微信返回的数据有时候竟然是text/plain
case 0: return [4 /*yield*/, this.access("https://api.weixin.qq.com/sns/oauth2/access_token?appid=".concat(this.appId, "&secret=").concat(this.appSecret, "&code=").concat(code, "&grant_type=authorization_code"), { session_key: 'aaa', openid: code, unionid: code })]; return {
case 1:
result = _b.sent();
_a = typeof result === 'string' ? JSON.parse(result) : result, session_key = _a.session_key, openid = _a.openid, unionid = _a.unionid;
return [2 /*return*/, {
sessionKey: session_key, sessionKey: session_key,
openId: openid, openId: openid,
unionId: unionid, unionId: unionid,
}];
}
});
});
}; };
WechatWebInstance.prototype.refreshAccessToken = function (url, init) { }
return tslib_1.__awaiter(this, void 0, void 0, function () { async refreshAccessToken(url, init) {
var result, _a, access_token, expires_in; const result = this.externalRefreshFn ? await this.externalRefreshFn(this.appId) : await this.access(`https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=${this.appId}&secret=${this.appSecret}`, { access_token: 'mockToken', expires_in: 600 });
var _this = this; const { access_token, expires_in } = result;
return tslib_1.__generator(this, function (_b) {
switch (_b.label) {
case 0:
if (!this.externalRefreshFn) return [3 /*break*/, 2];
return [4 /*yield*/, this.externalRefreshFn(this.appId)];
case 1:
_a = _b.sent();
return [3 /*break*/, 4];
case 2: return [4 /*yield*/, this.access("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=".concat(this.appId, "&secret=").concat(this.appSecret), { access_token: 'mockToken', expires_in: 600 })];
case 3:
_a = _b.sent();
_b.label = 4;
case 4:
result = _a;
access_token = result.access_token, expires_in = result.expires_in;
this.accessToken = access_token; this.accessToken = access_token;
// 生成下次刷新的定时器 // 生成下次刷新的定时器
this.refreshAccessTokenHandler = setTimeout(function () { this.refreshAccessTokenHandler = setTimeout(() => {
_this.refreshAccessToken(); this.refreshAccessToken();
}, (expires_in - 10) * 1000); }, (expires_in - 10) * 1000);
if (url) { if (url) {
return [2 /*return*/, this.access(url, init)]; return this.access(url, init);
} }
return [2 /*return*/];
} }
}); decryptData(sessionKey, encryptedData, iv, signature) {
}); const skBuf = buffer_1.Buffer.from(sessionKey, 'base64');
};
WechatWebInstance.prototype.decryptData = function (sessionKey, encryptedData, iv, signature) {
var skBuf = buffer_1.Buffer.from(sessionKey, 'base64');
// const edBuf = Buffer.from(encryptedData, 'base64'); // const edBuf = Buffer.from(encryptedData, 'base64');
var ivBuf = buffer_1.Buffer.from(iv, 'base64'); const ivBuf = buffer_1.Buffer.from(iv, 'base64');
var decipher = crypto_1.default.createDecipheriv('aes-128-cbc', skBuf, ivBuf); const decipher = crypto_1.default.createDecipheriv('aes-128-cbc', skBuf, ivBuf);
// 设置自动 padding 为 true删除填充补位 // 设置自动 padding 为 true删除填充补位
decipher.setAutoPadding(true); decipher.setAutoPadding(true);
var decoded = decipher.update(encryptedData, 'base64', 'utf8'); let decoded = decipher.update(encryptedData, 'base64', 'utf8');
decoded += decipher.final('utf8'); decoded += decipher.final('utf8');
var data = JSON.parse(decoded); const data = JSON.parse(decoded);
if (data.watermark.appid !== this.appId) { if (data.watermark.appid !== this.appId) {
throw new Error('Illegal Buffer'); throw new Error('Illegal Buffer');
} }
return data; return data;
}; }
return WechatWebInstance; }
}());
exports.WechatWebInstance = WechatWebInstance; exports.WechatWebInstance = WechatWebInstance;

View File

@ -1,4 +1,4 @@
"use strict"; "use strict";
Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "__esModule", { value: true });
var tslib_1 = require("tslib"); const tslib_1 = require("tslib");
tslib_1.__exportStar(require("./Wechat"), exports); tslib_1.__exportStar(require("./Wechat"), exports);

View File

@ -1,5 +1,5 @@
"use strict"; "use strict";
Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "__esModule", { value: true });
exports.load = void 0; exports.load = void 0;
var cheerio_1 = require("cheerio"); const cheerio_1 = require("cheerio");
Object.defineProperty(exports, "load", { enumerable: true, get: function () { return cheerio_1.load; } }); Object.defineProperty(exports, "load", { enumerable: true, get: function () { return cheerio_1.load; } });

View File

@ -1,5 +1,5 @@
"use strict"; "use strict";
Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "__esModule", { value: true });
exports.load = void 0; exports.load = void 0;
var cheerio_1 = require("cheerio"); const cheerio_1 = require("cheerio");
Object.defineProperty(exports, "load", { enumerable: true, get: function () { return cheerio_1.load; } }); Object.defineProperty(exports, "load", { enumerable: true, get: function () { return cheerio_1.load; } });

View File

@ -19,7 +19,7 @@
}, },
"license": "ISC", "license": "ISC",
"devDependencies": { "devDependencies": {
"@types/node": "^20.6.0", "@types/node": "^20.6.1",
"ts-node": "^10.9.1", "ts-node": "^10.9.1",
"tslib": "^2.4.0", "tslib": "^2.4.0",
"typescript": "^5.2.2" "typescript": "^5.2.2"

View File

@ -1,7 +1,7 @@
require('../../fetch'); require('../../fetch');
import crypto from 'crypto'; import crypto from 'crypto';
import { Buffer } from 'buffer'; import { Buffer } from 'buffer';
import URL from 'url';
// 目前先支持text和news, 其他type文档https://developers.weixin.qq.com/doc/offiaccount/Message_Management/Service_Center_messages.html // 目前先支持text和news, 其他type文档https://developers.weixin.qq.com/doc/offiaccount/Message_Management/Service_Center_messages.html
// type ServeMessageType = 'text' | 'news' | 'mpnews' | 'mpnewsarticle' | 'image' | 'voice' | 'video' | 'music' | 'msgmenu';/ // type ServeMessageType = 'text' | 'news' | 'mpnews' | 'mpnewsarticle' | 'image' | 'voice' | 'video' | 'music' | 'msgmenu';/
type TextServeMessageOption = { type TextServeMessageOption = {
@ -72,10 +72,10 @@ export class WechatPublicInstance {
private async access( private async access(
url: string, url: string,
mockData: any, mockData?: any,
init?: RequestInit init?: RequestInit
): Promise<any> { ): Promise<any> {
if (process.env.NODE_ENV === 'development') { if (process.env.NODE_ENV === 'development' && mockData) {
return mockData; return mockData;
} }
const response = await global.fetch(url, init); const response = await global.fetch(url, init);
@ -116,15 +116,15 @@ export class WechatPublicInstance {
async code2Session(code: string) { async code2Session(code: string) {
const result = await this.access( const result = await this.access(
`https://api.weixin.qq.com/sns/oauth2/access_token?appid=${this.appId}&secret=${this.appSecret}&code=${code}&grant_type=authorization_code`, `https://api.weixin.qq.com/sns/oauth2/access_token?appid=${this.appId}&secret=${this.appSecret}&code=${code}&grant_type=authorization_code`,
{ // {
access_token: 'aaa', // access_token: 'aaa',
openid: code, // openid: code,
unionid: code, // unionid: code,
refresh_token: 'aaa', // refresh_token: 'aaa',
is_snapshotuser: false, // is_snapshotuser: false,
expires_in: 30, // expires_in: 30,
scope: 'userinfo', // scope: 'userinfo',
} // }
); );
const { const {
access_token, access_token,
@ -151,12 +151,12 @@ export class WechatPublicInstance {
async refreshUserAccessToken(refreshToken: string) { async refreshUserAccessToken(refreshToken: string) {
const result = await this.access( const result = await this.access(
`https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=${this.appId}&grant_type=refresh_token&refresh_token=${refreshToken}`, `https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=${this.appId}&grant_type=refresh_token&refresh_token=${refreshToken}`,
{ // {
access_token: 'aaa', // access_token: 'aaa',
refresh_token: 'aaa', // refresh_token: 'aaa',
expires_in: 30, // expires_in: 30,
scope: 'userinfo', // scope: 'userinfo',
} // }
); );
const { access_token, refresh_token, expires_in, scope } = result; const { access_token, refresh_token, expires_in, scope } = result;
return { return {
@ -170,12 +170,12 @@ export class WechatPublicInstance {
async getUserInfo(accessToken: string, openId: string) { async getUserInfo(accessToken: string, openId: string) {
const result = await this.access( const result = await this.access(
`https://api.weixin.qq.com/sns/userinfo?access_token=${accessToken}&openid=${openId}&lang=zh_CN`, `https://api.weixin.qq.com/sns/userinfo?access_token=${accessToken}&openid=${openId}&lang=zh_CN`,
{ // {
nickname: '码农哥', // nickname: '码农哥',
sex: 1, // sex: 1,
headimgurl: // headimgurl:
'https://www.ertongzy.com/uploads/allimg/161005/2021233Y7-0.jpg', // 'https://www.ertongzy.com/uploads/allimg/161005/2021233Y7-0.jpg',
} // }
); );
const { nickname, sex, headimgurl } = result; const { nickname, sex, headimgurl } = result;
return { return {
@ -185,12 +185,127 @@ export class WechatPublicInstance {
}; };
} }
async getTags() {
const myInit = {
method: 'GET',
headers: {
'Content-Type': 'application/json',
},
};
const token = await this.getAccessToken();
const result = await this.access(
`https://api.weixin.qq.com/cgi-bin/tags/get?access_token=${token}`,
undefined,
myInit
)
return result;
}
async getCurrentMenu() {
const myInit = {
method: 'GET',
headers: {
'Content-Type': 'application/json',
},
};
const token = await this.getAccessToken();
const result = await this.access(
`https://api.weixin.qq.com/cgi-bin/get_current_selfmenu_info?access_token=${token}`,
undefined,
myInit
)
return result;
}
async getMenu() {
const myInit = {
method: 'GET',
headers: {
'Content-Type': 'application/json',
},
};
const token = await this.getAccessToken();
const result = await this.access(
`https://api.weixin.qq.com/cgi-bin/menu/get?access_token=${token}`,
undefined,
myInit
)
return result;
}
async createMenu(menuConfig: any) {
const myInit = {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(menuConfig),
};
const token = await this.getAccessToken();
const result = await this.access(
`https://api.weixin.qq.com/cgi-bin/menu/create?access_token=${token}`,
undefined,
myInit
);
const { errcode } = result;
if (errcode === 0) {
return Object.assign({ success: true }, result);
}
return Object.assign({ success: false }, result);
}
async createConditionalMenu(menuConfig: any) {
const myInit = {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(menuConfig),
};
const token = await this.getAccessToken();
const result = await this.access(
`https://api.weixin.qq.com/cgi-bin/menu/addconditional?access_token=${token}`,
undefined,
myInit
);
const { errcode } = result;
if (errcode === 0) {
return Object.assign({ success: true }, result);
}
return Object.assign({ success: false }, result);
}
async deleteConditionalMenu(menuid: number) {
const myInit = {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
menuid
}),
};
const token = await this.getAccessToken();
const result = await this.access(
`https://api.weixin.qq.com/cgi-bin/menu/delconditional?access_token=${token}`,
undefined,
myInit
);
const { errcode } = result;
if (errcode === 0) {
return Object.assign({ success: true }, result);
}
return Object.assign({ success: false }, result);
}
private async refreshAccessToken(url?: string, init?: RequestInit) { private async refreshAccessToken(url?: string, init?: RequestInit) {
const result = this.externalRefreshFn const result = this.externalRefreshFn
? await this.externalRefreshFn(this.appId) ? await this.externalRefreshFn(this.appId)
: await this.access( : await this.access(
`https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=${this.appId}&secret=${this.appSecret}`, `https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=${this.appId}&secret=${this.appSecret}`,
{ access_token: 'mockToken', expires_in: 600 } //{ access_token: 'mockToken', expires_in: 600 }
); );
const { access_token, expires_in } = result; const { access_token, expires_in } = result;
this.accessToken = access_token; this.accessToken = access_token;
@ -200,7 +315,10 @@ export class WechatPublicInstance {
this.refreshAccessToken(); this.refreshAccessToken();
}, (expires_in - 10) * 1000); }, (expires_in - 10) * 1000);
if (url) { if (url) {
return this.access(url, {}, init); const url2= new URL.URL(url);
url2.searchParams.set('access_token', access_token)
return this.access(url2.toString(), {}, init);
} }
} }
@ -278,11 +396,11 @@ export class WechatPublicInstance {
const token = await this.getAccessToken(); const token = await this.getAccessToken();
const result = await this.access( const result = await this.access(
`https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=${token}`, `https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=${token}`,
{ // {
ticket: `ticket${Date.now()}`, // ticket: `ticket${Date.now()}`,
url: `http://mock/q/${sceneId ? sceneId : sceneStr}`, // url: `http://mock/q/${sceneId ? sceneId : sceneStr}`,
expireSeconds: expireSeconds, // expireSeconds: expireSeconds,
}, // },
myInit myInit
); );
@ -322,11 +440,11 @@ export class WechatPublicInstance {
const token = await this.getAccessToken(); const token = await this.getAccessToken();
const result = await this.access( const result = await this.access(
`https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=${token}`, `https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=${token}`,
{ // {
errcode: 0, // errcode: 0,
errmsg: 'ok', // errmsg: 'ok',
msgid: Date.now(), // msgid: Date.now(),
}, // },
myInit myInit
); );
const { errcode } = result; const { errcode } = result;
@ -397,10 +515,10 @@ export class WechatPublicInstance {
const token = await this.getAccessToken(); const token = await this.getAccessToken();
const result = await this.access( const result = await this.access(
`https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=${token}`, `https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=${token}`,
{ // {
errcode: 0, // errcode: 0,
errmsg: 'ok', // errmsg: 'ok',
}, // },
myInit myInit
); );
const { errcode } = result; const { errcode } = result;
@ -429,33 +547,7 @@ export class WechatPublicInstance {
const token = await this.getAccessToken(); const token = await this.getAccessToken();
const result = await this.access( const result = await this.access(
`https://api.weixin.qq.com/cgi-bin/freepublish/batchget?access_token=${token}`, `https://api.weixin.qq.com/cgi-bin/freepublish/batchget?access_token=${token}`,
{ undefined,
total_count: 1,
item_count: 1,
item: [
{
article_id: 'test',
content: {
news_item: [
{
title: '测试文章',
author: '测试作者',
digest: '测试摘要',
content: '测试内容',
content_source_url: '',
thumb_media_id: 'TEST_MEDIA_ID',
show_cover_pic: 1,
need_open_comment: 0,
only_fans_can_comment: 0,
url: 'TEST_ARTICLE_URL',
is_deleted: false,
},
],
},
update_time: Date.now(),
},
],
},
myInit myInit
); );
const { errcode } = result; const { errcode } = result;
@ -465,6 +557,132 @@ export class WechatPublicInstance {
throw new Error(JSON.stringify(result)); throw new Error(JSON.stringify(result));
} }
async getArticle(options: {
article_id: string,
}) {
const { article_id } = options;
const myInit = {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
article_id,
}),
};
const token = await this.getAccessToken();
const result = await this.access(
`https://api.weixin.qq.com/cgi-bin/freepublish/getarticle?access_token=${token}`,
undefined,
myInit
);
const { errcode } = result;
if (!errcode) {
return result;
}
throw new Error(JSON.stringify(result));
}
async createMaterial(options: {
type: 'image' | 'voice' | 'video' | 'thumb',
media: FormData,
description?: FormData
}) {
const { type, media, description } = options;
const myInit = {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
};
if (type === 'video') {
Object.assign(myInit, {
body: JSON.stringify({
type,
media,
description,
}),
});
} else {
Object.assign(myInit, {
body: JSON.stringify({
type,
media,
}),
});
};
const token = await this.getAccessToken();
const result = await this.access(
`https://api.weixin.qq.com/cgi-bin/material/add_material?access_token=${token}`,
undefined,
myInit,
);
const { errcode } = result;
if (!errcode) {
return result;
}
throw new Error(JSON.stringify(result));
}
async batchGetMaterialList(options: {
type: 'image' | 'video' | 'voice' | 'news',
offset?: number;
count: number;
}) {
const { offset, count, type } = options;
const myInit = {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
type,
offset,
count,
}),
};
const token = await this.getAccessToken();
const result = await this.access(
`https://api.weixin.qq.com/cgi-bin/material/batchget_material?access_token=${token}`,
undefined,
myInit
);
const { errcode } = result;
if (!errcode) {
return result;
}
throw new Error(JSON.stringify(result));
}
async getMaterial(options: {
type: 'image' | 'video' | 'voice' | 'news',
media_id: string,
}) {
const { type, media_id } = options;
const myInit = {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
media_id
}),
};
let imgFile;
const token = await this.getAccessToken();
const result = await this.access(
`https://api.weixin.qq.com/cgi-bin/material/get_material?access_token=${token}`,
undefined,
myInit
);
if ('errcode' in result) {
throw new Error(JSON.stringify(result));
} else {
return result;
}
}
async getTicket() { async getTicket() {
const myInit = { const myInit = {
method: 'GET', method: 'GET',
@ -475,10 +693,10 @@ export class WechatPublicInstance {
const token = await this.getAccessToken(); const token = await this.getAccessToken();
const result = (await this.access( const result = (await this.access(
`https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=${token}&type=jsapi`, `https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=${token}&type=jsapi`,
{ // {
ticket: `ticket${Date.now()}`, // ticket: `ticket${Date.now()}`,
expires_in: 30, // expires_in: 30,
}, // },
myInit myInit
)) as { )) as {
ticket: string; ticket: string;

View File

@ -3,7 +3,7 @@
"jsx": "preserve", "jsx": "preserve",
/* Basic Options */ /* Basic Options */
// "incremental": true, /* Enable incremental compilation */ // "incremental": true, /* Enable incremental compilation */
"target": "ES5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */ "target": "ESNext", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */
"module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */
"lib": [ "lib": [
"dom", "dom",