@zhin.js/adapter-wechat-mp 1.0.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +478 -0
- package/README.md +40 -88
- package/adapters/wechat-mp.js +32 -0
- package/adapters/wechat-mp.ts +38 -0
- package/commands/endpoint/add/[id].js +3 -0
- package/commands/endpoint/add/[id].ts +3 -0
- package/commands/endpoint/list.js +3 -0
- package/commands/endpoint/list.ts +3 -0
- package/commands/endpoint/remove/[id].js +3 -0
- package/commands/endpoint/remove/[id].ts +3 -0
- package/lib/client.d.ts +32 -0
- package/lib/client.js +70 -0
- package/lib/endpoint.d.ts +32 -0
- package/lib/endpoint.js +264 -0
- package/lib/index.d.ts +6 -15
- package/lib/index.js +6 -25
- package/lib/media-upload.d.ts +22 -0
- package/lib/media-upload.js +64 -0
- package/lib/passive-reply.d.ts +0 -1
- package/lib/passive-reply.js +0 -1
- package/lib/protocol.d.ts +129 -0
- package/lib/protocol.js +349 -0
- package/lib/side-event-dispatch.d.ts +4 -0
- package/lib/side-event-dispatch.js +38 -0
- package/lib/webhook.d.ts +20 -0
- package/lib/webhook.js +152 -0
- package/lib/wechat-mp-endpoint-commands.d.ts +1 -0
- package/lib/wechat-mp-endpoint-commands.js +19 -0
- package/lib/wechat-mp-runtime-state.d.ts +1 -0
- package/lib/wechat-mp-runtime-state.js +6 -0
- package/package.json +53 -12
- package/plugin.js +14 -0
- package/schema.json +116 -0
- package/src/client.ts +121 -0
- package/src/endpoint.ts +313 -0
- package/src/index.ts +56 -35
- package/src/media-upload.ts +82 -0
- package/src/protocol.ts +507 -0
- package/src/side-event-dispatch.ts +45 -0
- package/src/webhook.ts +237 -0
- package/src/wechat-mp-endpoint-commands.ts +20 -0
- package/src/wechat-mp-runtime-state.ts +7 -0
- package/lib/adapter.d.ts +0 -13
- package/lib/adapter.d.ts.map +0 -1
- package/lib/adapter.js +0 -16
- package/lib/adapter.js.map +0 -1
- package/lib/bot.d.ts +0 -73
- package/lib/bot.d.ts.map +0 -1
- package/lib/bot.js +0 -783
- package/lib/bot.js.map +0 -1
- package/lib/index.d.ts.map +0 -1
- package/lib/index.js.map +0 -1
- package/lib/passive-reply.d.ts.map +0 -1
- package/lib/passive-reply.js.map +0 -1
- package/lib/types.d.ts +0 -58
- package/lib/types.d.ts.map +0 -1
- package/lib/types.js +0 -2
- package/lib/types.js.map +0 -1
- package/src/adapter.ts +0 -20
- package/src/bot.ts +0 -934
- package/src/types.ts +0 -60
- /package/{skills/wechat-mp/SKILL.md → agent/skills/wechat-mp.md} +0 -0
package/src/webhook.ts
ADDED
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WeChat MP webhook HTTP: URL verification + inbound message handling.
|
|
3
|
+
*/
|
|
4
|
+
import type { IncomingMessage, ServerResponse } from 'node:http';
|
|
5
|
+
import type { HttpHost, HttpRouteRegistration } from '@zhin.js/host-http';
|
|
6
|
+
import { formatCompact, getLogger } from '@zhin.js/logger';
|
|
7
|
+
import type { CapabilityId } from 'zhin.js';
|
|
8
|
+
import {
|
|
9
|
+
getPassiveReplyCapture,
|
|
10
|
+
runWithPassiveReplyCapture,
|
|
11
|
+
} from './passive-reply.js';
|
|
12
|
+
import {
|
|
13
|
+
buildTextReply,
|
|
14
|
+
computeSignatureHash,
|
|
15
|
+
decryptEchostr,
|
|
16
|
+
decryptMessage,
|
|
17
|
+
encryptMessage,
|
|
18
|
+
formatInboundContent,
|
|
19
|
+
formatInboundId,
|
|
20
|
+
isEncryptedEchostr,
|
|
21
|
+
normalizeEchostrParam,
|
|
22
|
+
parseXMLMessage,
|
|
23
|
+
queryParam,
|
|
24
|
+
readTextBody,
|
|
25
|
+
resolveEventPassiveReply,
|
|
26
|
+
verifySignature,
|
|
27
|
+
wechatMpInboundConversation,
|
|
28
|
+
type ResolvedWeChatMpConfig,
|
|
29
|
+
type WeChatMessage,
|
|
30
|
+
} from './protocol.js';
|
|
31
|
+
|
|
32
|
+
const logger = getLogger('wechat-mp');
|
|
33
|
+
|
|
34
|
+
export interface WeChatMpWebhookHandler {
|
|
35
|
+
readonly config: ResolvedWeChatMpConfig;
|
|
36
|
+
readonly isOpen: boolean;
|
|
37
|
+
readonly id: CapabilityId;
|
|
38
|
+
admit(msg: WeChatMessage): void | Promise<unknown>;
|
|
39
|
+
/** MsgId 去重缓存(可选;实现见 WeChatMpEndpoint)。 */
|
|
40
|
+
getCachedReply?(msgId: string): string | undefined;
|
|
41
|
+
cacheReply?(msgId: string, replyXML: string): void;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export function registerWeChatMpWebhookRoutes(
|
|
45
|
+
http: HttpHost,
|
|
46
|
+
handler: WeChatMpWebhookHandler,
|
|
47
|
+
): HttpRouteRegistration[] {
|
|
48
|
+
const path = handler.config.path;
|
|
49
|
+
return [
|
|
50
|
+
http.route('GET', path, (request, response, url) => {
|
|
51
|
+
handleWeChatMpVerification(request, response, url, handler.config);
|
|
52
|
+
}, { summary: 'WeChat MP URL verification', tags: ['wechat-mp'] }),
|
|
53
|
+
http.route('POST', path, async (request, response, url) => {
|
|
54
|
+
await handleWeChatMpMessage(request, response, url, handler);
|
|
55
|
+
}, { summary: 'WeChat MP inbound webhook', tags: ['wechat-mp'] }),
|
|
56
|
+
];
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export function handleWeChatMpVerification(
|
|
60
|
+
_request: IncomingMessage,
|
|
61
|
+
response: ServerResponse,
|
|
62
|
+
url: URL,
|
|
63
|
+
config: ResolvedWeChatMpConfig,
|
|
64
|
+
): void {
|
|
65
|
+
const signature = queryParam(url.searchParams.get('signature'));
|
|
66
|
+
const msgSignature = queryParam(url.searchParams.get('msg_signature'));
|
|
67
|
+
const timestamp = queryParam(url.searchParams.get('timestamp'));
|
|
68
|
+
const nonce = queryParam(url.searchParams.get('nonce'));
|
|
69
|
+
const echostr = normalizeEchostrParam(queryParam(url.searchParams.get('echostr')));
|
|
70
|
+
const secureMode = !!(config.encrypt && config.encodingAESKey);
|
|
71
|
+
const signToCheck = msgSignature || signature;
|
|
72
|
+
const signPayload = msgSignature
|
|
73
|
+
? { signature: msgSignature, timestamp, nonce, echostr }
|
|
74
|
+
: { signature, timestamp, nonce };
|
|
75
|
+
|
|
76
|
+
if (!signToCheck || !timestamp || !nonce) {
|
|
77
|
+
response.writeHead(403, { 'Content-Type': 'text/plain' });
|
|
78
|
+
response.end('Forbidden');
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
if (!verifySignature(config.token, signPayload)) {
|
|
83
|
+
const expected = computeSignatureHash(config.token, {
|
|
84
|
+
timestamp,
|
|
85
|
+
nonce,
|
|
86
|
+
...(msgSignature ? { echostr } : {}),
|
|
87
|
+
});
|
|
88
|
+
logger.error(formatCompact({
|
|
89
|
+
op: 'verify',
|
|
90
|
+
stage: 'sign',
|
|
91
|
+
ok: false,
|
|
92
|
+
expectedPrefix: expected.slice(0, 8),
|
|
93
|
+
gotPrefix: signToCheck.slice(0, 8),
|
|
94
|
+
}));
|
|
95
|
+
response.writeHead(403, { 'Content-Type': 'text/plain' });
|
|
96
|
+
response.end('Forbidden');
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
let body = echostr;
|
|
101
|
+
if (secureMode && echostr && isEncryptedEchostr(echostr) && config.encodingAESKey) {
|
|
102
|
+
try {
|
|
103
|
+
body = decryptEchostr(echostr, config.encodingAESKey, config.appId);
|
|
104
|
+
} catch (error) {
|
|
105
|
+
logger.error(formatCompact({
|
|
106
|
+
op: 'verify',
|
|
107
|
+
stage: 'decrypt',
|
|
108
|
+
ok: false,
|
|
109
|
+
error: error instanceof Error ? error.message : String(error),
|
|
110
|
+
}));
|
|
111
|
+
response.writeHead(403, { 'Content-Type': 'text/plain' });
|
|
112
|
+
response.end('Forbidden');
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
response.writeHead(200, { 'Content-Type': 'text/plain' });
|
|
118
|
+
response.end(body);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
export async function handleWeChatMpMessage(
|
|
122
|
+
request: IncomingMessage,
|
|
123
|
+
response: ServerResponse,
|
|
124
|
+
url: URL,
|
|
125
|
+
handler: WeChatMpWebhookHandler,
|
|
126
|
+
): Promise<void> {
|
|
127
|
+
try {
|
|
128
|
+
const config = handler.config;
|
|
129
|
+
const signature = queryParam(url.searchParams.get('signature'));
|
|
130
|
+
const timestamp = queryParam(url.searchParams.get('timestamp'));
|
|
131
|
+
const nonce = queryParam(url.searchParams.get('nonce'));
|
|
132
|
+
const msgSignature = queryParam(url.searchParams.get('msg_signature'));
|
|
133
|
+
const encryptType = queryParam(url.searchParams.get('encrypt_type'));
|
|
134
|
+
|
|
135
|
+
if (!verifySignature(config.token, { signature, timestamp, nonce })) {
|
|
136
|
+
logger.error('Invalid signature');
|
|
137
|
+
response.writeHead(403, { 'Content-Type': 'text/plain' });
|
|
138
|
+
response.end('Forbidden');
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
let xmlString = await readTextBody(request);
|
|
143
|
+
|
|
144
|
+
if (config.encrypt && encryptType === 'aes' && config.encodingAESKey) {
|
|
145
|
+
xmlString = await decryptMessage(
|
|
146
|
+
xmlString,
|
|
147
|
+
msgSignature,
|
|
148
|
+
timestamp,
|
|
149
|
+
nonce,
|
|
150
|
+
config.token,
|
|
151
|
+
config.encodingAESKey,
|
|
152
|
+
config.appId,
|
|
153
|
+
);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
const wechatMessage = await parseXMLMessage(xmlString);
|
|
157
|
+
if (!wechatMessage) {
|
|
158
|
+
response.writeHead(200, { 'Content-Type': 'text/plain' });
|
|
159
|
+
response.end('success');
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// 微信 5s 重推去重:同一 MsgId 直接回放首次回复,避免二次 admit。
|
|
164
|
+
const msgId = wechatMessage.MsgId;
|
|
165
|
+
if (msgId && handler.getCachedReply) {
|
|
166
|
+
const cached = handler.getCachedReply(msgId);
|
|
167
|
+
if (cached !== undefined) {
|
|
168
|
+
logger.debug(formatCompact({ op: 'wechat_mp_dedup_replay', msgId }));
|
|
169
|
+
response.writeHead(200, { 'Content-Type': cached ? 'text/xml' : 'text/plain' });
|
|
170
|
+
response.end(cached || 'success');
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
let replyXML = resolveEventPassiveReply(wechatMessage);
|
|
176
|
+
|
|
177
|
+
if (!replyXML && handler.isOpen) {
|
|
178
|
+
if (config.replyMode === 'passive') {
|
|
179
|
+
replyXML = await collectPassiveReply(handler, wechatMessage);
|
|
180
|
+
} else {
|
|
181
|
+
handler.admit(wechatMessage);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
const encryptReply = !!(
|
|
186
|
+
replyXML
|
|
187
|
+
&& config.encodingAESKey
|
|
188
|
+
&& encryptType === 'aes'
|
|
189
|
+
&& config.encryptMode === 'secure'
|
|
190
|
+
);
|
|
191
|
+
if (encryptReply && config.encodingAESKey) {
|
|
192
|
+
replyXML = encryptMessage(
|
|
193
|
+
replyXML,
|
|
194
|
+
config.token,
|
|
195
|
+
config.encodingAESKey,
|
|
196
|
+
config.appId,
|
|
197
|
+
timestamp,
|
|
198
|
+
);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
if (msgId && handler.cacheReply) {
|
|
202
|
+
handler.cacheReply(msgId, replyXML || '');
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
response.writeHead(200, { 'Content-Type': 'text/xml' });
|
|
206
|
+
response.end(replyXML || 'success');
|
|
207
|
+
} catch (error) {
|
|
208
|
+
logger.error('Error handling WeChat message:', error);
|
|
209
|
+
response.writeHead(200, { 'Content-Type': 'text/plain' });
|
|
210
|
+
response.end('success');
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
export async function collectPassiveReply(
|
|
215
|
+
handler: WeChatMpWebhookHandler,
|
|
216
|
+
wechatMsg: WeChatMessage,
|
|
217
|
+
): Promise<string> {
|
|
218
|
+
const timeoutMs = handler.config.passiveReplyTimeoutMs;
|
|
219
|
+
const text = await runWithPassiveReplyCapture(async () => {
|
|
220
|
+
const conversation = wechatMpInboundConversation(String(handler.id), wechatMsg);
|
|
221
|
+
await Promise.race([
|
|
222
|
+
Promise.resolve(handler.admit(wechatMsg)),
|
|
223
|
+
new Promise<void>((resolve) => setTimeout(resolve, timeoutMs)),
|
|
224
|
+
]);
|
|
225
|
+
return getPassiveReplyCapture()?.text ?? null;
|
|
226
|
+
});
|
|
227
|
+
if (!text) {
|
|
228
|
+
logger.warn(formatCompact({
|
|
229
|
+
op: 'passive_reply',
|
|
230
|
+
ok: false,
|
|
231
|
+
reason: 'timeout_or_empty',
|
|
232
|
+
timeoutMs,
|
|
233
|
+
}));
|
|
234
|
+
return '';
|
|
235
|
+
}
|
|
236
|
+
return buildTextReply(wechatMsg, text);
|
|
237
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `wechat-mp.endpoint` 命令族:由 @zhin.js/adapter 的 createEndpointCommands 套件生成。
|
|
3
|
+
* commands/endpoint/ 下的 list / add / remove 直接默认导出这三项。
|
|
4
|
+
*/
|
|
5
|
+
import { createEndpointCommands } from 'zhin.js/adapter';
|
|
6
|
+
import { defineCommand } from 'zhin.js/command';
|
|
7
|
+
import { wechatMpRuntimeStateToken } from './wechat-mp-runtime-state.js';
|
|
8
|
+
|
|
9
|
+
export const wechatMpEndpointCommands = createEndpointCommands({
|
|
10
|
+
adapterKey: 'wechat-mp',
|
|
11
|
+
adapterDisplayName: 'WeChat MP',
|
|
12
|
+
fields: [
|
|
13
|
+
{ key: 'appId', required: true, env: true, description: '公众号 AppID' },
|
|
14
|
+
{ key: 'appSecret', required: true, env: true, description: '公众号 AppSecret' },
|
|
15
|
+
{ key: 'token', required: true, env: true, description: '服务器配置 token' },
|
|
16
|
+
{ key: 'encodingAESKey', env: true, description: '消息加解密 key' },
|
|
17
|
+
],
|
|
18
|
+
running: (use) => use(wechatMpRuntimeStateToken).endpoints.values(),
|
|
19
|
+
describeEntry: (entry) => `appId: ${String(entry.appId)}`,
|
|
20
|
+
}, defineCommand);
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WeChat MP 插件实例的运行时状态:adapter create() 注册的 endpoint 列表。
|
|
3
|
+
* 由 plugin.ts setup() provide,adapter create 与 `wechat-mp.endpoint` 命令共享(同一 owner generation)。
|
|
4
|
+
*/
|
|
5
|
+
import { defineEndpointRuntimeStateToken } from 'zhin.js/adapter';
|
|
6
|
+
|
|
7
|
+
export const wechatMpRuntimeStateToken = defineEndpointRuntimeStateToken('wechat-mp');
|
package/lib/adapter.d.ts
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 微信公众号适配器
|
|
3
|
-
*/
|
|
4
|
-
import { Adapter, Plugin } from "zhin.js";
|
|
5
|
-
import type { Router } from "@zhin.js/host-router";
|
|
6
|
-
import { WeChatMPBot } from "./bot.js";
|
|
7
|
-
import type { WeChatMPConfig } from "./types.js";
|
|
8
|
-
export declare class WeChatMPAdapter extends Adapter<WeChatMPBot> {
|
|
9
|
-
#private;
|
|
10
|
-
constructor(plugin: Plugin, router: Router);
|
|
11
|
-
createBot(config: WeChatMPConfig): WeChatMPBot;
|
|
12
|
-
}
|
|
13
|
-
//# sourceMappingURL=adapter.d.ts.map
|
package/lib/adapter.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../src/adapter.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAC1C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AACvC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD,qBAAa,eAAgB,SAAQ,OAAO,CAAC,WAAW,CAAC;;gBAGzC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAK1C,SAAS,CAAC,MAAM,EAAE,cAAc,GAAG,WAAW;CAGjD"}
|
package/lib/adapter.js
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 微信公众号适配器
|
|
3
|
-
*/
|
|
4
|
-
import { Adapter } from "zhin.js";
|
|
5
|
-
import { WeChatMPBot } from "./bot.js";
|
|
6
|
-
export class WeChatMPAdapter extends Adapter {
|
|
7
|
-
#router;
|
|
8
|
-
constructor(plugin, router) {
|
|
9
|
-
super(plugin, 'wechat-mp', []);
|
|
10
|
-
this.#router = router;
|
|
11
|
-
}
|
|
12
|
-
createBot(config) {
|
|
13
|
-
return new WeChatMPBot(this, this.#router, config);
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
//# sourceMappingURL=adapter.js.map
|
package/lib/adapter.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"adapter.js","sourceRoot":"","sources":["../src/adapter.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,OAAO,EAAU,MAAM,SAAS,CAAC;AAE1C,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAGvC,MAAM,OAAO,eAAgB,SAAQ,OAAoB;IACrD,OAAO,CAAS;IAEhB,YAAY,MAAc,EAAE,MAAc;QACtC,KAAK,CAAC,MAAM,EAAE,WAAW,EAAE,EAAE,CAAC,CAAC;QAC/B,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC;IAC1B,CAAC;IAED,SAAS,CAAC,MAAsB;QAC5B,OAAO,IAAI,WAAW,CAAC,IAAI,EAAE,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IACvD,CAAC;CACJ"}
|
package/lib/bot.d.ts
DELETED
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
import { EventEmitter } from "events";
|
|
2
|
-
import { Bot, Message, MessageSegment, SendOptions } from 'zhin.js';
|
|
3
|
-
import { type Router } from "@zhin.js/host-router/router";
|
|
4
|
-
import type { WeChatMPConfig, WeChatMessage } from "./types.js";
|
|
5
|
-
import type { WeChatMPAdapter } from "./adapter.js";
|
|
6
|
-
export declare class WeChatMPBot extends EventEmitter implements Bot<WeChatMPConfig, WeChatMessage> {
|
|
7
|
-
adapter: WeChatMPAdapter;
|
|
8
|
-
$config: WeChatMPConfig;
|
|
9
|
-
$connected: boolean;
|
|
10
|
-
router: Router;
|
|
11
|
-
private accessToken;
|
|
12
|
-
private tokenExpireTime;
|
|
13
|
-
get logger(): import("zhin.js").Logger;
|
|
14
|
-
get $id(): string;
|
|
15
|
-
constructor(adapter: WeChatMPAdapter, router: Router, config: WeChatMPConfig);
|
|
16
|
-
private setupRoutes;
|
|
17
|
-
$connect(): Promise<void>;
|
|
18
|
-
$disconnect(): Promise<void>;
|
|
19
|
-
private handleVerification;
|
|
20
|
-
private handleMessage;
|
|
21
|
-
private computeSignatureHash;
|
|
22
|
-
private verifySignature;
|
|
23
|
-
private parseXMLMessage;
|
|
24
|
-
$formatMessage(wechatMsg: WeChatMessage): Message<WeChatMessage>;
|
|
25
|
-
static parseMessageContent(wechatMsg: WeChatMessage): MessageSegment[];
|
|
26
|
-
$sendMessage(options: SendOptions): Promise<string>;
|
|
27
|
-
$recallMessage(id: string): Promise<void>;
|
|
28
|
-
private sendCustomerServiceMessage;
|
|
29
|
-
private formatSendContent;
|
|
30
|
-
private getReplyMode;
|
|
31
|
-
private getEncryptMode;
|
|
32
|
-
private usesPassiveReply;
|
|
33
|
-
private extractSendText;
|
|
34
|
-
private collectPassiveReplyXml;
|
|
35
|
-
private handlePassiveReply;
|
|
36
|
-
private buildTextReply;
|
|
37
|
-
private refreshAccessToken;
|
|
38
|
-
private tokenRefreshTimer?;
|
|
39
|
-
private startTokenRefreshTimer;
|
|
40
|
-
getUserInfo(openid: string): Promise<any>;
|
|
41
|
-
/**
|
|
42
|
-
* 上传多媒体文件到微信服务器
|
|
43
|
-
* @param type 媒体类型:image(图片)、voice(语音)、video(视频)、thumb(缩略图)
|
|
44
|
-
* @param buffer 文件 Buffer
|
|
45
|
-
* @param filename 文件名(可选,用于确定文件类型)
|
|
46
|
-
* @returns 微信服务器返回的 media_id
|
|
47
|
-
*/
|
|
48
|
-
uploadMedia(type: 'image' | 'voice' | 'video' | 'thumb', buffer: Buffer, filename?: string): Promise<string>;
|
|
49
|
-
/**
|
|
50
|
-
* 获取文件扩展名
|
|
51
|
-
*/
|
|
52
|
-
private getFileExtension;
|
|
53
|
-
/**
|
|
54
|
-
* 获取 Content-Type
|
|
55
|
-
*/
|
|
56
|
-
private getContentType;
|
|
57
|
-
private getAESKey;
|
|
58
|
-
/** 微信安全模式加密 echostr 为较长 Base64;明文/兼容模式多为短字符串 */
|
|
59
|
-
private isEncryptedEchostr;
|
|
60
|
-
/**
|
|
61
|
-
* 解密安全模式 URL 验证中的 echostr
|
|
62
|
-
*/
|
|
63
|
-
private decryptEchostr;
|
|
64
|
-
/**
|
|
65
|
-
* 解密微信推送的加密消息
|
|
66
|
-
*/
|
|
67
|
-
private decryptMessage;
|
|
68
|
-
/**
|
|
69
|
-
* 加密被动回复消息
|
|
70
|
-
*/
|
|
71
|
-
private encryptMessage;
|
|
72
|
-
}
|
|
73
|
-
//# sourceMappingURL=bot.d.ts.map
|
package/lib/bot.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"bot.d.ts","sourceRoot":"","sources":["../src/bot.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAEtC,OAAO,EAEH,GAAG,EACH,OAAO,EACP,cAAc,EAGd,WAAW,EAGd,MAAM,SAAS,CAAC;AACjB,OAAO,EAAsB,KAAK,MAAM,EAAsB,MAAM,6BAA6B,CAAC;AAClG,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAoC,MAAM,YAAY,CAAC;AAClG,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAkBpD,qBAAa,WAAY,SAAQ,YAAa,YAAW,GAAG,CAAC,cAAc,EAAE,aAAa,CAAC;IAgBpE,OAAO,EAAE,eAAe;IAf3C,OAAO,EAAE,cAAc,CAAC;IACxB,UAAU,EAAE,OAAO,CAAS;IAC5B,MAAM,EAAE,MAAM,CAAC;IAEf,OAAO,CAAC,WAAW,CAAuB;IAC1C,OAAO,CAAC,eAAe,CAAa;IAEpC,IAAI,MAAM,6BAEX;IAED,IAAI,GAAG,WAEJ;gBAEkB,OAAO,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc;IASnF,OAAO,CAAC,WAAW;IAcb,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAoBzB,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC;IASlC,OAAO,CAAC,kBAAkB;YA8GZ,aAAa;IAqF3B,OAAO,CAAC,oBAAoB;IAc5B,OAAO,CAAC,eAAe;YAWT,eAAe;IAW7B,cAAc,CAAC,SAAS,EAAE,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC;IAuChE,MAAM,CAAC,mBAAmB,CAAC,SAAS,EAAE,aAAa,GAAG,cAAc,EAAE;IAgEhE,YAAY,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC;IAuBnD,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;YAIjC,0BAA0B;IAmBxC,OAAO,CAAC,iBAAiB;IAoEzB,OAAO,CAAC,YAAY;IAIpB,OAAO,CAAC,cAAc;IAOtB,OAAO,CAAC,gBAAgB;IAIxB,OAAO,CAAC,eAAe;YAOT,sBAAsB;YAyCtB,kBAAkB;IA4BhC,OAAO,CAAC,cAAc;YAeR,kBAAkB;IAoBhC,OAAO,CAAC,iBAAiB,CAAC,CAAiC;IAE3D,OAAO,CAAC,sBAAsB;IAcxB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC;IAW/C;;;;;;OAMG;IACG,WAAW,CACb,IAAI,EAAE,OAAO,GAAG,OAAO,GAAG,OAAO,GAAG,OAAO,EAC3C,MAAM,EAAE,MAAM,EACd,QAAQ,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,MAAM,CAAC;IA4ClB;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAiBxB;;OAEG;IACH,OAAO,CAAC,cAAc;IAatB,OAAO,CAAC,SAAS;IAKjB,gDAAgD;IAChD,OAAO,CAAC,kBAAkB;IAK1B;;OAEG;IACH,OAAO,CAAC,cAAc;IAyBtB;;OAEG;YACW,cAAc;IA8C5B;;OAEG;IACH,OAAO,CAAC,cAAc;CAyCzB"}
|