@zhin.js/adapter-wechat-mp 0.1.80 → 0.1.81

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 CHANGED
@@ -1,5 +1,13 @@
1
1
  # @zhin.js/adapter-wechat-mp
2
2
 
3
+ ## 0.1.81
4
+
5
+ ### Patch Changes
6
+
7
+ - acf5e0e: fix: update pnpm-lock.yaml and vitest configurations- Added new dependencies for the full-bot example, including multiple Zhin.js adapters and TypeScript.- Updated the test-bot example to include '@puniyu/system-info' and other necessary packages.- Modified vitest configuration to include additional module directories for better dependency resolution.- Enhanced documentation for the KOOK adapter, including new features like typing indicators and system notifications.- Removed unused test assets and scripts from the test-bot example to streamline the project.
8
+ - zhin.js@1.0.93
9
+ - @zhin.js/host-router@0.0.3
10
+
3
11
  ## 0.1.80
4
12
 
5
13
  ### Patch Changes
package/README.md CHANGED
@@ -24,7 +24,8 @@ pnpm add @zhin.js/adapter-wechat-mp
24
24
  | **服务器配置** | 配置 Token(与 `token` 字段一致);服务器 URL 须公网可访问 |
25
25
  | **host-router** | **必需** — 适配器在 `path` 上注册 GET/POST Webhook 路由 |
26
26
  | **响应时限** | 微信要求 **5 秒内**响应;超时会导致接入失败 |
27
- | **消息加密** | 可选;启用时配置 `encodingAESKey` 与 `encrypt: true` |
27
+ | **回复模式** | 默认 `replyMode: passive`(订阅号被动回复,在 webhook 响应里返回 XML);服务号可设 `customer_service` 走客服 API |
28
+ | **消息加密** | 可选;`encrypt: true` + `encodingAESKey`;`encryptMode: compatible`(默认,被动回复明文)或 `secure`(被动回复也加密) |
28
29
 
29
30
  必填字段见 `WeChatMPConfig`:`context`、`name`、`appId`、`appSecret`、`token`、`path`。
30
31
 
