公众号 生成二维码接口
This commit is contained in:
parent
f5bf7329d2
commit
4a26e1df1e
|
|
@ -12,4 +12,14 @@ export declare class WechatPublicInstance {
|
|||
}>;
|
||||
private refreshAccessToken;
|
||||
decryptData(sessionKey: string, encryptedData: string, iv: string, signature: string): any;
|
||||
getQrCode(options: {
|
||||
sceneId?: number;
|
||||
sceneStr?: string;
|
||||
expireSeconds?: number;
|
||||
isPermanent?: boolean;
|
||||
}): Promise<{
|
||||
ticket: any;
|
||||
url: any;
|
||||
expireSeconds: any;
|
||||
}>;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,9 +36,9 @@ var WechatPublicInstance = /** @class */ (function () {
|
|||
}
|
||||
return [2 /*return*/, json];
|
||||
case 3:
|
||||
if (!(contentType.includes('text')
|
||||
|| contentType.includes('xml')
|
||||
|| contentType.includes('html'))) return [3 /*break*/, 5];
|
||||
if (!(contentType.includes('text') ||
|
||||
contentType.includes('xml') ||
|
||||
contentType.includes('html'))) return [3 /*break*/, 5];
|
||||
return [4 /*yield*/, response.text()];
|
||||
case 4:
|
||||
data = _a.sent();
|
||||
|
|
@ -105,6 +105,64 @@ var WechatPublicInstance = /** @class */ (function () {
|
|||
}
|
||||
return data;
|
||||
};
|
||||
WechatPublicInstance.prototype.getQrCode = function (options) {
|
||||
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
||||
var sceneId, sceneStr, expireSeconds, isPermanent, scene, actionName, myInit, 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) {
|
||||
throw new Error('Missing sceneId or sceneStr');
|
||||
}
|
||||
scene = sceneId
|
||||
? {
|
||||
scene_id: sceneId,
|
||||
}
|
||||
: {
|
||||
scene_str: sceneStr,
|
||||
};
|
||||
actionName = sceneId ? 'QR_SCENE' : 'QR_STR_SCENE';
|
||||
myInit = {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
expire_seconds: expireSeconds,
|
||||
action_name: actionName,
|
||||
action_info: {
|
||||
scene: scene,
|
||||
},
|
||||
}),
|
||||
};
|
||||
if (isPermanent) {
|
||||
actionName = sceneId ? 'QR_LIMIT_SCENE' : 'QR_LIMIT_STR_SCENE';
|
||||
myInit = {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
action_name: actionName,
|
||||
action_info: {
|
||||
scene: scene,
|
||||
},
|
||||
}),
|
||||
};
|
||||
}
|
||||
return [4 /*yield*/, this.access("https://api.weixin.qq.com/cgi-bin/qrcode/create??access_token=".concat(this.accessToken), myInit)];
|
||||
case 1:
|
||||
result = _a.sent();
|
||||
return [2 /*return*/, {
|
||||
ticket: result.ticket,
|
||||
url: result.url,
|
||||
expireSeconds: result.expire_seconds,
|
||||
}];
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
return WechatPublicInstance;
|
||||
}());
|
||||
exports.WechatPublicInstance = WechatPublicInstance;
|
||||
|
|
|
|||
|
|
@ -20,23 +20,26 @@ export class WechatPublicInstance {
|
|||
return mockData;
|
||||
}
|
||||
const response = await global.fetch(url, init);
|
||||
|
||||
|
||||
const { headers, status } = response;
|
||||
if (![200, 201].includes(status)) {
|
||||
throw new Error(`微信服务器返回不正确应答:${status}`);
|
||||
}
|
||||
const contentType = (headers as any)['Content-Type'] || headers.get('Content-Type')!;
|
||||
const contentType =
|
||||
(headers as any)['Content-Type'] || headers.get('Content-Type')!;
|
||||
if (contentType.includes('application/json')) {
|
||||
const json = await response.json();
|
||||
if (typeof json.errcode === 'number' && json.errcode !== 0) {
|
||||
throw new Error(`调用微信接口返回出错,code是${json.errcode},信息是${json.errmsg}`);
|
||||
throw new Error(
|
||||
`调用微信接口返回出错,code是${json.errcode},信息是${json.errmsg}`
|
||||
);
|
||||
}
|
||||
return json;
|
||||
}
|
||||
if (
|
||||
contentType.includes('text')
|
||||
|| contentType.includes('xml')
|
||||
|| contentType.includes('html')
|
||||
contentType.includes('text') ||
|
||||
contentType.includes('xml') ||
|
||||
contentType.includes('html')
|
||||
) {
|
||||
const data = await response.text();
|
||||
return data;
|
||||
|
|
@ -48,12 +51,13 @@ export class WechatPublicInstance {
|
|||
return response;
|
||||
}
|
||||
|
||||
async code2Session(code: string) {
|
||||
async code2Session(code: string) {
|
||||
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 }
|
||||
);
|
||||
const { session_key, openid, unionid } = typeof result === 'string' ? JSON.parse(result) : result; // 这里微信返回的数据有时候竟然是text/plain
|
||||
const { session_key, openid, unionid } =
|
||||
typeof result === 'string' ? JSON.parse(result) : result; // 这里微信返回的数据有时候竟然是text/plain
|
||||
|
||||
return {
|
||||
sessionKey: session_key as string,
|
||||
|
|
@ -75,19 +79,22 @@ export class WechatPublicInstance {
|
|||
}, (expires_in - 10) * 1000);
|
||||
}
|
||||
|
||||
|
||||
decryptData(sessionKey: string, encryptedData: string, iv: string, signature: string) {
|
||||
decryptData(
|
||||
sessionKey: string,
|
||||
encryptedData: string,
|
||||
iv: string,
|
||||
signature: string
|
||||
) {
|
||||
const skBuf = Buffer.from(sessionKey, 'base64');
|
||||
// const edBuf = Buffer.from(encryptedData, 'base64');
|
||||
const ivBuf = Buffer.from(iv, 'base64');
|
||||
|
||||
|
||||
const decipher = crypto.createDecipheriv('aes-128-cbc', skBuf, ivBuf);
|
||||
// 设置自动 padding 为 true,删除填充补位
|
||||
decipher.setAutoPadding(true);
|
||||
let decoded = decipher.update(encryptedData, 'base64', 'utf8');
|
||||
decoded += decipher.final('utf8');
|
||||
|
||||
|
||||
const data = JSON.parse(decoded);
|
||||
|
||||
if (data.watermark.appid !== this.appId) {
|
||||
|
|
@ -96,4 +103,63 @@ export class WechatPublicInstance {
|
|||
|
||||
return data;
|
||||
}
|
||||
|
||||
async getQrCode(options: {
|
||||
sceneId?: number;
|
||||
sceneStr?: string;
|
||||
expireSeconds?: number;
|
||||
isPermanent?: boolean;
|
||||
}) {
|
||||
const { sceneId, sceneStr, expireSeconds, isPermanent } = options;
|
||||
if (!sceneId && !sceneStr) {
|
||||
throw new Error('Missing sceneId or sceneStr');
|
||||
}
|
||||
const scene = sceneId
|
||||
? {
|
||||
scene_id: sceneId,
|
||||
}
|
||||
: {
|
||||
scene_str: sceneStr,
|
||||
};
|
||||
let actionName = sceneId ? 'QR_SCENE' : 'QR_STR_SCENE';
|
||||
let myInit = {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
expire_seconds: expireSeconds,
|
||||
action_name: actionName,
|
||||
action_info: {
|
||||
scene,
|
||||
},
|
||||
}),
|
||||
};
|
||||
if (isPermanent) {
|
||||
actionName = sceneId ? 'QR_LIMIT_SCENE' : 'QR_LIMIT_STR_SCENE';
|
||||
myInit = {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
action_name: actionName,
|
||||
action_info: {
|
||||
scene,
|
||||
},
|
||||
}),
|
||||
};
|
||||
}
|
||||
|
||||
const result = await this.access(
|
||||
`https://api.weixin.qq.com/cgi-bin/qrcode/create??access_token=${this.accessToken}`,
|
||||
myInit
|
||||
);
|
||||
|
||||
return {
|
||||
ticket: result.ticket,
|
||||
url: result.url,
|
||||
expireSeconds: result.expire_seconds,
|
||||
};
|
||||
}
|
||||
};
|
||||
Loading…
Reference in New Issue