@tencent-weixin/openclaw-weixin 2.3.1 → 2.4.2

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.
Files changed (102) hide show
  1. package/dist/index.js +16 -0
  2. package/dist/index.js.map +1 -0
  3. package/dist/src/api/api.js +374 -0
  4. package/dist/src/api/api.js.map +1 -0
  5. package/dist/src/api/config-cache.js +64 -0
  6. package/dist/src/api/config-cache.js.map +1 -0
  7. package/dist/src/api/session-guard.js +49 -0
  8. package/dist/src/api/session-guard.js.map +1 -0
  9. package/dist/src/api/types.js +35 -0
  10. package/dist/src/api/types.js.map +1 -0
  11. package/dist/src/auth/accounts.js +326 -0
  12. package/dist/src/auth/accounts.js.map +1 -0
  13. package/dist/src/auth/login-qr.js +332 -0
  14. package/dist/src/auth/login-qr.js.map +1 -0
  15. package/dist/src/auth/pairing.js +104 -0
  16. package/dist/src/auth/pairing.js.map +1 -0
  17. package/dist/src/cdn/aes-ecb.js +19 -0
  18. package/dist/src/cdn/aes-ecb.js.map +1 -0
  19. package/dist/src/cdn/cdn-upload.js +73 -0
  20. package/dist/src/cdn/cdn-upload.js.map +1 -0
  21. package/dist/src/cdn/cdn-url.js +14 -0
  22. package/dist/src/cdn/cdn-url.js.map +1 -0
  23. package/dist/src/cdn/pic-decrypt.js +89 -0
  24. package/dist/src/cdn/pic-decrypt.js.map +1 -0
  25. package/dist/src/cdn/upload.js +106 -0
  26. package/dist/src/cdn/upload.js.map +1 -0
  27. package/dist/src/channel.js +460 -0
  28. package/dist/src/channel.js.map +1 -0
  29. package/dist/src/compat.js +67 -0
  30. package/dist/src/compat.js.map +1 -0
  31. package/dist/src/config/config-schema.js +19 -0
  32. package/dist/src/config/config-schema.js.map +1 -0
  33. package/dist/src/media/media-download.js +95 -0
  34. package/dist/src/media/media-download.js.map +1 -0
  35. package/dist/src/media/mime.js +73 -0
  36. package/dist/src/media/mime.js.map +1 -0
  37. package/dist/src/media/silk-transcode.js +64 -0
  38. package/dist/src/media/silk-transcode.js.map +1 -0
  39. package/dist/src/media/voice-outbound.js +177 -0
  40. package/dist/src/media/voice-outbound.js.map +1 -0
  41. package/dist/src/messaging/abort-fence.js +70 -0
  42. package/dist/src/messaging/abort-fence.js.map +1 -0
  43. package/dist/src/messaging/buttons.js +117 -0
  44. package/dist/src/messaging/buttons.js.map +1 -0
  45. package/dist/src/messaging/debug-mode.js +63 -0
  46. package/dist/src/messaging/debug-mode.js.map +1 -0
  47. package/dist/src/messaging/error-notice.js +24 -0
  48. package/dist/src/messaging/error-notice.js.map +1 -0
  49. package/dist/src/messaging/inbound.js +201 -0
  50. package/dist/src/messaging/inbound.js.map +1 -0
  51. package/dist/src/messaging/lane-key.js +66 -0
  52. package/dist/src/messaging/lane-key.js.map +1 -0
  53. package/dist/src/messaging/markdown-filter.js +368 -0
  54. package/dist/src/messaging/markdown-filter.js.map +1 -0
  55. package/dist/src/messaging/merged-record.js +149 -0
  56. package/dist/src/messaging/merged-record.js.map +1 -0
  57. package/dist/src/messaging/model-buttons.js +182 -0
  58. package/dist/src/messaging/model-buttons.js.map +1 -0
  59. package/dist/src/messaging/model-callback-handler.js +133 -0
  60. package/dist/src/messaging/model-callback-handler.js.map +1 -0
  61. package/dist/src/messaging/outbound-hooks.js +56 -0
  62. package/dist/src/messaging/outbound-hooks.js.map +1 -0
  63. package/dist/src/messaging/process-message.js +381 -0
  64. package/dist/src/messaging/process-message.js.map +1 -0
  65. package/dist/src/messaging/send-media.js +54 -0
  66. package/dist/src/messaging/send-media.js.map +1 -0
  67. package/dist/src/messaging/send.js +182 -0
  68. package/dist/src/messaging/send.js.map +1 -0
  69. package/dist/src/messaging/slash-commands.js +70 -0
  70. package/dist/src/messaging/slash-commands.js.map +1 -0
  71. package/dist/src/monitor/lane-scheduler.js +46 -0
  72. package/dist/src/monitor/lane-scheduler.js.map +1 -0
  73. package/dist/src/monitor/monitor.js +143 -0
  74. package/dist/src/monitor/monitor.js.map +1 -0
  75. package/dist/src/runtime.js +54 -0
  76. package/dist/src/runtime.js.map +1 -0
  77. package/dist/src/storage/state-dir.js +9 -0
  78. package/dist/src/storage/state-dir.js.map +1 -0
  79. package/dist/src/storage/sync-buf.js +64 -0
  80. package/dist/src/storage/sync-buf.js.map +1 -0
  81. package/dist/src/streaming/stream-pipeline.js +431 -0
  82. package/dist/src/streaming/stream-pipeline.js.map +1 -0
  83. package/dist/src/streaming/stream-session.js +260 -0
  84. package/dist/src/streaming/stream-session.js.map +1 -0
  85. package/dist/src/streaming/stream.js +239 -0
  86. package/dist/src/streaming/stream.js.map +1 -0
  87. package/dist/src/util/logger.js +120 -0
  88. package/dist/src/util/logger.js.map +1 -0
  89. package/dist/src/util/markdown-fences.js +54 -0
  90. package/dist/src/util/markdown-fences.js.map +1 -0
  91. package/dist/src/util/random.js +16 -0
  92. package/dist/src/util/random.js.map +1 -0
  93. package/dist/src/util/redact.js +54 -0
  94. package/dist/src/util/redact.js.map +1 -0
  95. package/index.ts +0 -5
  96. package/openclaw.plugin.json +11 -1
  97. package/package.json +9 -2
  98. package/src/api/api.ts +2 -3
  99. package/src/auth/accounts.ts +0 -1
  100. package/src/channel.ts +13 -1
  101. package/src/monitor/monitor.ts +11 -10
  102. package/src/runtime.ts +0 -70