@@ -119,7 +120,7 @@ addMiddleware(async (message, next) => {
119
120
 
120
121
  1. 登录 [微信公众平台](https://mp.weixin.qq.com/)
121
122
  2. 在「开发 → 基本配置」中获取 `AppID` 和 `AppSecret`
122
- 3. 配置服务器地址(URL):`http://your-server:8086/api/wechat/webhook`
123
+ 3. 配置服务器地址(URL):`https://your-server/wechat/webhook`(无 `/api` 前缀;经反向代理时自行映射)
123
124
  4. 设置 Token(与配置文件中的 `token` 一致)
124
125
  5. 如需消息加解密,设置 EncodingAESKey
125
126
 
@@ -127,9 +128,10 @@ addMiddleware(async (message, next) => {
127
128
 
128
129
  | 现象 | 排查 |
129
130
  |------|------|
130
- | 服务器配置验证失败 | `token` 与公众平台一致;URL 为 `http(s)://<host>/api<path>`(Host 默认前缀 `/api`);Host 已启动且公网可达 |
131
+ | 服务器配置验证失败 | `token` 与公众平台一致;URL 为 `https://<host>/wechat/webhook`;Host 已启动且公网可达 |
131
132
  | 收不到用户消息 | 公众号类型是否支持消息接口;用户是否已关注;`path` 与公众平台 URL 一致 |
132
- | 回复超时 | 业务逻辑须在 5 秒内返回;耗时操作应异步处理后再调用客服接口 |
133
+ | 回复超时 / 无回复 | 默认被动回复须在 **~4.5s** 内完成;AI 过慢会返回 `success` 无正文,可改 `replyMode: customer_service`(需客服接口权限) |
134
+ | `48001 api unauthorized` | 未认证订阅号无客服 API;保持默认 `replyMode: passive` |
133
135
  | 加密模式报错 | `encodingAESKey`、`encrypt` 与公众平台「安全模式」设置一致 |
134
136
 
135
137
  ## 文档链接
package/lib/bot.d.ts CHANGED
@@ -18,6 +18,7 @@ export declare class WeChatMPBot extends EventEmitter implements Bot<WeChatMPCon
18
18
  $disconnect(): Promise<void>;
19
19
  private handleVerification;
20
20
  private handleMessage;
21
+ private computeSignatureHash;
21
22
  private verifySignature;
22
23
  private parseXMLMessage;
23
24
  $formatMessage(wechatMsg: WeChatMessage): Message<WeChatMessage>;
@@ -26,6 +27,11 @@ export declare class WeChatMPBot extends EventEmitter implements Bot<WeChatMPCon
26
27
  $recallMessage(id: string): Promise<void>;
27
28
  private sendCustomerServiceMessage;
28
29
  private formatSendContent;
30
+ private getReplyMode;
31
+ private getEncryptMode;
32
+ private usesPassiveReply;
33
+ private extractSendText;
34
+ private collectPassiveReplyXml;
29
35
  private handlePassiveReply;
30
36
  private buildTextReply;
31
37
  private refreshAccessToken;
@@ -49,6 +55,12 @@ export declare class WeChatMPBot extends EventEmitter implements Bot<WeChatMPCon
49
55
  */
50
56
  private getContentType;
51
57
  private getAESKey;
58
+ /** 微信安全模式加密 echostr 为较长 Base64;明文/兼容模式多为短字符串 */
59
+ private isEncryptedEchostr;
60
+ /**
61
+ * 解密安全模式 URL 验证中的 echostr
62
+ */
63
+ private decryptEchostr;
52
64
  /**
53
65
  * 解密微信推送的加密消息
54
66
  */
package/lib/bot.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"bot.d.ts","sourceRoot":"","sources":["../src/bot.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAEtC,OAAO,EAAiB,GAAG,EAAE,OAAO,EAAE,cAAc,EAAwB,WAAW,EAAE,MAAM,SAAS,CAAC;AACzG,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;AAEpD,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;YAiBZ,aAAa;IAsD3B,OAAO,CAAC,eAAe;YAQT,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;IAUnD,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;YAIjC,0BAA0B;IAmBxC,OAAO,CAAC,iBAAiB;YAoEX,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;;OAEG;YACW,cAAc;IA8C5B;;OAEG;IACH,OAAO,CAAC,cAAc;CAyCzB"}
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"}
package/lib/bot.js CHANGED
@@ -6,8 +6,20 @@ import * as xml2js from "xml2js";
6
6
  import { createHash, createDecipheriv, createCipheriv, randomBytes } from "crypto";
7
7
  import { EventEmitter } from "events";
8
8
  import FormData from "form-data";
9
- import { formatCompact, Message, segment } from 'zhin.js';
9
+ import { formatCompact, Message, segment, runInboundMessage, truncatePreview, } from 'zhin.js';
10
10
  import { registerFetchRoute } from "@zhin.js/host-router/router";
11
+ import { getPassiveReplyCapture, recordPassiveReplyText, runWithPassiveReplyCapture, } from "./passive-reply.js";
12
+ function queryParam(value) {
13
+ if (typeof value === "string")
14
+ return value;
15
+ if (Array.isArray(value) && typeof value[0] === "string")
16
+ return value[0];
17
+ return "";
18
+ }
19
+ /** URL 查询里的 Base64 可能把 `+` 解码成空格 */
20
+ function normalizeEchostrParam(echostr) {
21
+ return echostr.replace(/ /g, "+");
22
+ }
11
23
  export class WeChatMPBot extends EventEmitter {
12
24
  adapter;
13
25
  $config;
@@ -35,9 +47,9 @@ export class WeChatMPBot extends EventEmitter {
35
47
  registerFetchRoute(this.router, "GET", path, (ctx) => {
36
48
  this.handleVerification(ctx);
37
49
  });
38
- // 接收微信消息 (POST)
39
- registerFetchRoute(this.router, "POST", path, (ctx) => {
40
- void this.handleMessage(ctx);
50
+ // 接收微信消息 (POST);必须 await,否则 Koa 会在被动回复写入 ctx.body 前就结束响应
51
+ registerFetchRoute(this.router, "POST", path, async (ctx) => {
52
+ await this.handleMessage(ctx);
41
53
  });
42
54
  }
43
55
  async $connect() {
@@ -66,22 +78,122 @@ export class WeChatMPBot extends EventEmitter {
66
78
  this.logger.info(formatCompact({ op: "disconnect", bot: this.$config.name }));
67
79
  }
68
80
  handleVerification(ctx) {
69
- const { signature, timestamp, nonce, echostr } = ctx.query;
70
- if (this.verifySignature(signature, timestamp, nonce)) {
71
- this.logger.info(formatCompact({ op: "verify" }));
72
- ctx.body = echostr;
81
+ const signature = queryParam(ctx.query.signature);
82
+ const msgSignature = queryParam(ctx.query.msg_signature);
83
+ const timestamp = queryParam(ctx.query.timestamp);
84
+ const nonce = queryParam(ctx.query.nonce);
85
+ const echostr = normalizeEchostrParam(queryParam(ctx.query.echostr));
86
+ const secureMode = !!(this.$config.encrypt && this.$config.encodingAESKey);
87
+ // GET 验证:signature 始终为 3 参数;msg_signature(若存在)为 4 参数含 echostr
88
+ const signMode = msgSignature ? "msg_signature" : "signature";
89
+ const signToCheck = msgSignature || signature;
90
+ const signPayload = msgSignature
91
+ ? { signature: msgSignature, timestamp, nonce, echostr }
92
+ : { signature, timestamp, nonce };
93
+ const signFields = msgSignature ? 4 : 3;
94
+ this.logger.info(formatCompact({
95
+ op: "verify",
96
+ stage: "recv",
97
+ path: ctx.path,
98
+ secureMode,
99
+ signMode,
100
+ hasSignature: !!signature,
101
+ hasMsgSignature: !!msgSignature,
102
+ hasEchostr: !!echostr,
103
+ timestamp,
104
+ nonce,
105
+ echostrLen: echostr.length,
106
+ tokenLen: this.$config.token.length,
107
+ }));
108
+ if (!signToCheck || !timestamp || !nonce) {
109
+ this.logger.error(formatCompact({
110
+ op: "verify",
111
+ stage: "sign",
112
+ ok: false,
113
+ error: "missing_query_params",
114
+ }));
115
+ ctx.status = 403;
116
+ ctx.body = "Forbidden";
117
+ return;
73
118
  }
74
- else {
75
- this.logger.error('WeChat verification failed');
119
+ if (!this.verifySignature(signPayload)) {
120
+ const expected = this.computeSignatureHash(signPayload);
121
+ this.logger.error(formatCompact({
122
+ op: "verify",
123
+ stage: "sign",
124
+ ok: false,
125
+ secureMode,
126
+ signMode,
127
+ signFields,
128
+ expectedPrefix: expected.slice(0, 8),
129
+ gotPrefix: signToCheck.slice(0, 8),
130
+ }));
76
131
  ctx.status = 403;
77
- ctx.body = 'Forbidden';
132
+ ctx.body = "Forbidden";
133
+ return;
134
+ }
135
+ this.logger.info(formatCompact({
136
+ op: "verify",
137
+ stage: "sign",
138
+ ok: true,
139
+ signMode,
140
+ signFields,
141
+ }));
142
+ let body = echostr;
143
+ if (secureMode && echostr && this.isEncryptedEchostr(echostr)) {
144
+ try {
145
+ body = this.decryptEchostr(echostr);
146
+ this.logger.info(formatCompact({
147
+ op: "verify",
148
+ stage: "decrypt",
149
+ ok: true,
150
+ mode: "aes",
151
+ plainLen: body.length,
152
+ }));
153
+ }
154
+ catch (error) {
155
+ this.logger.error(formatCompact({
156
+ op: "verify",
157
+ stage: "decrypt",
158
+ ok: false,
159
+ mode: "aes",
160
+ error: error instanceof Error ? error.message : String(error),
161
+ }));
162
+ ctx.status = 403;
163
+ ctx.body = "Forbidden";
164
+ return;
165
+ }
166
+ }
167
+ else if (secureMode && echostr) {
168
+ this.logger.info(formatCompact({
169
+ op: "verify",
170
+ stage: "decrypt",
171
+ ok: true,
172
+ mode: "plain_echostr",
173
+ plainLen: body.length,
174
+ }));
78
175
  }
176
+ this.logger.info(formatCompact({
177
+ op: "verify",
178
+ stage: "done",
179
+ ok: true,
180
+ replyLen: body.length,
181
+ }));
182
+ ctx.body = body;
79
183
  }
80
184
  async handleMessage(ctx) {
81
185
  try {
82
- const { signature, timestamp, nonce, msg_signature, encrypt_type } = ctx.query;
186
+ const signature = queryParam(ctx.query.signature);
187
+ const timestamp = queryParam(ctx.query.timestamp);
188
+ const nonce = queryParam(ctx.query.nonce);
189
+ const msg_signature = queryParam(ctx.query.msg_signature);
190
+ const encrypt_type = queryParam(ctx.query.encrypt_type);
83
191
  // 验证签名
84
- if (!this.verifySignature(signature, timestamp, nonce)) {
192
+ if (!this.verifySignature({
193
+ signature,
194
+ timestamp,
195
+ nonce,
196
+ })) {
85
197
  this.logger.error('Invalid signature');
86
198
  ctx.status = 403;
87
199
  ctx.body = 'Forbidden';
@@ -96,15 +208,40 @@ export class WeChatMPBot extends EventEmitter {
96
208
  const wechatMessage = await this.parseXMLMessage(xmlString);
97
209
  if (wechatMessage) {
98
210
  const message = this.$formatMessage(wechatMessage);
99
- this.adapter.emit('message.receive', message);
100
- // 处理被动回复
211
+ this.logger.info(formatCompact({
212
+ recv: `private(${message.$channel.id})`,
213
+ bot: message.$bot,
214
+ preview: truncatePreview(segment.raw(message.$content)),
215
+ replyMode: this.getReplyMode(),
216
+ encryptMode: this.getEncryptMode(),
217
+ encryptType: encrypt_type || "plain",
218
+ }));
101
219
  let replyXML = await this.handlePassiveReply(wechatMessage, message);
102
- // AES 加密模式:加密回复
103
- if (replyXML && this.$config.encrypt && this.$config.encodingAESKey) {
104
- replyXML = this.encryptMessage(replyXML);
220
+ if (!replyXML && this.usesPassiveReply()) {
221
+ replyXML = await this.collectPassiveReplyXml(wechatMessage, message);
222
+ }
223
+ else if (!replyXML) {
224
+ this.adapter.emit("message.receive", message);
225
+ }
226
+ // 仅安全模式加密被动回复;兼容模式可明文回包(微信官方允许)
227
+ const encryptReply = !!(replyXML &&
228
+ this.$config.encodingAESKey &&
229
+ encrypt_type === "aes" &&
230
+ this.getEncryptMode() === "secure");
231
+ if (encryptReply) {
232
+ replyXML = this.encryptMessage(replyXML, timestamp);
233
+ }
234
+ ctx.set("Content-Type", "text/xml");
235
+ ctx.body = replyXML || "success";
236
+ if (replyXML) {
237
+ this.logger.info(formatCompact({
238
+ op: "passive_reply",
239
+ stage: "sent",
240
+ encrypted: encryptReply,
241
+ encryptMode: this.getEncryptMode(),
242
+ bodyLen: replyXML.length,
243
+ }));
105
244
  }
106
- ctx.set('Content-Type', 'text/xml');
107
- ctx.body = replyXML || 'success';
108
245
  }
109
246
  else {
110
247
  ctx.body = 'success';
@@ -115,12 +252,20 @@ export class WeChatMPBot extends EventEmitter {
115
252
  ctx.body = 'success';
116
253
  }
117
254
  }
118
- verifySignature(signature, timestamp, nonce) {
255
+ computeSignatureHash(params) {
256
+ const { timestamp, nonce, echostr } = params;
119
257
  const token = this.$config.token;
120
- const arr = [token, timestamp, nonce].sort();
121
- const str = arr.join('');
122
- const hash = createHash('sha1').update(str).digest('hex');
123
- return hash === signature;
258
+ const arr = echostr
259
+ ? [token, timestamp, nonce, echostr]
260
+ : [token, timestamp, nonce];
261
+ arr.sort();
262
+ return createHash("sha1").update(arr.join("")).digest("hex");
263
+ }
264
+ verifySignature(params) {
265
+ const { signature, timestamp, nonce, echostr } = params;
266
+ if (!signature || !timestamp || !nonce)
267
+ return false;
268
+ return this.computeSignatureHash({ timestamp, nonce, echostr }) === signature;
124
269
  }
125
270
  async parseXMLMessage(xmlString) {
126
271
  try {
@@ -223,15 +368,26 @@ export class WeChatMPBot extends EventEmitter {
223
368
  return segments.length > 0 ? segments : [segment.text('(空消息)')];
224
369
  }
225
370
  async $sendMessage(options) {
226
- try {
227
- // 公众号主动发送消息需要通过客服消息API
228
- const msgId = await this.sendCustomerServiceMessage(options);
229
- return msgId;
371
+ if (getPassiveReplyCapture()) {
372
+ const text = this.extractSendText(options);
373
+ recordPassiveReplyText(text);
374
+ return `passive_${Date.now()}`;
230
375
  }
231
- catch (error) {
232
- this.logger.error('Failed to send WeChat message:', error);
233
- throw error;
376
+ if (!this.usesPassiveReply()) {
377
+ try {
378
+ return await this.sendCustomerServiceMessage(options);
379
+ }
380
+ catch (error) {
381
+ this.logger.error("Failed to send WeChat message:", error);
382
+ throw error;
383
+ }
234
384
  }
385
+ this.logger.warn(formatCompact({
386
+ op: "send",
387
+ skip: "passive_outside_webhook",
388
+ bot: this.$config.name,
389
+ }));
390
+ return `passive_skipped_${Date.now()}`;
235
391
  }
236
392
  async $recallMessage(id) {
237
393
  // 公众号不支持撤回消息
@@ -311,6 +467,55 @@ export class WeChatMPBot extends EventEmitter {
311
467
  }
312
468
  return messageData;
313
469
  }
470
+ getReplyMode() {
471
+ return this.$config.replyMode ?? "passive";
472
+ }
473
+ getEncryptMode() {
474
+ if (!this.$config.encrypt || !this.$config.encodingAESKey) {
475
+ return "plain";
476
+ }
477
+ return this.$config.encryptMode ?? "compatible";
478
+ }
479
+ usesPassiveReply() {
480
+ return this.getReplyMode() === "passive";
481
+ }
482
+ extractSendText(options) {
483
+ if (typeof options.content === "string") {
484
+ return options.content;
485
+ }
486
+ return segment.raw(options.content);
487
+ }
488
+ async collectPassiveReplyXml(wechatMsg, message) {
489
+ const timeoutMs = this.$config.passiveReplyTimeoutMs ?? 4500;
490
+ const text = await runWithPassiveReplyCapture(async () => {
491
+ await Promise.race([
492
+ runInboundMessage({
493
+ plugin: this.adapter.plugin,
494
+ message,
495
+ emitAdapterObservers: () => {
496
+ EventEmitter.prototype.emit.call(this.adapter, "message.receive", message);
497
+ },
498
+ }),
499
+ new Promise((resolve) => setTimeout(resolve, timeoutMs)),
500
+ ]);
501
+ return getPassiveReplyCapture()?.text ?? null;
502
+ });
503
+ if (!text) {
504
+ this.logger.warn(formatCompact({
505
+ op: "passive_reply",
506
+ ok: false,
507
+ reason: "timeout_or_empty",
508
+ timeoutMs,
509
+ }));
510
+ return "";
511
+ }
512
+ this.logger.info(formatCompact({
513
+ op: "passive_reply",
514
+ ok: true,
515
+ plainLen: text.length,
516
+ }));
517
+ return this.buildTextReply(wechatMsg, text);
518
+ }
314
519
  async handlePassiveReply(wechatMsg, message) {
315
520
  // 事件类型消息的自动回复
316
521
  if (wechatMsg.MsgType === 'event') {
@@ -338,17 +543,17 @@ export class WeChatMPBot extends EventEmitter {
338
543
  return '';
339
544
  }
340
545
  buildTextReply(wechatMsg, content) {
341
- const replyMsg = {
342
- xml: {
343
- ToUserName: wechatMsg.FromUserName,
344
- FromUserName: wechatMsg.ToUserName,
345
- CreateTime: Math.floor(Date.now() / 1000),
346
- MsgType: 'text',
347
- Content: content
348
- }
349
- };
350
- const builder = new xml2js.Builder({ rootName: 'xml', headless: true });
351
- return builder.buildObject(replyMsg);
546
+ const cdata = (value) => value.replace(/]]>/g, "]]]]><![CDATA[>");
547
+ const createTime = Math.floor(Date.now() / 1000);
548
+ return [
549
+ "<xml>",
550
+ `<ToUserName><![CDATA[${cdata(wechatMsg.FromUserName)}]]></ToUserName>`,
551
+ `<FromUserName><![CDATA[${cdata(wechatMsg.ToUserName)}]]></FromUserName>`,
552
+ `<CreateTime>${createTime}</CreateTime>`,
553
+ `<MsgType><![CDATA[text]]></MsgType>`,
554
+ `<Content><![CDATA[${cdata(content)}]]></Content>`,
555
+ "</xml>",
556
+ ].join("");
352
557
  }
353
558
  async refreshAccessToken() {
354
559
  const url = `https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=${this.$config.appId}&secret=${this.$config.appSecret}`;
@@ -470,6 +675,34 @@ export class WeChatMPBot extends EventEmitter {
470
675
  const key = this.$config.encodingAESKey;
471
676
  return Buffer.from(key + '=', 'base64');
472
677
  }
678
+ /** 微信安全模式加密 echostr 为较长 Base64;明文/兼容模式多为短字符串 */
679
+ isEncryptedEchostr(echostr) {
680
+ if (echostr.length < 32)
681
+ return false;
682
+ return /^[A-Za-z0-9+/]+={0,2}$/.test(echostr);
683
+ }
684
+ /**
685
+ * 解密安全模式 URL 验证中的 echostr
686
+ */
687
+ decryptEchostr(encrypted) {
688
+ const aesKey = this.getAESKey();
689
+ const iv = aesKey.subarray(0, 16);
690
+ const decipher = createDecipheriv("aes-256-cbc", aesKey, iv);
691
+ decipher.setAutoPadding(false);
692
+ const decrypted = Buffer.concat([
693
+ decipher.update(Buffer.from(encrypted, "base64")),
694
+ decipher.final(),
695
+ ]);
696
+ const pad = decrypted[decrypted.length - 1];
697
+ const content = decrypted.subarray(0, decrypted.length - pad);
698
+ const msgLen = content.readUInt32BE(16);
699
+ const plain = content.subarray(20, 20 + msgLen).toString("utf8");
700
+ const appId = content.subarray(20 + msgLen).toString("utf8");
701
+ if (appId !== this.$config.appId) {
702
+ throw new Error(`AppID mismatch: expected ${this.$config.appId}, got ${appId}`);
703
+ }
704
+ return plain;
705
+ }
473
706
  /**
474
707
  * 解密微信推送的加密消息
475
708
  */
@@ -510,7 +743,7 @@ export class WeChatMPBot extends EventEmitter {
510
743
  /**
511
744
  * 加密被动回复消息
512
745
  */
513
- encryptMessage(replyXml) {
746
+ encryptMessage(replyXml, requestTimestamp) {
514
747
  const aesKey = this.getAESKey();
515
748
  const iv = aesKey.subarray(0, 16);
516
749
  // 组装明文: 16 bytes random + 4 bytes msgLen + msg + appId
@@ -530,8 +763,8 @@ export class WeChatMPBot extends EventEmitter {
530
763
  cipher.setAutoPadding(false);
531
764
  const encrypted = Buffer.concat([cipher.update(padded), cipher.final()]);
532
765
  const encryptStr = encrypted.toString('base64');
533
- // 签名
534
- const timestamp = Math.floor(Date.now() / 1000).toString();
766
+ // 签名(TimeStamp 优先复用入站请求值,与微信官方示例一致)
767
+ const timestamp = requestTimestamp || Math.floor(Date.now() / 1000).toString();
535
768
  const nonce = randomBytes(8).toString('hex');
536
769
  const signature = createHash('sha1')
537
770
  .update([this.$config.token, timestamp, nonce, encryptStr].sort().join(''))
package/lib/bot.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"bot.js","sourceRoot":"","sources":["../src/bot.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"bot.js","sourceRoot":"","sources":["../src/bot.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,KAAK,MAAM,MAAM,QAAQ,CAAC;AACjC,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AACnF,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,QAAQ,MAAM,WAAW,CAAC;AACjC,OAAO,EACH,aAAa,EAEb,OAAO,EAEP,OAAO,EAGP,iBAAiB,EACjB,eAAe,GAClB,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,kBAAkB,EAAmC,MAAM,6BAA6B,CAAC;AAGlG,OAAO,EACH,sBAAsB,EACtB,sBAAsB,EACtB,0BAA0B,GAC7B,MAAM,oBAAoB,CAAC;AAE5B,SAAS,UAAU,CAAC,KAAc;IAC9B,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IAC5C,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC;IAC1E,OAAO,EAAE,CAAC;AACd,CAAC;AAED,oCAAoC;AACpC,SAAS,qBAAqB,CAAC,OAAe;IAC1C,OAAO,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;AACtC,CAAC;AAED,MAAM,OAAO,WAAY,SAAQ,YAAY;IAgBtB;IAfnB,OAAO,CAAiB;IACxB,UAAU,GAAY,KAAK,CAAC;IAC5B,MAAM,CAAS;IAEP,WAAW,GAAkB,IAAI,CAAC;IAClC,eAAe,GAAW,CAAC,CAAC;IAEpC,IAAI,MAAM;QACV,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC;IACpC,CAAC;IAED,IAAI,GAAG;QACD,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC;IAC7B,CAAC;IAED,YAAmB,OAAwB,EAAE,MAAc,EAAE,MAAsB;QAC/E,KAAK,EAAE,CAAC;QADO,YAAO,GAAP,OAAO,CAAiB;QAEvC,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC;QACtB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QAErB,QAAQ;QACR,IAAI,CAAC,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,IAAI,KAAK,CAAC;IACzD,CAAC;IAEO,WAAW;QACf,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC;QAE/B,gBAAgB;QAChB,kBAAkB,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,GAAkB,EAAE,EAAE;YAChE,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC;QACjC,CAAC,CAAC,CAAC;QAEH,yDAAyD;QACzD,kBAAkB,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAkB,EAAE,EAAE;YACvE,MAAM,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;QAClC,CAAC,CAAC,CAAC;IACP,CAAC;IAED,KAAK,CAAC,QAAQ;QACV,IAAI,CAAC;YACD,iBAAiB;YACjB,MAAM,IAAI,CAAC,kBAAkB,EAAE,CAAC;YAEhC,OAAO;YACP,IAAI,CAAC,WAAW,EAAE,CAAC;YAEnB,mBAAmB;YACnB,IAAI,CAAC,sBAAsB,EAAE,CAAC;YAE9B,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;YAC5D,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,aAAa,CAAE,EAAE,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;YAC7E,IAAI,CAAC,UAAU,GAAE,IAAI,CAAC;QAC1B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,kCAAkC,EAAE,KAAK,CAAC,CAAC;YAC7D,MAAM,KAAK,CAAC;QAChB,CAAC;IACL,CAAC;IAED,KAAK,CAAC,WAAW;QACb,IAAI,IAAI,CAAC,iBAAiB,EAAE,CAAC;YACzB,aAAa,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;YACtC,IAAI,CAAC,iBAAiB,GAAG,SAAS,CAAC;QACvC,CAAC;QACD,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC;QACxB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,aAAa,CAAE,EAAE,EAAE,EAAE,YAAY,EAAE,GAAG,EAAE,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;IACnF,CAAC;IAEO,kBAAkB,CAAC,GAAkB;QACzC,MAAM,SAAS,GAAG,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;QAClD,MAAM,YAAY,GAAG,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;QACzD,MAAM,SAAS,GAAG,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;QAClD,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAC1C,MAAM,OAAO,GAAG,qBAAqB,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;QAErE,MAAM,UAAU,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,IAAI,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;QAC3E,8DAA8D;QAC9D,MAAM,QAAQ,GAAG,YAAY,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,WAAW,CAAC;QAC9D,MAAM,WAAW,GAAG,YAAY,IAAI,SAAS,CAAC;QAC9C,MAAM,WAAW,GAAG,YAAY;YAC5B,CAAC,CAAC,EAAE,SAAS,EAAE,YAAY,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,EAAE;YACxD,CAAC,CAAC,EAAE,SAAS,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;QACtC,MAAM,UAAU,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAExC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC;YAC3B,EAAE,EAAE,QAAQ;YACZ,KAAK,EAAE,MAAM;YACb,IAAI,EAAE,GAAG,CAAC,IAAI;YACd,UAAU;YACV,QAAQ;YACR,YAAY,EAAE,CAAC,CAAC,SAAS;YACzB,eAAe,EAAE,CAAC,CAAC,YAAY;YAC/B,UAAU,EAAE,CAAC,CAAC,OAAO;YACrB,SAAS;YACT,KAAK;YACL,UAAU,EAAE,OAAO,CAAC,MAAM;YAC1B,QAAQ,EAAE,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM;SACtC,CAAC,CAAC,CAAC;QAEJ,IAAI,CAAC,WAAW,IAAI,CAAC,SAAS,IAAI,CAAC,KAAK,EAAE,CAAC;YACvC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC;gBAC5B,EAAE,EAAE,QAAQ;gBACZ,KAAK,EAAE,MAAM;gBACb,EAAE,EAAE,KAAK;gBACT,KAAK,EAAE,sBAAsB;aAChC,CAAC,CAAC,CAAC;YACJ,GAAG,CAAC,MAAM,GAAG,GAAG,CAAC;YACjB,GAAG,CAAC,IAAI,GAAG,WAAW,CAAC;YACvB,OAAO;QACX,CAAC;QAED,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,WAAW,CAAC,EAAE,CAAC;YACrC,MAAM,QAAQ,GAAG,IAAI,CAAC,oBAAoB,CAAC,WAAW,CAAC,CAAC;YACxD,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC;gBAC5B,EAAE,EAAE,QAAQ;gBACZ,KAAK,EAAE,MAAM;gBACb,EAAE,EAAE,KAAK;gBACT,UAAU;gBACV,QAAQ;gBACR,UAAU;gBACV,cAAc,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;gBACpC,SAAS,EAAE,WAAW,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;aACrC,CAAC,CAAC,CAAC;YACJ,GAAG,CAAC,MAAM,GAAG,GAAG,CAAC;YACjB,GAAG,CAAC,IAAI,GAAG,WAAW,CAAC;YACvB,OAAO;QACX,CAAC;QAED,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC;YAC3B,EAAE,EAAE,QAAQ;YACZ,KAAK,EAAE,MAAM;YACb,EAAE,EAAE,IAAI;YACR,QAAQ;YACR,UAAU;SACb,CAAC,CAAC,CAAC;QAEJ,IAAI,IAAI,GAAG,OAAO,CAAC;QACnB,IAAI,UAAU,IAAI,OAAO,IAAI,IAAI,CAAC,kBAAkB,CAAC,OAAO,CAAC,EAAE,CAAC;YAC5D,IAAI,CAAC;gBACD,IAAI,GAAG,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;gBACpC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC;oBAC3B,EAAE,EAAE,QAAQ;oBACZ,KAAK,EAAE,SAAS;oBAChB,EAAE,EAAE,IAAI;oBACR,IAAI,EAAE,KAAK;oBACX,QAAQ,EAAE,IAAI,CAAC,MAAM;iBACxB,CAAC,CAAC,CAAC;YACR,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACb,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC;oBAC5B,EAAE,EAAE,QAAQ;oBACZ,KAAK,EAAE,SAAS;oBAChB,EAAE,EAAE,KAAK;oBACT,IAAI,EAAE,KAAK;oBACX,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;iBAChE,CAAC,CAAC,CAAC;gBACJ,GAAG,CAAC,MAAM,GAAG,GAAG,CAAC;gBACjB,GAAG,CAAC,IAAI,GAAG,WAAW,CAAC;gBACvB,OAAO;YACX,CAAC;QACL,CAAC;aAAM,IAAI,UAAU,IAAI,OAAO,EAAE,CAAC;YAC/B,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC;gBAC3B,EAAE,EAAE,QAAQ;gBACZ,KAAK,EAAE,SAAS;gBAChB,EAAE,EAAE,IAAI;gBACR,IAAI,EAAE,eAAe;gBACrB,QAAQ,EAAE,IAAI,CAAC,MAAM;aACxB,CAAC,CAAC,CAAC;QACR,CAAC;QAED,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC;YAC3B,EAAE,EAAE,QAAQ;YACZ,KAAK,EAAE,MAAM;YACb,EAAE,EAAE,IAAI;YACR,QAAQ,EAAE,IAAI,CAAC,MAAM;SACxB,CAAC,CAAC,CAAC;QACJ,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC;IACpB,CAAC;IAEO,KAAK,CAAC,aAAa,CAAC,GAAkB;QAC1C,IAAI,CAAC;YACD,MAAM,SAAS,GAAG,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;YAClD,MAAM,SAAS,GAAG,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;YAClD,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YAC1C,MAAM,aAAa,GAAG,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;YAC1D,MAAM,YAAY,GAAG,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;YAExD,OAAO;YACP,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC;gBACtB,SAAS;gBACT,SAAS;gBACT,KAAK;aACR,CAAC,EAAE,CAAC;gBACD,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAC;gBACvC,GAAG,CAAC,MAAM,GAAG,GAAG,CAAC;gBACjB,GAAG,CAAC,IAAI,GAAG,WAAW,CAAC;gBACvB,OAAO;YACX,CAAC;YAED,YAAY;YACZ,IAAI,SAAS,GAAG,OAAO,GAAG,CAAC,OAAO,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;YAE7E,eAAe;YACf,IAAI,IAAI,CAAC,OAAO,CAAC,OAAO,IAAI,YAAY,KAAK,KAAK,IAAI,IAAI,CAAC,OAAO,CAAC,cAAc,EAAE,CAAC;gBAChF,SAAS,GAAG,MAAM,IAAI,CAAC,cAAc,CACjC,SAAS,EACT,aAAuB,EACvB,SAAmB,EACnB,KAAe,CAClB,CAAC;YACN,CAAC;YAED,MAAM,aAAa,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,SAAS,CAAC,CAAC;YAE5D,IAAI,aAAa,EAAE,CAAC;gBAChB,MAAM,OAAO,GAAG,IAAI,CAAC,cAAc,CAAC,aAAa,CAAC,CAAC;gBACnD,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC;oBAC3B,IAAI,EAAE,WAAW,OAAO,CAAC,QAAQ,CAAC,EAAE,GAAG;oBACvC,GAAG,EAAE,OAAO,CAAC,IAAI;oBACjB,OAAO,EAAE,eAAe,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;oBACvD,SAAS,EAAE,IAAI,CAAC,YAAY,EAAE;oBAC9B,WAAW,EAAE,IAAI,CAAC,cAAc,EAAE;oBAClC,WAAW,EAAE,YAAY,IAAI,OAAO;iBACvC,CAAC,CAAC,CAAC;gBAEJ,IAAI,QAAQ,GAAG,MAAM,IAAI,CAAC,kBAAkB,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;gBAErE,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,gBAAgB,EAAE,EAAE,CAAC;oBACvC,QAAQ,GAAG,MAAM,IAAI,CAAC,sBAAsB,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;gBACzE,CAAC;qBAAM,IAAI,CAAC,QAAQ,EAAE,CAAC;oBACnB,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,iBAAiB,EAAE,OAAO,CAAC,CAAC;gBAClD,CAAC;gBAED,gCAAgC;gBAChC,MAAM,YAAY,GAAG,CAAC,CAAC,CACnB,QAAQ;oBACR,IAAI,CAAC,OAAO,CAAC,cAAc;oBAC3B,YAAY,KAAK,KAAK;oBACtB,IAAI,CAAC,cAAc,EAAE,KAAK,QAAQ,CACrC,CAAC;gBACF,IAAI,YAAY,EAAE,CAAC;oBACf,QAAQ,GAAG,IAAI,CAAC,cAAc,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;gBACxD,CAAC;gBAED,GAAG,CAAC,GAAG,CAAC,cAAc,EAAE,UAAU,CAAC,CAAC;gBACpC,GAAG,CAAC,IAAI,GAAG,QAAQ,IAAI,SAAS,CAAC;gBACjC,IAAI,QAAQ,EAAE,CAAC;oBACX,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC;wBAC3B,EAAE,EAAE,eAAe;wBACnB,KAAK,EAAE,MAAM;wBACb,SAAS,EAAE,YAAY;wBACvB,WAAW,EAAE,IAAI,CAAC,cAAc,EAAE;wBAClC,OAAO,EAAE,QAAQ,CAAC,MAAM;qBAC3B,CAAC,CAAC,CAAC;gBACR,CAAC;YACL,CAAC;iBAAM,CAAC;gBACJ,GAAG,CAAC,IAAI,GAAG,SAAS,CAAC;YACzB,CAAC;QACL,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,gCAAgC,EAAE,KAAK,CAAC,CAAC;YAC3D,GAAG,CAAC,IAAI,GAAG,SAAS,CAAC;QACzB,CAAC;IACL,CAAC;IAEO,oBAAoB,CAAC,MAI5B;QACG,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,MAAM,CAAC;QAC7C,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC;QACjC,MAAM,GAAG,GAAG,OAAO;YACf,CAAC,CAAC,CAAC,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,CAAC;YACpC,CAAC,CAAC,CAAC,KAAK,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC;QAChC,GAAG,CAAC,IAAI,EAAE,CAAC;QACX,OAAO,UAAU,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACjE,CAAC;IAEO,eAAe,CAAC,MAKvB;QACG,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,MAAM,CAAC;QACxD,IAAI,CAAC,SAAS,IAAI,CAAC,SAAS,IAAI,CAAC,KAAK;YAAE,OAAO,KAAK,CAAC;QACrD,OAAO,IAAI,CAAC,oBAAoB,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,KAAK,SAAS,CAAC;IAClF,CAAC;IAEO,KAAK,CAAC,eAAe,CAAC,SAAiB;QAC3C,IAAI,CAAC;YACD,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,MAAM,CAAC,EAAE,aAAa,EAAE,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC;YAC9E,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,kBAAkB,CAAC,SAAS,CAAC,CAAC;YAC1D,OAAO,MAAM,CAAC,GAAoB,CAAC;QACvC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,oBAAoB,EAAE,KAAK,CAAC,CAAC;YAC/C,OAAO,IAAI,CAAC;QAChB,CAAC;IACL,CAAC;IAED,cAAc,CAAC,SAAwB;QACnC,MAAM,WAAW,GAAG,SAAS,CAAC,CAAC,YAAY;QAC3C,MAAM,SAAS,GAAG,SAAS,CAAC,YAAY,CAAC;QAEzC,SAAS;QACT,MAAM,OAAO,GAAG,WAAW,CAAC,mBAAmB,CAAC,SAAS,CAAC,CAAC;QAE3D,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,SAAS,EAAE;YACnC,GAAG,EAAE,SAAS,CAAC,KAAK,IAAI,GAAG,SAAS,CAAC,UAAU,EAAE;YACjD,QAAQ,EAAE,WAAW;YACrB,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,IAAI;YACvB,OAAO,EAAE;gBACL,EAAE,EAAE,SAAS,CAAC,YAAY;gBAC1B,IAAI,EAAE,SAAS,CAAC,YAAY;aAC/B;YACD,QAAQ,EAAE;gBACN,EAAE,EAAE,SAAS;gBACb,IAAI,EAAE,WAAkB;aAC3B;YACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC;YAC/B,UAAU,EAAE,SAAS,CAAC,UAAU,GAAG,IAAI;YACvC,QAAQ,EAAE,OAAO;YACjB,OAAO,EAAE,KAAK,IAAI,EAAE;gBAChB,MAAM,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;YACzC,CAAC;YACD,MAAM,EAAE,KAAK,EAAE,OAAoB,EAAmB,EAAE;gBACpD,OAAO,MAAM,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC;oBAClC,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,OAAO;oBAC7B,GAAG,EAAE,IAAI,CAAC,OAAO,CAAC,IAAI;oBACtB,EAAE,EAAE,SAAS,CAAC,YAAY;oBAC1B,IAAI,EAAE,SAAS;oBACf,OAAO;iBACV,CAAC,CAAC;YACP,CAAC;SACJ,CAAC,CAAC;QAEH,OAAO,MAAM,CAAC;IAClB,CAAC;IAED,MAAM,CAAC,mBAAmB,CAAC,SAAwB;QAC/C,MAAM,QAAQ,GAAqB,EAAE,CAAC;QAEtC,QAAQ,SAAS,CAAC,OAAO,EAAE,CAAC;YACxB,KAAK,MAAM;gBACP,IAAI,SAAS,CAAC,OAAO,EAAE,CAAC;oBACpB,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC;gBACnD,CAAC;gBACD,MAAM;YAEV,KAAK,OAAO;gBACR,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE;oBAC3B,GAAG,EAAE,SAAS,CAAC,MAAM;oBACrB,OAAO,EAAE,SAAS,CAAC,OAAO;iBAC7B,CAAC,CAAC,CAAC;gBACJ,MAAM;YAEV,KAAK,OAAO;gBACR,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE;oBAC3B,OAAO,EAAE,SAAS,CAAC,OAAO;oBAC1B,MAAM,EAAE,SAAS,CAAC,MAAM;oBACxB,WAAW,EAAE,SAAS,CAAC,WAAW;iBACrC,CAAC,CAAC,CAAC;gBACJ,MAAM;YAEV,KAAK,OAAO,CAAC;YACb,KAAK,YAAY;gBACb,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE;oBAC3B,OAAO,EAAE,SAAS,CAAC,OAAO;oBAC1B,YAAY,EAAE,SAAS,CAAC,YAAY;iBACvC,CAAC,CAAC,CAAC;gBACJ,MAAM;YAEV,KAAK,UAAU;gBACX,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE;oBAC9B,QAAQ,EAAE,SAAS,CAAC,UAAU;oBAC9B,SAAS,EAAE,SAAS,CAAC,UAAU;oBAC/B,KAAK,EAAE,SAAS,CAAC,KAAK;oBACtB,KAAK,EAAE,SAAS,CAAC,KAAK;iBACzB,CAAC,CAAC,CAAC;gBACJ,MAAM;YAEV,KAAK,MAAM;gBACP,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE;oBAC1B,KAAK,EAAE,SAAS,CAAC,KAAK;oBACtB,WAAW,EAAE,SAAS,CAAC,WAAW;oBAClC,GAAG,EAAE,SAAS,CAAC,GAAG;iBACrB,CAAC,CAAC,CAAC;gBACJ,MAAM;YAEV,KAAK,OAAO;gBACR,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE;oBAC3B,KAAK,EAAE,SAAS,CAAC,KAAK;oBACtB,QAAQ,EAAE,SAAS,CAAC,QAAQ;iBAC/B,CAAC,CAAC,CAAC;gBACJ,MAAM;YAEV;gBACI,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,cAAc,SAAS,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC;QACxE,CAAC;QAED,OAAO,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;IACpE,CAAC;IAED,KAAK,CAAC,YAAY,CAAC,OAAoB;QACnC,IAAI,sBAAsB,EAAE,EAAE,CAAC;YAC3B,MAAM,IAAI,GAAG,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;YAC3C,sBAAsB,CAAC,IAAI,CAAC,CAAC;YAC7B,OAAO,WAAW,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;QACnC,CAAC;QAED,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,EAAE,CAAC;YAC3B,IAAI,CAAC;gBACD,OAAO,MAAM,IAAI,CAAC,0BAA0B,CAAC,OAAO,CAAC,CAAC;YAC1D,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACb,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,gCAAgC,EAAE,KAAK,CAAC,CAAC;gBAC3D,MAAM,KAAK,CAAC;YAChB,CAAC;QACL,CAAC;QAED,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC;YAC3B,EAAE,EAAE,MAAM;YACV,IAAI,EAAE,yBAAyB;YAC/B,GAAG,EAAE,IAAI,CAAC,OAAO,CAAC,IAAI;SACzB,CAAC,CAAC,CAAC;QACJ,OAAO,mBAAmB,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;IAC3C,CAAC;IACD,KAAK,CAAC,cAAc,CAAC,EAAU;QAC3B,aAAa;IACjB,CAAC;IAEO,KAAK,CAAC,0BAA0B,CAAC,OAAoB;QACzD,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;YACpB,MAAM,IAAI,CAAC,kBAAkB,EAAE,CAAC;QACpC,CAAC;QAED,MAAM,GAAG,GAAG,sEAAsE,IAAI,CAAC,WAAW,EAAE,CAAC;QAErG,MAAM,WAAW,GAAG,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC;QAEpD,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;QACpD,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAyB,CAAC;QAElD,IAAI,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,OAAO,KAAK,CAAC,EAAE,CAAC;YACzC,MAAM,IAAI,KAAK,CAAC,qBAAqB,MAAM,CAAC,OAAO,MAAM,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;QAC9E,CAAC;QAED,OAAO,MAAM,CAAC,KAAK,EAAE,QAAQ,EAAE,IAAI,MAAM,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;IAC1D,CAAC;IAEO,iBAAiB,CAAC,OAAoB;QAC1C,MAAM,WAAW,GAAQ;YACrB,MAAM,EAAE,OAAO,CAAC,EAAE;YAClB,OAAO,EAAE,MAAM;YACf,IAAI,EAAE;gBACF,OAAO,EAAE,EAAE;aACd;SACJ,CAAC;QAEF,IAAI,OAAO,OAAO,CAAC,OAAO,KAAK,QAAQ,EAAE,CAAC;YACtC,WAAW,CAAC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;QAC/C,CAAC;aAAM,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;YACxC,MAAM,SAAS,GAAa,EAAE,CAAC;YAC/B,IAAI,QAAQ,GAAG,KAAK,CAAC;YAErB,KAAK,MAAM,IAAI,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;gBACjC,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;oBAC3B,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACzB,CAAC;qBAAM,CAAC;oBACJ,MAAM,OAAO,GAAG,IAAsB,CAAC;oBACvC,QAAQ,OAAO,CAAC,IAAI,EAAE,CAAC;wBACnB,KAAK,MAAM;4BACP,MAAM,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC;4BACpE,SAAS,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;4BAC5B,MAAM;wBAEV,KAAK,OAAO;4BACR,IAAI,CAAC,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;gCACpC,WAAW,CAAC,OAAO,GAAG,OAAO,CAAC;gCAC9B,WAAW,CAAC,KAAK,GAAG,EAAE,QAAQ,EAAE,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;gCACvD,OAAO,WAAW,CAAC,IAAI,CAAC;gCACxB,QAAQ,GAAG,IAAI,CAAC;4BACpB,CAAC;4BACD,MAAM;wBAEV,KAAK,OAAO;4BACR,IAAI,CAAC,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;gCACpC,WAAW,CAAC,OAAO,GAAG,OAAO,CAAC;gCAC9B,WAAW,CAAC,KAAK,GAAG,EAAE,QAAQ,EAAE,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;gCACvD,OAAO,WAAW,CAAC,IAAI,CAAC;gCACxB,QAAQ,GAAG,IAAI,CAAC;4BACpB,CAAC;4BACD,MAAM;wBAEV,KAAK,OAAO;4BACR,IAAI,CAAC,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;gCACpC,WAAW,CAAC,OAAO,GAAG,OAAO,CAAC;gCAC9B,WAAW,CAAC,KAAK,GAAG;oCAChB,QAAQ,EAAE,OAAO,CAAC,IAAI,CAAC,OAAO;oCAC9B,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE;oCAC/B,WAAW,EAAE,OAAO,CAAC,IAAI,CAAC,WAAW,IAAI,EAAE;iCAC9C,CAAC;gCACF,OAAO,WAAW,CAAC,IAAI,CAAC;gCACxB,QAAQ,GAAG,IAAI,CAAC;4BACpB,CAAC;4BACD,MAAM;oBACd,CAAC;gBACL,CAAC;YACL,CAAC;YAED,IAAI,CAAC,QAAQ,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACpC,WAAW,CAAC,IAAI,CAAC,OAAO,GAAG,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACpD,CAAC;QACL,CAAC;QAED,OAAO,WAAW,CAAC;IACvB,CAAC;IAEO,YAAY;QAChB,OAAO,IAAI,CAAC,OAAO,CAAC,SAAS,IAAI,SAAS,CAAC;IAC/C,CAAC;IAEO,cAAc;QAClB,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,cAAc,EAAE,CAAC;YACxD,OAAO,OAAO,CAAC;QACnB,CAAC;QACD,OAAO,IAAI,CAAC,OAAO,CAAC,WAAW,IAAI,YAAY,CAAC;IACpD,CAAC;IAEO,gBAAgB;QACpB,OAAO,IAAI,CAAC,YAAY,EAAE,KAAK,SAAS,CAAC;IAC7C,CAAC;IAEO,eAAe,CAAC,OAAoB;QACxC,IAAI,OAAO,OAAO,CAAC,OAAO,KAAK,QAAQ,EAAE,CAAC;YACtC,OAAO,OAAO,CAAC,OAAO,CAAC;QAC3B,CAAC;QACD,OAAO,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,OAA2B,CAAC,CAAC;IAC5D,CAAC;IAEO,KAAK,CAAC,sBAAsB,CAChC,SAAwB,EACxB,OAA+B;QAE/B,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,qBAAqB,IAAI,IAAI,CAAC;QAE7D,MAAM,IAAI,GAAG,MAAM,0BAA0B,CAAC,KAAK,IAAI,EAAE;YACrD,MAAM,OAAO,CAAC,IAAI,CAAC;gBACf,iBAAiB,CAAC;oBACd,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,MAAM;oBAC3B,OAAO;oBACP,oBAAoB,EAAE,GAAG,EAAE;wBACvB,YAAY,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAC5B,IAAI,CAAC,OAAO,EACZ,iBAAiB,EACjB,OAAO,CACV,CAAC;oBACN,CAAC;iBACJ,CAAC;gBACF,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;aACjE,CAAC,CAAC;YACH,OAAO,sBAAsB,EAAE,EAAE,IAAI,IAAI,IAAI,CAAC;QAClD,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,IAAI,EAAE,CAAC;YACR,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC;gBAC3B,EAAE,EAAE,eAAe;gBACnB,EAAE,EAAE,KAAK;gBACT,MAAM,EAAE,kBAAkB;gBAC1B,SAAS;aACZ,CAAC,CAAC,CAAC;YACJ,OAAO,EAAE,CAAC;QACd,CAAC;QAED,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC;YAC3B,EAAE,EAAE,eAAe;YACnB,EAAE,EAAE,IAAI;YACR,QAAQ,EAAE,IAAI,CAAC,MAAM;SACxB,CAAC,CAAC,CAAC;QACJ,OAAO,IAAI,CAAC,cAAc,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;IAChD,CAAC;IAEO,KAAK,CAAC,kBAAkB,CAAC,SAAwB,EAAE,OAA+B;QACtF,cAAc;QACd,IAAI,SAAS,CAAC,OAAO,KAAK,OAAO,EAAE,CAAC;YAChC,QAAQ,SAAS,CAAC,KAAK,EAAE,CAAC;gBACtB,KAAK,WAAW;oBACZ,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,aAAa,CAAE,EAAE,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,SAAS,CAAC,YAAY,EAAE,KAAK,EAAE,SAAS,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;oBAC/G,OAAO,IAAI,CAAC,cAAc,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;gBACnD,KAAK,aAAa;oBACd,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,aAAa,CAAE,EAAE,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,SAAS,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC;oBACtF,OAAO,EAAE,CAAC;gBACd,KAAK,MAAM;oBACP,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,aAAa,CAAE,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,CAAC,YAAY,EAAE,KAAK,EAAE,SAAS,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;oBAC1G,OAAO,EAAE,CAAC;gBACd,KAAK,UAAU;oBACX,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,kBAAkB,SAAS,CAAC,YAAY,SAAS,SAAS,CAAC,UAAU,SAAS,SAAS,CAAC,UAAU,EAAE,CAAC,CAAC;oBACxH,OAAO,EAAE,CAAC;gBACd,KAAK,OAAO;oBACR,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,eAAe,SAAS,CAAC,QAAQ,EAAE,CAAC,CAAC;oBACvD,OAAO,EAAE,CAAC;gBACd,KAAK,MAAM;oBACP,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,cAAc,SAAS,CAAC,QAAQ,EAAE,CAAC,CAAC;oBACtD,OAAO,EAAE,CAAC;YAClB,CAAC;QACL,CAAC;QAED,OAAO,EAAE,CAAC;IACd,CAAC;IAEO,cAAc,CAAC,SAAwB,EAAE,OAAe;QAC5D,MAAM,KAAK,GAAG,CAAC,KAAa,EAAE,EAAE,CAC5B,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;QAC7C,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;QACjD,OAAO;YACH,OAAO;YACP,wBAAwB,KAAK,CAAC,SAAS,CAAC,YAAY,CAAC,kBAAkB;YACvE,0BAA0B,KAAK,CAAC,SAAS,CAAC,UAAU,CAAC,oBAAoB;YACzE,eAAe,UAAU,eAAe;YACxC,qCAAqC;YACrC,qBAAqB,KAAK,CAAC,OAAO,CAAC,eAAe;YAClD,QAAQ;SACX,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,CAAC;IAEO,KAAK,CAAC,kBAAkB;QAC5B,MAAM,GAAG,GAAG,8EAA8E,IAAI,CAAC,OAAO,CAAC,KAAK,WAAW,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC;QAEhJ,IAAI,CAAC;YACD,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,CAAgB,GAAG,CAAC,CAAC;YACrD,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC;YAE3B,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;gBACpB,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,YAAY,CAAC;gBACrC,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,IAAI,CAAC,UAAU,GAAG,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC,UAAU;gBAC9E,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,aAAa,CAAE,EAAE,EAAE,EAAE,eAAe,EAAE,CAAC,CAAC,CAAC;YAC/D,CAAC;iBAAM,CAAC;gBACJ,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;YAClD,CAAC;QACL,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,iCAAiC,EAAE,KAAK,CAAC,CAAC;YAC5D,MAAM,KAAK,CAAC;QAChB,CAAC;IACL,CAAC;IAEO,iBAAiB,CAAkC;IAEnD,sBAAsB;QAC1B,qBAAqB;QACrB,IAAI,CAAC,iBAAiB,GAAG,WAAW,CAAC,KAAK,IAAI,EAAE;YAC5C,IAAI,IAAI,CAAC,GAAG,EAAE,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC;gBACrC,IAAI,CAAC;oBACD,MAAM,IAAI,CAAC,kBAAkB,EAAE,CAAC;gBACpC,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACb,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,0CAA0C,EAAE,KAAK,CAAC,CAAC;gBACzE,CAAC;YACL,CAAC;QACL,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,MAAM;IACvB,CAAC;IAED,SAAS;IACT,KAAK,CAAC,WAAW,CAAC,MAAc;QAC5B,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;YACpB,MAAM,IAAI,CAAC,kBAAkB,EAAE,CAAC;QACpC,CAAC;QAED,MAAM,GAAG,GAAG,4DAA4D,IAAI,CAAC,WAAW,WAAW,MAAM,aAAa,CAAC;QAEvH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACtC,OAAO,QAAQ,CAAC,IAAI,CAAC;IACzB,CAAC;IAED;;;;;;OAMG;IACH,KAAK,CAAC,WAAW,CACb,IAA2C,EAC3C,MAAc,EACd,QAAiB;QAEjB,IAAI,CAAC;YACD,sBAAsB;YACtB,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;gBACpB,MAAM,IAAI,CAAC,kBAAkB,EAAE,CAAC;YACpC,CAAC;YACD,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,CAAC;YAC/B,MAAM,GAAG,GAAG,+DAA+D,KAAK,SAAS,IAAI,EAAE,CAAC;YAEhG,cAAc;YACd,MAAM,IAAI,GAAG,IAAI,QAAQ,EAAE,CAAC;YAE5B,cAAc;YACd,MAAM,GAAG,GAAG,IAAI,CAAC,gBAAgB,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;YAClD,MAAM,aAAa,GAAG,QAAQ,IAAI,SAAS,GAAG,EAAE,CAAC;YAEjD,iBAAiB;YACjB,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE;gBACzB,QAAQ,EAAE,aAAa;gBACvB,WAAW,EAAE,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC;aACzC,CAAC,CAAC;YAEH,SAAS;YACT,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,EAAE;gBACzC,OAAO,EAAE;oBACL,GAAG,IAAI,CAAC,UAAU,EAAE;iBACvB;gBACD,aAAa,EAAE,QAAQ;gBACvB,gBAAgB,EAAE,QAAQ;aAC7B,CAAC,CAAC;YAEH,IAAI,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;gBACxB,MAAM,IAAI,KAAK,CACX,aAAa,QAAQ,CAAC,IAAI,CAAC,MAAM,UAAU,QAAQ,CAAC,IAAI,CAAC,OAAO,GAAG,CACtE,CAAC;YACN,CAAC;YAED,OAAO,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC;QAClC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;YACtC,MAAM,KAAK,CAAC;QAChB,CAAC;IACL,CAAC;IAED;;OAEG;IACK,gBAAgB,CAAC,IAAY,EAAE,QAAiB;QACpD,IAAI,QAAQ,EAAE,CAAC;YACX,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;YAC3C,IAAI,KAAK;gBAAE,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC;QAC/B,CAAC;QAED,QAAQ;QACR,MAAM,UAAU,GAA2B;YACvC,KAAK,EAAE,KAAK;YACZ,KAAK,EAAE,KAAK;YACZ,KAAK,EAAE,KAAK;YACZ,KAAK,EAAE,KAAK;SACf,CAAC;QAEF,OAAO,UAAU,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC;IACrC,CAAC;IAED;;OAEG;IACK,cAAc,CAAC,IAAY;QAC/B,MAAM,YAAY,GAA2B;YACzC,KAAK,EAAE,YAAY;YACnB,KAAK,EAAE,YAAY;YACnB,KAAK,EAAE,WAAW;YAClB,KAAK,EAAE,YAAY;SACtB,CAAC;QAEF,OAAO,YAAY,CAAC,IAAI,CAAC,IAAI,0BAA0B,CAAC;IAC5D,CAAC;IAED,kDAAkD;IAE1C,SAAS;QACb,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,cAAe,CAAC;QACzC,OAAO,MAAM,CAAC,IAAI,CAAC,GAAG,GAAG,GAAG,EAAE,QAAQ,CAAC,CAAC;IAC5C,CAAC;IAED,gDAAgD;IACxC,kBAAkB,CAAC,OAAe;QACtC,IAAI,OAAO,CAAC,MAAM,GAAG,EAAE;YAAE,OAAO,KAAK,CAAC;QACtC,OAAO,wBAAwB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAClD,CAAC;IAED;;OAEG;IACK,cAAc,CAAC,SAAiB;QACpC,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC;QAChC,MAAM,EAAE,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QAClC,MAAM,QAAQ,GAAG,gBAAgB,CAAC,aAAa,EAAE,MAAM,EAAE,EAAE,CAAC,CAAC;QAC7D,QAAQ,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;QAE/B,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC;YAC5B,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;YACjD,QAAQ,CAAC,KAAK,EAAE;SACnB,CAAC,CAAC;QAEH,MAAM,GAAG,GAAG,SAAS,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QAC5C,MAAM,OAAO,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC,EAAE,SAAS,CAAC,MAAM,GAAG,GAAG,CAAC,CAAC;QAE9D,MAAM,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;QACxC,MAAM,KAAK,GAAG,OAAO,CAAC,QAAQ,CAAC,EAAE,EAAE,EAAE,GAAG,MAAM,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QACjE,MAAM,KAAK,GAAG,OAAO,CAAC,QAAQ,CAAC,EAAE,GAAG,MAAM,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QAE7D,IAAI,KAAK,KAAK,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;YAC/B,MAAM,IAAI,KAAK,CAAC,4BAA4B,IAAI,CAAC,OAAO,CAAC,KAAK,SAAS,KAAK,EAAE,CAAC,CAAC;QACpF,CAAC;QAED,OAAO,KAAK,CAAC;IACjB,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,cAAc,CACxB,YAAoB,EACpB,YAAoB,EACpB,SAAiB,EACjB,KAAa;QAEb,wBAAwB;QACxB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,YAAY,CAAC,CAAC;QACxD,MAAM,OAAO,GAAI,MAAc,EAAE,OAAO,CAAC;QACzC,IAAI,CAAC,OAAO;YAAE,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAC;QAE5E,mBAAmB;QACnB,MAAM,QAAQ,GAAG,UAAU,CAAC,MAAM,CAAC;aAC9B,MAAM,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;aACvE,MAAM,CAAC,KAAK,CAAC,CAAC;QACnB,IAAI,QAAQ,KAAK,YAAY,EAAE,CAAC;YAC5B,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC;QACzD,CAAC;QAED,iBAAiB;QACjB,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC;QAChC,MAAM,EAAE,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QAClC,MAAM,QAAQ,GAAG,gBAAgB,CAAC,aAAa,EAAE,MAAM,EAAE,EAAE,CAAC,CAAC;QAC7D,QAAQ,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;QAE/B,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC;YAC5B,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;YAC/C,QAAQ,CAAC,KAAK,EAAE;SACnB,CAAC,CAAC;QAEH,eAAe;QACf,MAAM,GAAG,GAAG,SAAS,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QAC5C,MAAM,OAAO,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC,EAAE,SAAS,CAAC,MAAM,GAAG,GAAG,CAAC,CAAC;QAE9D,qEAAqE;QACrE,MAAM,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;QACxC,MAAM,UAAU,GAAG,OAAO,CAAC,QAAQ,CAAC,EAAE,EAAE,EAAE,GAAG,MAAM,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QACtE,MAAM,KAAK,GAAG,OAAO,CAAC,QAAQ,CAAC,EAAE,GAAG,MAAM,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QAE7D,IAAI,KAAK,KAAK,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;YAC/B,MAAM,IAAI,KAAK,CAAC,4BAA4B,IAAI,CAAC,OAAO,CAAC,KAAK,SAAS,KAAK,EAAE,CAAC,CAAC;QACpF,CAAC;QAED,OAAO,UAAU,CAAC;IACtB,CAAC;IAED;;OAEG;IACK,cAAc,CAAC,QAAgB,EAAE,gBAAyB;QAC9D,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC;QAChC,MAAM,EAAE,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QAElC,uDAAuD;QACvD,MAAM,MAAM,GAAG,WAAW,CAAC,EAAE,CAAC,CAAC;QAC/B,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QAC7C,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QACzD,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAC/B,MAAM,CAAC,aAAa,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QAEvC,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC;QAEpE,YAAY;QACZ,MAAM,SAAS,GAAG,EAAE,CAAC;QACrB,MAAM,MAAM,GAAG,SAAS,GAAG,CAAC,SAAS,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;QAC1D,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAC5C,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC;QAElD,iBAAiB;QACjB,MAAM,MAAM,GAAG,cAAc,CAAC,aAAa,EAAE,MAAM,EAAE,EAAE,CAAC,CAAC;QACzD,MAAM,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;QAC7B,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;QACzE,MAAM,UAAU,GAAG,SAAS,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QAEhD,oCAAoC;QACpC,MAAM,SAAS,GAAG,gBAAgB,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC;QAC/E,MAAM,KAAK,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QAC7C,MAAM,SAAS,GAAG,UAAU,CAAC,MAAM,CAAC;aAC/B,MAAM,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,UAAU,CAAC,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;aAC1E,MAAM,CAAC,KAAK,CAAC,CAAC;QAEnB,OAAO;YACH,OAAO;YACP,qBAAqB,UAAU,eAAe;YAC9C,0BAA0B,SAAS,oBAAoB;YACvD,cAAc,SAAS,cAAc;YACrC,mBAAmB,KAAK,aAAa;YACrC,QAAQ;SACX,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACjB,CAAC;CACJ;AAED,eAAe"}
@@ -0,0 +1,8 @@
1
+ export type PassiveReplyCapture = {
2
+ /** 同一次 webhook 内最后一次文本出站(被动回复仅支持一条) */
3
+ text: string | null;
4
+ };
5
+ export declare function getPassiveReplyCapture(): PassiveReplyCapture | undefined;
6
+ export declare function runWithPassiveReplyCapture<T>(fn: () => Promise<T>): Promise<T>;
7
+ export declare function recordPassiveReplyText(text: string): void;
8
+ //# sourceMappingURL=passive-reply.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"passive-reply.d.ts","sourceRoot":"","sources":["../src/passive-reply.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,mBAAmB,GAAG;IAC9B,uCAAuC;IACvC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB,CAAC;AAIF,wBAAgB,sBAAsB,IAAI,mBAAmB,GAAG,SAAS,CAExE;AAED,wBAAsB,0BAA0B,CAAC,CAAC,EAC9C,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GACrB,OAAO,CAAC,CAAC,CAAC,CAGZ;AAED,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAIzD"}
@@ -0,0 +1,16 @@
1
+ import { AsyncLocalStorage } from "node:async_hooks";
2
+ const passiveReplyStorage = new AsyncLocalStorage();
3
+ export function getPassiveReplyCapture() {
4
+ return passiveReplyStorage.getStore();
5
+ }
6
+ export async function runWithPassiveReplyCapture(fn) {
7
+ const capture = { text: null };
8
+ return passiveReplyStorage.run(capture, fn);
9
+ }
10
+ export function recordPassiveReplyText(text) {
11
+ const capture = passiveReplyStorage.getStore();
12
+ if (!capture || !text.trim())
13
+ return;
14
+ capture.text = text;
15
+ }
16
+ //# sourceMappingURL=passive-reply.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"passive-reply.js","sourceRoot":"","sources":["../src/passive-reply.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAOrD,MAAM,mBAAmB,GAAG,IAAI,iBAAiB,EAAuB,CAAC;AAEzE,MAAM,UAAU,sBAAsB;IAClC,OAAO,mBAAmB,CAAC,QAAQ,EAAE,CAAC;AAC1C,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,0BAA0B,CAC5C,EAAoB;IAEpB,MAAM,OAAO,GAAwB,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IACpD,OAAO,mBAAmB,CAAC,GAAG,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;AAChD,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,IAAY;IAC/C,MAAM,OAAO,GAAG,mBAAmB,CAAC,QAAQ,EAAE,CAAC;IAC/C,IAAI,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE;QAAE,OAAO;IACrC,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;AACxB,CAAC"}
package/lib/types.d.ts CHANGED
@@ -10,6 +10,19 @@ export interface WeChatMPConfig {
10
10
  encodingAESKey?: string;
11
11
  path: string;
12
12
  encrypt?: boolean;
13
+ /**
14
+ * plain:明文入站/出站
15
+ * compatible:入站可解密,被动回复用明文(微信兼容模式推荐)
16
+ * secure:入站/出站均加密
17
+ */
18
+ encryptMode?: "plain" | "compatible" | "secure";
19
+ /**
20
+ * passive:订阅号默认,在 webhook 响应内被动回复(5 秒内)
21
+ * customer_service:走客服消息 API(需接口权限)
22
+ */
23
+ replyMode?: "passive" | "customer_service";
24
+ /** 被动回复等待入站处理的最长时间(毫秒),默认 4500 */
25
+ passiveReplyTimeoutMs?: number;
13
26
  }
14
27
  export interface WeChatMessage {
15
28
  ToUserName: string;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,WAAW,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,aAAa;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,aAAa;IAC5B,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,WAAW,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;;OAIG;IACH,WAAW,CAAC,EAAE,OAAO,GAAG,YAAY,GAAG,QAAQ,CAAC;IAChD;;;OAGG;IACH,SAAS,CAAC,EAAE,SAAS,GAAG,kBAAkB,CAAC;IAC3C,kCAAkC;IAClC,qBAAqB,CAAC,EAAE,MAAM,CAAC;CAChC;AAED,MAAM,WAAW,aAAa;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,aAAa;IAC5B,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zhin.js/adapter-wechat-mp",
3
- "version": "0.1.80",
3
+ "version": "0.1.81",
4
4
  "type": "module",
5
5
  "description": "Zhin.js adapter for WeChat Official Account (微信公众号)",
6
6
  "main": "./lib/index.js",
@@ -11,15 +11,15 @@
11
11
  "form-data": "^4.0.0"
12
12
  },
13
13
  "peerDependencies": {
14
- "@zhin.js/host-router": "0.0.3",
15
- "zhin.js": "1.0.92"
14
+ "zhin.js": "1.0.93",
15
+ "@zhin.js/host-router": "0.0.3"
16
16
  },
17
17
  "devDependencies": {
18
18
  "@types/xml2js": "^0.4.14",
19
19
  "@types/koa": "^3.0.3",
20
20
  "@types/node": "^25.9.1",
21
21
  "typescript": "^6.0.3",
22
- "zhin.js": "1.0.92"
22
+ "zhin.js": "1.0.93"
23
23
  },
24
24
  "keywords": [
25
25
  "zhin",
package/src/bot.ts CHANGED
@@ -6,10 +6,36 @@ import * as xml2js from "xml2js";
6
6
  import { createHash, createDecipheriv, createCipheriv, randomBytes } from "crypto";
7
7
  import { EventEmitter } from "events";
8
8
  import FormData from "form-data";
9
- import { formatCompact, Bot, Message, MessageSegment, segment, SendContent, SendOptions } from 'zhin.js';
9
+ import {
10
+ formatCompact,
11
+ Bot,
12
+ Message,
13
+ MessageSegment,
14
+ segment,
15
+ SendContent,
16
+ SendOptions,
17
+ runInboundMessage,
18
+ truncatePreview,
19
+ } from 'zhin.js';
10
20
  import { registerFetchRoute, type Router, type RouterContext } from "@zhin.js/host-router/router";
11
21
  import type { WeChatMPConfig, WeChatMessage, WeChatAPIResponse, TokenResponse } from "./types.js";
12
22
  import type { WeChatMPAdapter } from "./adapter.js";
23
+ import {
24
+ getPassiveReplyCapture,
25
+ recordPassiveReplyText,
26
+ runWithPassiveReplyCapture,
27
+ } from "./passive-reply.js";
28
+
29
+ function queryParam(value: unknown): string {
30
+ if (typeof value === "string") return value;
31
+ if (Array.isArray(value) && typeof value[0] === "string") return value[0];
32
+ return "";
33
+ }
34
+
35
+ /** URL 查询里的 Base64 可能把 `+` 解码成空格 */
36
+ function normalizeEchostrParam(echostr: string): string {
37
+ return echostr.replace(/ /g, "+");
38
+ }
13
39
 
14
40
  export class WeChatMPBot extends EventEmitter implements Bot<WeChatMPConfig, WeChatMessage> {
15
41
  $config: WeChatMPConfig;
@@ -44,9 +70,9 @@ export class WeChatMPBot extends EventEmitter implements Bot<WeChatMPConfig, WeC
44
70
  this.handleVerification(ctx);
45
71
  });
46
72
 
47
- // 接收微信消息 (POST)
48
- registerFetchRoute(this.router, "POST", path, (ctx: RouterContext) => {
49
- void this.handleMessage(ctx);
73
+ // 接收微信消息 (POST);必须 await,否则 Koa 会在被动回复写入 ctx.body 前就结束响应
74
+ registerFetchRoute(this.router, "POST", path, async (ctx: RouterContext) => {
75
+ await this.handleMessage(ctx);
50
76
  });
51
77
  }
52
78
 
@@ -80,32 +106,129 @@ export class WeChatMPBot extends EventEmitter implements Bot<WeChatMPConfig, WeC
80
106
  }
81
107
 
82
108
  private handleVerification(ctx: RouterContext): void {
83
- const { signature, timestamp, nonce, echostr } = ctx.query;
84
-
85
- if (this.verifySignature(
86
- signature as string,
87
- timestamp as string,
88
- nonce as string
89
- )) {
90
- this.logger.info(formatCompact( { op: "verify" }));
91
- ctx.body = echostr;
92
- } else {
93
- this.logger.error('WeChat verification failed');
109
+ const signature = queryParam(ctx.query.signature);
110
+ const msgSignature = queryParam(ctx.query.msg_signature);
111
+ const timestamp = queryParam(ctx.query.timestamp);
112
+ const nonce = queryParam(ctx.query.nonce);
113
+ const echostr = normalizeEchostrParam(queryParam(ctx.query.echostr));
114
+
115
+ const secureMode = !!(this.$config.encrypt && this.$config.encodingAESKey);
116
+ // GET 验证:signature 始终为 3 参数;msg_signature(若存在)为 4 参数含 echostr
117
+ const signMode = msgSignature ? "msg_signature" : "signature";
118
+ const signToCheck = msgSignature || signature;
119
+ const signPayload = msgSignature
120
+ ? { signature: msgSignature, timestamp, nonce, echostr }
121
+ : { signature, timestamp, nonce };
122
+ const signFields = msgSignature ? 4 : 3;
123
+
124
+ this.logger.info(formatCompact({
125
+ op: "verify",
126
+ stage: "recv",
127
+ path: ctx.path,
128
+ secureMode,
129
+ signMode,
130
+ hasSignature: !!signature,
131
+ hasMsgSignature: !!msgSignature,
132
+ hasEchostr: !!echostr,
133
+ timestamp,
134
+ nonce,
135
+ echostrLen: echostr.length,
136
+ tokenLen: this.$config.token.length,
137
+ }));
138
+
139
+ if (!signToCheck || !timestamp || !nonce) {
140
+ this.logger.error(formatCompact({
141
+ op: "verify",
142
+ stage: "sign",
143
+ ok: false,
144
+ error: "missing_query_params",
145
+ }));
146
+ ctx.status = 403;
147
+ ctx.body = "Forbidden";
148
+ return;
149
+ }
150
+
151
+ if (!this.verifySignature(signPayload)) {
152
+ const expected = this.computeSignatureHash(signPayload);
153
+ this.logger.error(formatCompact({
154
+ op: "verify",
155
+ stage: "sign",
156
+ ok: false,
157
+ secureMode,
158
+ signMode,
159
+ signFields,
160
+ expectedPrefix: expected.slice(0, 8),
161
+ gotPrefix: signToCheck.slice(0, 8),
162
+ }));
94
163
  ctx.status = 403;
95
- ctx.body = 'Forbidden';
164
+ ctx.body = "Forbidden";
165
+ return;
96
166
  }
167
+
168
+ this.logger.info(formatCompact({
169
+ op: "verify",
170
+ stage: "sign",
171
+ ok: true,
172
+ signMode,
173
+ signFields,
174
+ }));
175
+
176
+ let body = echostr;
177
+ if (secureMode && echostr && this.isEncryptedEchostr(echostr)) {
178
+ try {
179
+ body = this.decryptEchostr(echostr);
180
+ this.logger.info(formatCompact({
181
+ op: "verify",
182
+ stage: "decrypt",
183
+ ok: true,
184
+ mode: "aes",
185
+ plainLen: body.length,
186
+ }));
187
+ } catch (error) {
188
+ this.logger.error(formatCompact({
189
+ op: "verify",
190
+ stage: "decrypt",
191
+ ok: false,
192
+ mode: "aes",
193
+ error: error instanceof Error ? error.message : String(error),
194
+ }));
195
+ ctx.status = 403;
196
+ ctx.body = "Forbidden";
197
+ return;
198
+ }
199
+ } else if (secureMode && echostr) {
200
+ this.logger.info(formatCompact({
201
+ op: "verify",
202
+ stage: "decrypt",
203
+ ok: true,
204
+ mode: "plain_echostr",
205
+ plainLen: body.length,
206
+ }));
207
+ }
208
+
209
+ this.logger.info(formatCompact({
210
+ op: "verify",
211
+ stage: "done",
212
+ ok: true,
213
+ replyLen: body.length,
214
+ }));
215
+ ctx.body = body;
97
216
  }
98
217
 
99
218
  private async handleMessage(ctx: RouterContext): Promise<void> {
100
219
  try {
101
- const { signature, timestamp, nonce, msg_signature, encrypt_type } = ctx.query;
220
+ const signature = queryParam(ctx.query.signature);
221
+ const timestamp = queryParam(ctx.query.timestamp);
222
+ const nonce = queryParam(ctx.query.nonce);
223
+ const msg_signature = queryParam(ctx.query.msg_signature);
224
+ const encrypt_type = queryParam(ctx.query.encrypt_type);
102
225
 
103
226
  // 验证签名
104
- if (!this.verifySignature(
105
- signature as string,
106
- timestamp as string,
107
- nonce as string
108
- )) {
227
+ if (!this.verifySignature({
228
+ signature,
229
+ timestamp,
230
+ nonce,
231
+ })) {
109
232
  this.logger.error('Invalid signature');
110
233
  ctx.status = 403;
111
234
  ctx.body = 'Forbidden';
@@ -129,18 +252,45 @@ export class WeChatMPBot extends EventEmitter implements Bot<WeChatMPConfig, WeC
129
252
 
130
253
  if (wechatMessage) {
131
254
  const message = this.$formatMessage(wechatMessage);
132
- this.adapter.emit('message.receive', message);
133
-
134
- // 处理被动回复
255
+ this.logger.info(formatCompact({
256
+ recv: `private(${message.$channel.id})`,
257
+ bot: message.$bot,
258
+ preview: truncatePreview(segment.raw(message.$content)),
259
+ replyMode: this.getReplyMode(),
260
+ encryptMode: this.getEncryptMode(),
261
+ encryptType: encrypt_type || "plain",
262
+ }));
263
+
135
264
  let replyXML = await this.handlePassiveReply(wechatMessage, message);
136
265
 
137
- // AES 加密模式:加密回复
138
- if (replyXML && this.$config.encrypt && this.$config.encodingAESKey) {
139
- replyXML = this.encryptMessage(replyXML);
266
+ if (!replyXML && this.usesPassiveReply()) {
267
+ replyXML = await this.collectPassiveReplyXml(wechatMessage, message);
268
+ } else if (!replyXML) {
269
+ this.adapter.emit("message.receive", message);
140
270
  }
141
271
 
142
- ctx.set('Content-Type', 'text/xml');
143
- ctx.body = replyXML || 'success';
272
+ // 仅安全模式加密被动回复;兼容模式可明文回包(微信官方允许)
273
+ const encryptReply = !!(
274
+ replyXML &&
275
+ this.$config.encodingAESKey &&
276
+ encrypt_type === "aes" &&
277
+ this.getEncryptMode() === "secure"
278
+ );
279
+ if (encryptReply) {
280
+ replyXML = this.encryptMessage(replyXML, timestamp);
281
+ }
282
+
283
+ ctx.set("Content-Type", "text/xml");
284
+ ctx.body = replyXML || "success";
285
+ if (replyXML) {
286
+ this.logger.info(formatCompact({
287
+ op: "passive_reply",
288
+ stage: "sent",
289
+ encrypted: encryptReply,
290
+ encryptMode: this.getEncryptMode(),
291
+ bodyLen: replyXML.length,
292
+ }));
293
+ }
144
294
  } else {
145
295
  ctx.body = 'success';
146
296
  }
@@ -150,12 +300,29 @@ export class WeChatMPBot extends EventEmitter implements Bot<WeChatMPConfig, WeC
150
300
  }
151
301
  }
152
302
 
153
- private verifySignature(signature: string, timestamp: string, nonce: string): boolean {
303
+ private computeSignatureHash(params: {
304
+ timestamp: string;
305
+ nonce: string;
306
+ echostr?: string;
307
+ }): string {
308
+ const { timestamp, nonce, echostr } = params;
154
309
  const token = this.$config.token;
155
- const arr = [token, timestamp, nonce].sort();
156
- const str = arr.join('');
157
- const hash = createHash('sha1').update(str).digest('hex');
158
- return hash === signature;
310
+ const arr = echostr
311
+ ? [token, timestamp, nonce, echostr]
312
+ : [token, timestamp, nonce];
313
+ arr.sort();
314
+ return createHash("sha1").update(arr.join("")).digest("hex");
315
+ }
316
+
317
+ private verifySignature(params: {
318
+ signature: string;
319
+ timestamp: string;
320
+ nonce: string;
321
+ echostr?: string;
322
+ }): boolean {
323
+ const { signature, timestamp, nonce, echostr } = params;
324
+ if (!signature || !timestamp || !nonce) return false;
325
+ return this.computeSignatureHash({ timestamp, nonce, echostr }) === signature;
159
326
  }
160
327
 
161
328
  private async parseXMLMessage(xmlString: string): Promise<WeChatMessage | null> {
@@ -273,14 +440,27 @@ export class WeChatMPBot extends EventEmitter implements Bot<WeChatMPConfig, WeC
273
440
  }
274
441
 
275
442
  async $sendMessage(options: SendOptions): Promise<string> {
276
- try {
277
- // 公众号主动发送消息需要通过客服消息API
278
- const msgId = await this.sendCustomerServiceMessage(options);
279
- return msgId;
280
- } catch (error) {
281
- this.logger.error('Failed to send WeChat message:', error);
282
- throw error;
443
+ if (getPassiveReplyCapture()) {
444
+ const text = this.extractSendText(options);
445
+ recordPassiveReplyText(text);
446
+ return `passive_${Date.now()}`;
447
+ }
448
+
449
+ if (!this.usesPassiveReply()) {
450
+ try {
451
+ return await this.sendCustomerServiceMessage(options);
452
+ } catch (error) {
453
+ this.logger.error("Failed to send WeChat message:", error);
454
+ throw error;
455
+ }
283
456
  }
457
+
458
+ this.logger.warn(formatCompact({
459
+ op: "send",
460
+ skip: "passive_outside_webhook",
461
+ bot: this.$config.name,
462
+ }));
463
+ return `passive_skipped_${Date.now()}`;
284
464
  }
285
465
  async $recallMessage(id: string): Promise<void> {
286
466
  // 公众号不支持撤回消息
@@ -373,6 +553,69 @@ export class WeChatMPBot extends EventEmitter implements Bot<WeChatMPConfig, WeC
373
553
  return messageData;
374
554
  }
375
555
 
556
+ private getReplyMode(): "passive" | "customer_service" {
557
+ return this.$config.replyMode ?? "passive";
558
+ }
559
+
560
+ private getEncryptMode(): "plain" | "compatible" | "secure" {
561
+ if (!this.$config.encrypt || !this.$config.encodingAESKey) {
562
+ return "plain";
563
+ }
564
+ return this.$config.encryptMode ?? "compatible";
565
+ }
566
+
567
+ private usesPassiveReply(): boolean {
568
+ return this.getReplyMode() === "passive";
569
+ }
570
+
571
+ private extractSendText(options: SendOptions): string {
572
+ if (typeof options.content === "string") {
573
+ return options.content;
574
+ }
575
+ return segment.raw(options.content as MessageSegment[]);
576
+ }
577
+
578
+ private async collectPassiveReplyXml(
579
+ wechatMsg: WeChatMessage,
580
+ message: Message<WeChatMessage>,
581
+ ): Promise<string> {
582
+ const timeoutMs = this.$config.passiveReplyTimeoutMs ?? 4500;
583
+
584
+ const text = await runWithPassiveReplyCapture(async () => {
585
+ await Promise.race([
586
+ runInboundMessage({
587
+ plugin: this.adapter.plugin,
588
+ message,
589
+ emitAdapterObservers: () => {
590
+ EventEmitter.prototype.emit.call(
591
+ this.adapter,
592
+ "message.receive",
593
+ message,
594
+ );
595
+ },
596
+ }),
597
+ new Promise<void>((resolve) => setTimeout(resolve, timeoutMs)),
598
+ ]);
599
+ return getPassiveReplyCapture()?.text ?? null;
600
+ });
601
+ if (!text) {
602
+ this.logger.warn(formatCompact({
603
+ op: "passive_reply",
604
+ ok: false,
605
+ reason: "timeout_or_empty",
606
+ timeoutMs,
607
+ }));
608
+ return "";
609
+ }
610
+
611
+ this.logger.info(formatCompact({
612
+ op: "passive_reply",
613
+ ok: true,
614
+ plainLen: text.length,
615
+ }));
616
+ return this.buildTextReply(wechatMsg, text);
617
+ }
618
+
376
619
  private async handlePassiveReply(wechatMsg: WeChatMessage, message: Message<WeChatMessage>): Promise<string> {
377
620
  // 事件类型消息的自动回复
378
621
  if (wechatMsg.MsgType === 'event') {
@@ -402,18 +645,18 @@ export class WeChatMPBot extends EventEmitter implements Bot<WeChatMPConfig, WeC
402
645
  }
403
646
 
404
647
  private buildTextReply(wechatMsg: WeChatMessage, content: string): string {
405
- const replyMsg = {
406
- xml: {
407
- ToUserName: wechatMsg.FromUserName,
408
- FromUserName: wechatMsg.ToUserName,
409
- CreateTime: Math.floor(Date.now() / 1000),
410
- MsgType: 'text',
411
- Content: content
412
- }
413
- };
414
-
415
- const builder = new xml2js.Builder({ rootName: 'xml', headless: true });
416
- return builder.buildObject(replyMsg);
648
+ const cdata = (value: string) =>
649
+ value.replace(/]]>/g, "]]]]><![CDATA[>");
650
+ const createTime = Math.floor(Date.now() / 1000);
651
+ return [
652
+ "<xml>",
653
+ `<ToUserName><![CDATA[${cdata(wechatMsg.FromUserName)}]]></ToUserName>`,
654
+ `<FromUserName><![CDATA[${cdata(wechatMsg.ToUserName)}]]></FromUserName>`,
655
+ `<CreateTime>${createTime}</CreateTime>`,
656
+ `<MsgType><![CDATA[text]]></MsgType>`,
657
+ `<Content><![CDATA[${cdata(content)}]]></Content>`,
658
+ "</xml>",
659
+ ].join("");
417
660
  }
418
661
 
419
662
  private async refreshAccessToken(): Promise<void> {
@@ -559,6 +802,40 @@ export class WeChatMPBot extends EventEmitter implements Bot<WeChatMPConfig, WeC
559
802
  return Buffer.from(key + '=', 'base64');
560
803
  }
561
804
 
805
+ /** 微信安全模式加密 echostr 为较长 Base64;明文/兼容模式多为短字符串 */
806
+ private isEncryptedEchostr(echostr: string): boolean {
807
+ if (echostr.length < 32) return false;
808
+ return /^[A-Za-z0-9+/]+={0,2}$/.test(echostr);
809
+ }
810
+
811
+ /**
812
+ * 解密安全模式 URL 验证中的 echostr
813
+ */
814
+ private decryptEchostr(encrypted: string): string {
815
+ const aesKey = this.getAESKey();
816
+ const iv = aesKey.subarray(0, 16);
817
+ const decipher = createDecipheriv("aes-256-cbc", aesKey, iv);
818
+ decipher.setAutoPadding(false);
819
+
820
+ const decrypted = Buffer.concat([
821
+ decipher.update(Buffer.from(encrypted, "base64")),
822
+ decipher.final(),
823
+ ]);
824
+
825
+ const pad = decrypted[decrypted.length - 1];
826
+ const content = decrypted.subarray(0, decrypted.length - pad);
827
+
828
+ const msgLen = content.readUInt32BE(16);
829
+ const plain = content.subarray(20, 20 + msgLen).toString("utf8");
830
+ const appId = content.subarray(20 + msgLen).toString("utf8");
831
+
832
+ if (appId !== this.$config.appId) {
833
+ throw new Error(`AppID mismatch: expected ${this.$config.appId}, got ${appId}`);
834
+ }
835
+
836
+ return plain;
837
+ }
838
+
562
839
  /**
563
840
  * 解密微信推送的加密消息
564
841
  */
@@ -611,7 +888,7 @@ export class WeChatMPBot extends EventEmitter implements Bot<WeChatMPConfig, WeC
611
888
  /**
612
889
  * 加密被动回复消息
613
890
  */
614
- private encryptMessage(replyXml: string): string {
891
+ private encryptMessage(replyXml: string, requestTimestamp?: string): string {
615
892
  const aesKey = this.getAESKey();
616
893
  const iv = aesKey.subarray(0, 16);
617
894
 
@@ -636,8 +913,8 @@ export class WeChatMPBot extends EventEmitter implements Bot<WeChatMPConfig, WeC
636
913
  const encrypted = Buffer.concat([cipher.update(padded), cipher.final()]);
637
914
  const encryptStr = encrypted.toString('base64');
638
915
 
639
- // 签名
640
- const timestamp = Math.floor(Date.now() / 1000).toString();
916
+ // 签名(TimeStamp 优先复用入站请求值,与微信官方示例一致)
917
+ const timestamp = requestTimestamp || Math.floor(Date.now() / 1000).toString();
641
918
  const nonce = randomBytes(8).toString('hex');
642
919
  const signature = createHash('sha1')
643
920
  .update([this.$config.token, timestamp, nonce, encryptStr].sort().join(''))
@@ -0,0 +1,25 @@
1
+ import { AsyncLocalStorage } from "node:async_hooks";
2
+
3
+ export type PassiveReplyCapture = {
4
+ /** 同一次 webhook 内最后一次文本出站(被动回复仅支持一条) */
5
+ text: string | null;
6
+ };
7
+
8
+ const passiveReplyStorage = new AsyncLocalStorage<PassiveReplyCapture>();
9
+
10
+ export function getPassiveReplyCapture(): PassiveReplyCapture | undefined {
11
+ return passiveReplyStorage.getStore();
12
+ }
13
+
14
+ export async function runWithPassiveReplyCapture<T>(
15
+ fn: () => Promise<T>,
16
+ ): Promise<T> {
17
+ const capture: PassiveReplyCapture = { text: null };
18
+ return passiveReplyStorage.run(capture, fn);
19
+ }
20
+
21
+ export function recordPassiveReplyText(text: string): void {
22
+ const capture = passiveReplyStorage.getStore();
23
+ if (!capture || !text.trim()) return;
24
+ capture.text = text;
25
+ }
package/src/types.ts CHANGED
@@ -10,6 +10,19 @@ export interface WeChatMPConfig {
10
10
  encodingAESKey?: string;
11
11
  path: string;
12
12
  encrypt?: boolean;
13
+ /**
14
+ * plain:明文入站/出站
15
+ * compatible:入站可解密,被动回复用明文(微信兼容模式推荐)
16
+ * secure:入站/出站均加密
17
+ */
18
+ encryptMode?: "plain" | "compatible" | "secure";
19
+ /**
20
+ * passive:订阅号默认,在 webhook 响应内被动回复(5 秒内)
21
+ * customer_service:走客服消息 API(需接口权限)
22
+ */
23
+ replyMode?: "passive" | "customer_service";
24
+ /** 被动回复等待入站处理的最长时间(毫秒),默认 4500 */
25
+ passiveReplyTimeoutMs?: number;
13
26
  }
14
27
 
15
28
  export interface WeChatMessage {