@@ -0,0 +1 @@
1
+ {"version":3,"file":"send.js","sourceRoot":"","sources":["../../../src/messaging/send.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,70 @@
1
+ import { logger } from "../util/logger.js";
2
+ import { toggleDebugMode } from "./debug-mode.js";
3
+ import { sendMessageWeixin } from "./send.js";
4
+ /** 发送回复消息 */
5
+ async function sendReply(ctx, text) {
6
+ const opts = {
7
+ baseUrl: ctx.baseUrl,
8
+ token: ctx.token,
9
+ contextToken: ctx.contextToken,
10
+ };
11
+ await sendMessageWeixin({ to: ctx.to, text, opts });
12
+ }
13
+ /** 处理 /echo 指令 */
14
+ async function handleEcho(ctx, args, receivedAt, eventTimestamp) {
15
+ const message = args.trim();
16
+ if (message) {
17
+ await sendReply(ctx, message);
18
+ }
19
+ const eventTs = eventTimestamp ?? 0;
20
+ const platformDelay = eventTs > 0 ? `${receivedAt - eventTs}ms` : "N/A";
21
+ const timing = [
22
+ "⏱ 通道耗时",
23
+ `├ 事件时间: ${eventTs > 0 ? new Date(eventTs).toISOString() : "N/A"}`,
24
+ `├ 平台→插件: ${platformDelay}`,
25
+ `└ 插件处理: ${Date.now() - receivedAt}ms`,
26
+ ].join("\n");
27
+ await sendReply(ctx, timing);
28
+ }
29
+ /**
30
+ * 尝试处理斜杠指令
31
+ *
32
+ * @returns handled=true 表示该消息已作为指令处理,不需要继续走 AI 管道
33
+ */
34
+ export async function handleSlashCommand(content, ctx, receivedAt, eventTimestamp) {
35
+ const trimmed = content.trim();
36
+ if (!trimmed.startsWith("/")) {
37
+ return { handled: false };
38
+ }
39
+ const spaceIdx = trimmed.indexOf(" ");
40
+ const command = spaceIdx === -1 ? trimmed.toLowerCase() : trimmed.slice(0, spaceIdx).toLowerCase();
41
+ const args = spaceIdx === -1 ? "" : trimmed.slice(spaceIdx + 1);
42
+ logger.info(`[weixin] Slash command: ${command}, args: ${args.slice(0, 50)}`);
43
+ try {
44
+ switch (command) {
45
+ case "/echo":
46
+ await handleEcho(ctx, args, receivedAt, eventTimestamp);
47
+ return { handled: true };
48
+ case "/toggle-debug": {
49
+ const enabled = toggleDebugMode(ctx.accountId);
50
+ await sendReply(ctx, enabled
51
+ ? "Debug 模式已开启"
52
+ : "Debug 模式已关闭");
53
+ return { handled: true };
54
+ }
55
+ default:
56
+ return { handled: false };
57
+ }
58
+ }
59
+ catch (err) {
60
+ logger.error(`[weixin] Slash command error: ${String(err)}`);
61
+ try {
62
+ await sendReply(ctx, `❌ 指令执行失败: ${String(err).slice(0, 200)}`);
63
+ }
64
+ catch {
65
+ // 发送错误消息也失败了,只能记日志
66
+ }
67
+ return { handled: true };
68
+ }
69
+ }
70
+ //# sourceMappingURL=slash-commands.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slash-commands.js","sourceRoot":"","sources":["../../../src/messaging/slash-commands.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAE3C,OAAO,EAAE,eAAe,EAAe,MAAM,iBAAiB,CAAC;AAC/D,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAiB9C,aAAa;AACb,KAAK,UAAU,SAAS,CAAC,GAAwB,EAAE,IAAY;IAC7D,MAAM,IAAI,GAAiD;QACzD,OAAO,EAAE,GAAG,CAAC,OAAO;QACpB,KAAK,EAAE,GAAG,CAAC,KAAK;QAChB,YAAY,EAAE,GAAG,CAAC,YAAY;KAC/B,CAAC;IACF,MAAM,iBAAiB,CAAC,EAAE,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;AACtD,CAAC;AAED,kBAAkB;AAClB,KAAK,UAAU,UAAU,CACvB,GAAwB,EACxB,IAAY,EACZ,UAAkB,EAClB,cAAuB;IAEvB,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;IAC5B,IAAI,OAAO,EAAE,CAAC;QACZ,MAAM,SAAS,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IAChC,CAAC;IACD,MAAM,OAAO,GAAG,cAAc,IAAI,CAAC,CAAC;IACpC,MAAM,aAAa,GAAG,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,UAAU,GAAG,OAAO,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC;IACxE,MAAM,MAAM,GAAG;QACb,QAAQ;QACR,WAAW,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,KAAK,EAAE;QAClE,YAAY,aAAa,EAAE;QAC3B,WAAW,IAAI,CAAC,GAAG,EAAE,GAAG,UAAU,IAAI;KACvC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACb,MAAM,SAAS,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;AAC/B,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,OAAe,EACf,GAAwB,EACxB,UAAkB,EAClB,cAAuB;IAEvB,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;IAC/B,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QAC7B,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;IAC5B,CAAC;IAED,MAAM,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACtC,MAAM,OAAO,GAAG,QAAQ,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,WAAW,EAAE,CAAC;IACnG,MAAM,IAAI,GAAG,QAAQ,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC;IAEhE,MAAM,CAAC,IAAI,CAAC,2BAA2B,OAAO,WAAW,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC;IAE9E,IAAI,CAAC;QACH,QAAQ,OAAO,EAAE,CAAC;YAChB,KAAK,OAAO;gBACV,MAAM,UAAU,CAAC,GAAG,EAAE,IAAI,EAAE,UAAU,EAAE,cAAc,CAAC,CAAC;gBACxD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;YAC3B,KAAK,eAAe,CAAC,CAAC,CAAC;gBACrB,MAAM,OAAO,GAAG,eAAe,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;gBAC/C,MAAM,SAAS,CACb,GAAG,EACH,OAAO;oBACL,CAAC,CAAC,aAAa;oBACf,CAAC,CAAC,aAAa,CAClB,CAAC;gBACF,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;YAC3B,CAAC;YACD;gBACE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;QAC9B,CAAC;IACH,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,CAAC,KAAK,CAAC,iCAAiC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAC7D,IAAI,CAAC;YACH,MAAM,SAAS,CAAC,GAAG,EAAE,aAAa,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;QACjE,CAAC;QAAC,MAAM,CAAC;YACP,mBAAmB;QACrB,CAAC;QACD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAC3B,CAAC;AACH,CAAC"}
@@ -0,0 +1,46 @@
1
+ export function createLaneScheduler() {
2
+ /**
3
+ * laneKey -> tail promise of the lane's in-flight chain. The chain is built
4
+ * with internal `try/catch` so failures of earlier tasks do not poison later
5
+ * tasks on the same lane. Entries are pruned when the lane goes idle.
6
+ */
7
+ const lanes = new Map();
8
+ function enqueue(key, task) {
9
+ const previousTail = lanes.get(key) ?? Promise.resolve();
10
+ let resolveResult;
11
+ let rejectResult;
12
+ const result = new Promise((resolve, reject) => {
13
+ resolveResult = resolve;
14
+ rejectResult = reject;
15
+ });
16
+ const nextTail = previousTail.then(async () => {
17
+ try {
18
+ const value = await task();
19
+ resolveResult(value);
20
+ }
21
+ catch (err) {
22
+ rejectResult(err);
23
+ }
24
+ });
25
+ lanes.set(key, nextTail);
26
+ void nextTail.finally(() => {
27
+ // Only prune if no one queued behind us in the meantime; otherwise the
28
+ // newer enqueue() owns the slot.
29
+ if (lanes.get(key) === nextTail) {
30
+ lanes.delete(key);
31
+ }
32
+ });
33
+ return result;
34
+ }
35
+ function size() {
36
+ return lanes.size;
37
+ }
38
+ async function drain() {
39
+ while (lanes.size > 0) {
40
+ const tails = [...lanes.values()];
41
+ await Promise.allSettled(tails);
42
+ }
43
+ }
44
+ return { enqueue, size, drain };
45
+ }
46
+ //# sourceMappingURL=lane-scheduler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lane-scheduler.js","sourceRoot":"","sources":["../../../src/monitor/lane-scheduler.ts"],"names":[],"mappings":"AA8BA,MAAM,UAAU,mBAAmB;IACjC;;;;OAIG;IACH,MAAM,KAAK,GAAG,IAAI,GAAG,EAAyB,CAAC;IAE/C,SAAS,OAAO,CAAI,GAAW,EAAE,IAAsB;QACrD,MAAM,YAAY,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;QACzD,IAAI,aAAmD,CAAC;QACxD,IAAI,YAAyC,CAAC;QAC9C,MAAM,MAAM,GAAG,IAAI,OAAO,CAAI,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YAChD,aAAa,GAAG,OAAO,CAAC;YACxB,YAAY,GAAG,MAAM,CAAC;QACxB,CAAC,CAAC,CAAC;QACH,MAAM,QAAQ,GAAG,YAAY,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE;YAC5C,IAAI,CAAC;gBACH,MAAM,KAAK,GAAG,MAAM,IAAI,EAAE,CAAC;gBAC3B,aAAa,CAAC,KAAK,CAAC,CAAC;YACvB,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,YAAY,CAAC,GAAG,CAAC,CAAC;YACpB,CAAC;QACH,CAAC,CAAC,CAAC;QACH,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;QACzB,KAAK,QAAQ,CAAC,OAAO,CAAC,GAAG,EAAE;YACzB,uEAAuE;YACvE,iCAAiC;YACjC,IAAI,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,QAAQ,EAAE,CAAC;gBAChC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACpB,CAAC;QACH,CAAC,CAAC,CAAC;QACH,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,SAAS,IAAI;QACX,OAAO,KAAK,CAAC,IAAI,CAAC;IACpB,CAAC;IAED,KAAK,UAAU,KAAK;QAClB,OAAO,KAAK,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC;YACtB,MAAM,KAAK,GAAG,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;YAClC,MAAM,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;QAClC,CAAC;IACH,CAAC;IAED,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;AAClC,CAAC"}
@@ -0,0 +1,143 @@
1
+ import { getUpdates } from "../api/api.js";
2
+ import { WeixinConfigManager } from "../api/config-cache.js";
3
+ import { SESSION_EXPIRED_ERRCODE, pauseSession, getRemainingPauseMs } from "../api/session-guard.js";
4
+ import { processOneMessage } from "../messaging/process-message.js";
5
+ import { getSyncBufFilePath, loadGetUpdatesBuf, saveGetUpdatesBuf } from "../storage/sync-buf.js";
6
+ import { logger } from "../util/logger.js";
7
+ import { redactBody } from "../util/redact.js";
8
+ const DEFAULT_LONG_POLL_TIMEOUT_MS = 35_000;
9
+ const MAX_CONSECUTIVE_FAILURES = 3;
10
+ const BACKOFF_DELAY_MS = 30_000;
11
+ const RETRY_DELAY_MS = 2_000;
12
+ /**
13
+ * Long-poll loop: getUpdates -> normalize -> recordInboundSession -> dispatchReplyFromConfig.
14
+ * Runs until abort.
15
+ */
16
+ export async function monitorWeixinProvider(opts) {
17
+ const { baseUrl, cdnBaseUrl, token, accountId, config, channelRuntime, abortSignal, longPollTimeoutMs, setStatus, } = opts;
18
+ const log = opts.runtime?.log ?? (() => { });
19
+ const errLog = opts.runtime?.error ?? ((m) => log(m));
20
+ const aLog = logger.withAccount(accountId);
21
+ if (!channelRuntime) {
22
+ const msg = "channelRuntime missing on monitor opts; gateway must inject ChannelGatewayContext.channelRuntime";
23
+ aLog.error(msg);
24
+ throw new Error(msg);
25
+ }
26
+ log(`weixin monitor started (${baseUrl}, account=${accountId})`);
27
+ aLog.info(`Monitor started: baseUrl=${baseUrl} timeoutMs=${longPollTimeoutMs ?? DEFAULT_LONG_POLL_TIMEOUT_MS}`);
28
+ const syncFilePath = getSyncBufFilePath(accountId);
29
+ aLog.debug(`syncFilePath: ${syncFilePath}`);
30
+ const previousGetUpdatesBuf = loadGetUpdatesBuf(syncFilePath);
31
+ let getUpdatesBuf = previousGetUpdatesBuf ?? "";
32
+ if (previousGetUpdatesBuf) {
33
+ log(`[weixin] resuming from previous sync buf (${getUpdatesBuf.length} bytes)`);
34
+ aLog.debug(`Using previous get_updates_buf (${getUpdatesBuf.length} bytes)`);
35
+ }
36
+ else {
37
+ log(`[weixin] no previous sync buf, starting fresh`);
38
+ aLog.info(`No previous get_updates_buf found, starting fresh`);
39
+ }
40
+ const configManager = new WeixinConfigManager({ baseUrl, token }, log);
41
+ let nextTimeoutMs = longPollTimeoutMs ?? DEFAULT_LONG_POLL_TIMEOUT_MS;
42
+ let consecutiveFailures = 0;
43
+ while (!abortSignal?.aborted) {
44
+ try {
45
+ aLog.debug(`getUpdates: get_updates_buf=${getUpdatesBuf.substring(0, 50)}..., timeoutMs=${nextTimeoutMs}`);
46
+ const resp = await getUpdates({
47
+ baseUrl,
48
+ token,
49
+ get_updates_buf: getUpdatesBuf,
50
+ timeoutMs: nextTimeoutMs,
51
+ });
52
+ aLog.debug(`getUpdates response: ret=${resp.ret}, msgs=${resp.msgs?.length ?? 0}, get_updates_buf_length=${resp.get_updates_buf?.length ?? 0}`);
53
+ if (resp.longpolling_timeout_ms != null && resp.longpolling_timeout_ms > 0) {
54
+ nextTimeoutMs = resp.longpolling_timeout_ms;
55
+ aLog.debug(`Updated next poll timeout: ${nextTimeoutMs}ms`);
56
+ }
57
+ const isApiError = (resp.ret !== undefined && resp.ret !== 0) ||
58
+ (resp.errcode !== undefined && resp.errcode !== 0);
59
+ if (isApiError) {
60
+ const isSessionExpired = resp.errcode === SESSION_EXPIRED_ERRCODE || resp.ret === SESSION_EXPIRED_ERRCODE;
61
+ if (isSessionExpired) {
62
+ pauseSession(accountId);
63
+ const pauseMs = getRemainingPauseMs(accountId);
64
+ errLog(`weixin getUpdates: session expired (errcode ${SESSION_EXPIRED_ERRCODE}), pausing bot for ${Math.ceil(pauseMs / 60_000)} min`);
65
+ aLog.error(`getUpdates: session expired (errcode=${resp.errcode} ret=${resp.ret}), pausing all requests for ${Math.ceil(pauseMs / 60_000)} min`);
66
+ consecutiveFailures = 0;
67
+ await sleep(pauseMs, abortSignal);
68
+ continue;
69
+ }
70
+ consecutiveFailures += 1;
71
+ errLog(`weixin getUpdates failed: ret=${resp.ret} errcode=${resp.errcode} errmsg=${resp.errmsg ?? ""} (${consecutiveFailures}/${MAX_CONSECUTIVE_FAILURES})`);
72
+ aLog.error(`getUpdates failed: ret=${resp.ret} errcode=${resp.errcode} errmsg=${resp.errmsg} response=${redactBody(JSON.stringify(resp))}`);
73
+ if (consecutiveFailures >= MAX_CONSECUTIVE_FAILURES) {
74
+ errLog(`weixin getUpdates: ${MAX_CONSECUTIVE_FAILURES} consecutive failures, backing off 30s`);
75
+ aLog.error(`getUpdates: ${MAX_CONSECUTIVE_FAILURES} consecutive failures, backing off 30s`);
76
+ consecutiveFailures = 0;
77
+ await sleep(BACKOFF_DELAY_MS, abortSignal);
78
+ }
79
+ else {
80
+ await sleep(RETRY_DELAY_MS, abortSignal);
81
+ }
82
+ continue;
83
+ }
84
+ consecutiveFailures = 0;
85
+ setStatus?.({ accountId, lastEventAt: Date.now() });
86
+ if (resp.get_updates_buf != null && resp.get_updates_buf !== "") {
87
+ saveGetUpdatesBuf(syncFilePath, resp.get_updates_buf);
88
+ getUpdatesBuf = resp.get_updates_buf;
89
+ aLog.debug(`Saved new get_updates_buf (${getUpdatesBuf.length} bytes)`);
90
+ }
91
+ const list = resp.msgs ?? [];
92
+ for (const full of list) {
93
+ aLog.info(`inbound message: from=${full.from_user_id} types=${full.item_list?.map((i) => i.type).join(",") ?? "none"}`);
94
+ const now = Date.now();
95
+ setStatus?.({ accountId, lastEventAt: now, lastInboundAt: now });
96
+ // allowFrom filtering is delegated to processOneMessage via the framework
97
+ // authorization pipeline (resolveSenderCommandAuthorizationWithRuntime).
98
+ const fromUserId = full.from_user_id ?? "";
99
+ const cachedConfig = await configManager.getForUser(fromUserId, full.context_token);
100
+ await processOneMessage(full, {
101
+ accountId,
102
+ config,
103
+ channelRuntime,
104
+ baseUrl,
105
+ cdnBaseUrl,
106
+ token,
107
+ typingTicket: cachedConfig.typingTicket,
108
+ log: opts.runtime?.log ?? (() => { }),
109
+ errLog,
110
+ });
111
+ }
112
+ }
113
+ catch (err) {
114
+ if (abortSignal?.aborted) {
115
+ aLog.info(`Monitor stopped (aborted)`);
116
+ return;
117
+ }
118
+ consecutiveFailures += 1;
119
+ errLog(`weixin getUpdates error (${consecutiveFailures}/${MAX_CONSECUTIVE_FAILURES}): ${String(err)}`);
120
+ aLog.error(`getUpdates error: ${String(err)}, stack=${err.stack}`);
121
+ if (consecutiveFailures >= MAX_CONSECUTIVE_FAILURES) {
122
+ errLog(`weixin getUpdates: ${MAX_CONSECUTIVE_FAILURES} consecutive failures, backing off 30s`);
123
+ aLog.error(`getUpdates: ${MAX_CONSECUTIVE_FAILURES} consecutive failures, backing off 30s`);
124
+ consecutiveFailures = 0;
125
+ await sleep(30_000, abortSignal);
126
+ }
127
+ else {
128
+ await sleep(2000, abortSignal);
129
+ }
130
+ }
131
+ }
132
+ aLog.info(`Monitor ended`);
133
+ }
134
+ function sleep(ms, signal) {
135
+ return new Promise((resolve, reject) => {
136
+ const t = setTimeout(resolve, ms);
137
+ signal?.addEventListener("abort", () => {
138
+ clearTimeout(t);
139
+ reject(new Error("aborted"));
140
+ }, { once: true });
141
+ });
142
+ }
143
+ //# sourceMappingURL=monitor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"monitor.js","sourceRoot":"","sources":["../../../src/monitor/monitor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,54 @@
1
+ import { logger } from "./util/logger.js";
2
+ let pluginRuntime = null;
3
+ /**
4
+ * Sets the global Weixin runtime (called from plugin register).
5
+ */
6
+ export function setWeixinRuntime(next) {
7
+ pluginRuntime = next;
8
+ logger.info(`[runtime] setWeixinRuntime called, runtime set successfully`);
9
+ }
10
+ /**
11
+ * Gets the global Weixin runtime (throws if not initialized).
12
+ */
13
+ export function getWeixinRuntime() {
14
+ if (!pluginRuntime) {
15
+ throw new Error("Weixin runtime not initialized");
16
+ }
17
+ return pluginRuntime;
18
+ }
19
+ const WAIT_INTERVAL_MS = 100;
20
+ const DEFAULT_TIMEOUT_MS = 10_000;
21
+ /**
22
+ * Waits for the Weixin runtime to be initialized (async polling).
23
+ */
24
+ export async function waitForWeixinRuntime(timeoutMs = DEFAULT_TIMEOUT_MS) {
25
+ const start = Date.now();
26
+ while (!pluginRuntime) {
27
+ if (Date.now() - start > timeoutMs) {
28
+ throw new Error("Weixin runtime initialization timeout");
29
+ }
30
+ await new Promise((resolve) => setTimeout(resolve, WAIT_INTERVAL_MS));
31
+ }
32
+ return pluginRuntime;
33
+ }
34
+ /**
35
+ * Resolves `PluginRuntime["channel"]` for the long-poll monitor.
36
+ *
37
+ * Prefer the gateway-injected `channelRuntime` on `ChannelGatewayContext` when present (avoids
38
+ * races with the module-global from `register()`). Fall back to the global set by `setWeixinRuntime()`,
39
+ * then to a short wait for legacy hosts.
40
+ */
41
+ export async function resolveWeixinChannelRuntime(params) {
42
+ if (params.channelRuntime) {
43
+ logger.debug("[runtime] channelRuntime from gateway context");
44
+ return params.channelRuntime;
45
+ }
46
+ if (pluginRuntime) {
47
+ logger.debug("[runtime] channelRuntime from register() global");
48
+ return pluginRuntime.channel;
49
+ }
50
+ logger.warn("[runtime] no channelRuntime on ctx and no global runtime yet; waiting for register()");
51
+ const pr = await waitForWeixinRuntime(params.waitTimeoutMs ?? DEFAULT_TIMEOUT_MS);
52
+ return pr.channel;
53
+ }
54
+ //# sourceMappingURL=runtime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime.js","sourceRoot":"","sources":["../../src/runtime.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAE1C,IAAI,aAAa,GAAyB,IAAI,CAAC;AAI/C;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAAC,IAAmB;IAClD,aAAa,GAAG,IAAI,CAAC;IACrB,MAAM,CAAC,IAAI,CAAC,6DAA6D,CAAC,CAAC;AAC7E,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,gBAAgB;IAC9B,IAAI,CAAC,aAAa,EAAE,CAAC;QACnB,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAC;IACpD,CAAC;IACD,OAAO,aAAa,CAAC;AACvB,CAAC;AAED,MAAM,gBAAgB,GAAG,GAAG,CAAC;AAC7B,MAAM,kBAAkB,GAAG,MAAM,CAAC;AAElC;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,SAAS,GAAG,kBAAkB;IAE9B,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACzB,OAAO,CAAC,aAAa,EAAE,CAAC;QACtB,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,GAAG,SAAS,EAAE,CAAC;YACnC,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;QAC3D,CAAC;QACD,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,gBAAgB,CAAC,CAAC,CAAC;IACxE,CAAC;IACD,OAAO,aAAa,CAAC;AACvB,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,2BAA2B,CAAC,MAGjD;IACC,IAAI,MAAM,CAAC,cAAc,EAAE,CAAC;QAC1B,MAAM,CAAC,KAAK,CAAC,+CAA+C,CAAC,CAAC;QAC9D,OAAO,MAAM,CAAC,cAAc,CAAC;IAC/B,CAAC;IACD,IAAI,aAAa,EAAE,CAAC;QAClB,MAAM,CAAC,KAAK,CAAC,iDAAiD,CAAC,CAAC;QAChE,OAAO,aAAa,CAAC,OAAO,CAAC;IAC/B,CAAC;IACD,MAAM,CAAC,IAAI,CACT,sFAAsF,CACvF,CAAC;IACF,MAAM,EAAE,GAAG,MAAM,oBAAoB,CAAC,MAAM,CAAC,aAAa,IAAI,kBAAkB,CAAC,CAAC;IAClF,OAAO,EAAE,CAAC,OAAO,CAAC;AACpB,CAAC"}
@@ -0,0 +1,9 @@
1
+ import os from "node:os";
2
+ import path from "node:path";
3
+ /** Resolve the OpenClaw state directory (mirrors core logic in src/infra). */
4
+ export function resolveStateDir() {
5
+ return (process.env.OPENCLAW_STATE_DIR?.trim() ||
6
+ process.env.CLAWDBOT_STATE_DIR?.trim() ||
7
+ path.join(os.homedir(), ".openclaw"));
8
+ }
9
+ //# sourceMappingURL=state-dir.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state-dir.js","sourceRoot":"","sources":["../../../src/storage/state-dir.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,8EAA8E;AAC9E,MAAM,UAAU,eAAe;IAC7B,OAAO,CACL,OAAO,CAAC,GAAG,CAAC,kBAAkB,EAAE,IAAI,EAAE;QACtC,OAAO,CAAC,GAAG,CAAC,kBAAkB,EAAE,IAAI,EAAE;QACtC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,WAAW,CAAC,CACrC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,64 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+ import { deriveRawAccountId } from "../auth/accounts.js";
4
+ import { resolveStateDir } from "./state-dir.js";
5
+ function resolveAccountsDir() {
6
+ return path.join(resolveStateDir(), "openclaw-weixin", "accounts");
7
+ }
8
+ /**
9
+ * Path to the persistent get_updates_buf file for an account.
10
+ * Stored alongside account data: ~/.openclaw/openclaw-weixin/accounts/{accountId}.sync.json
11
+ */
12
+ export function getSyncBufFilePath(accountId) {
13
+ return path.join(resolveAccountsDir(), `${accountId}.sync.json`);
14
+ }
15
+ /** Legacy single-account syncbuf (pre multi-account): `.openclaw-weixin-sync/default.json`. */
16
+ function getLegacySyncBufDefaultJsonPath() {
17
+ return path.join(resolveStateDir(), "agents", "default", "sessions", ".openclaw-weixin-sync", "default.json");
18
+ }
19
+ function readSyncBufFile(filePath) {
20
+ try {
21
+ const raw = fs.readFileSync(filePath, "utf-8");
22
+ const data = JSON.parse(raw);
23
+ if (typeof data.get_updates_buf === "string") {
24
+ return data.get_updates_buf;
25
+ }
26
+ }
27
+ catch {
28
+ // file not found or invalid
29
+ }
30
+ return undefined;
31
+ }
32
+ /**
33
+ * Load persisted get_updates_buf.
34
+ * Falls back in order:
35
+ * 1. Primary path (normalized accountId, new installs)
36
+ * 2. Compat path (raw accountId derived from pattern, old installs)
37
+ * 3. Legacy single-account path (very old installs without multi-account support)
38
+ */
39
+ export function loadGetUpdatesBuf(filePath) {
40
+ const value = readSyncBufFile(filePath);
41
+ if (value !== undefined)
42
+ return value;
43
+ // Compat: if given path uses a normalized accountId (e.g. "b0f5860fdecb-im-bot.sync.json"),
44
+ // also try the old raw-ID filename (e.g. "b0f5860fdecb@im.bot.sync.json").
45
+ const accountId = path.basename(filePath, ".sync.json");
46
+ const rawId = deriveRawAccountId(accountId);
47
+ if (rawId) {
48
+ const compatPath = path.join(resolveAccountsDir(), `${rawId}.sync.json`);
49
+ const compatValue = readSyncBufFile(compatPath);
50
+ if (compatValue !== undefined)
51
+ return compatValue;
52
+ }
53
+ // Legacy fallback: old single-account installs stored syncbuf without accountId.
54
+ return readSyncBufFile(getLegacySyncBufDefaultJsonPath());
55
+ }
56
+ /**
57
+ * Persist get_updates_buf. Creates parent dir if needed.
58
+ */
59
+ export function saveGetUpdatesBuf(filePath, getUpdatesBuf) {
60
+ const dir = path.dirname(filePath);
61
+ fs.mkdirSync(dir, { recursive: true });
62
+ fs.writeFileSync(filePath, JSON.stringify({ get_updates_buf: getUpdatesBuf }, null, 0), "utf-8");
63
+ }
64
+ //# sourceMappingURL=sync-buf.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync-buf.js","sourceRoot":"","sources":["../../../src/storage/sync-buf.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAEzD,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAEjD,SAAS,kBAAkB;IACzB,OAAO,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE,EAAE,iBAAiB,EAAE,UAAU,CAAC,CAAC;AACrE,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAAC,SAAiB;IAClD,OAAO,IAAI,CAAC,IAAI,CAAC,kBAAkB,EAAE,EAAE,GAAG,SAAS,YAAY,CAAC,CAAC;AACnE,CAAC;AAED,+FAA+F;AAC/F,SAAS,+BAA+B;IACtC,OAAO,IAAI,CAAC,IAAI,CACd,eAAe,EAAE,EACjB,QAAQ,EACR,SAAS,EACT,UAAU,EACV,uBAAuB,EACvB,cAAc,CACf,CAAC;AACJ,CAAC;AAMD,SAAS,eAAe,CAAC,QAAgB;IACvC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QAC/C,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAiC,CAAC;QAC7D,IAAI,OAAO,IAAI,CAAC,eAAe,KAAK,QAAQ,EAAE,CAAC;YAC7C,OAAO,IAAI,CAAC,eAAe,CAAC;QAC9B,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,4BAA4B;IAC9B,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,iBAAiB,CAAC,QAAgB;IAChD,MAAM,KAAK,GAAG,eAAe,CAAC,QAAQ,CAAC,CAAC;IACxC,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC;IAEtC,4FAA4F;IAC5F,2EAA2E;IAC3E,MAAM,SAAS,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;IACxD,MAAM,KAAK,GAAG,kBAAkB,CAAC,SAAS,CAAC,CAAC;IAC5C,IAAI,KAAK,EAAE,CAAC;QACV,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,kBAAkB,EAAE,EAAE,GAAG,KAAK,YAAY,CAAC,CAAC;QACzE,MAAM,WAAW,GAAG,eAAe,CAAC,UAAU,CAAC,CAAC;QAChD,IAAI,WAAW,KAAK,SAAS;YAAE,OAAO,WAAW,CAAC;IACpD,CAAC;IAED,iFAAiF;IACjF,OAAO,eAAe,CAAC,+BAA+B,EAAE,CAAC,CAAC;AAC5D,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAAC,QAAgB,EAAE,aAAqB;IACvE,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACnC,EAAE,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACvC,EAAE,CAAC,aAAa,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,eAAe,EAAE,aAAa,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;AACnG,CAAC"}