@xuanyue202/wechat-mp 2026.3.21

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 (95) hide show
  1. package/README.md +74 -0
  2. package/dist/index.d.ts +20 -0
  3. package/dist/index.d.ts.map +1 -0
  4. package/dist/index.js +59 -0
  5. package/dist/index.js.map +1 -0
  6. package/dist/src/api.d.ts +101 -0
  7. package/dist/src/api.d.ts.map +1 -0
  8. package/dist/src/api.js +142 -0
  9. package/dist/src/api.js.map +1 -0
  10. package/dist/src/channel.d.ts +296 -0
  11. package/dist/src/channel.d.ts.map +1 -0
  12. package/dist/src/channel.js +341 -0
  13. package/dist/src/channel.js.map +1 -0
  14. package/dist/src/config.d.ts +69 -0
  15. package/dist/src/config.d.ts.map +1 -0
  16. package/dist/src/config.js +167 -0
  17. package/dist/src/config.js.map +1 -0
  18. package/dist/src/crypto.d.ts +117 -0
  19. package/dist/src/crypto.d.ts.map +1 -0
  20. package/dist/src/crypto.js +270 -0
  21. package/dist/src/crypto.js.map +1 -0
  22. package/dist/src/crypto.test.d.ts +2 -0
  23. package/dist/src/crypto.test.d.ts.map +1 -0
  24. package/dist/src/crypto.test.js +76 -0
  25. package/dist/src/crypto.test.js.map +1 -0
  26. package/dist/src/dispatch.d.ts +15 -0
  27. package/dist/src/dispatch.d.ts.map +1 -0
  28. package/dist/src/dispatch.js +193 -0
  29. package/dist/src/dispatch.js.map +1 -0
  30. package/dist/src/dispatch.test.d.ts +2 -0
  31. package/dist/src/dispatch.test.d.ts.map +1 -0
  32. package/dist/src/dispatch.test.js +231 -0
  33. package/dist/src/dispatch.test.js.map +1 -0
  34. package/dist/src/inbound.d.ts +7 -0
  35. package/dist/src/inbound.d.ts.map +1 -0
  36. package/dist/src/inbound.js +82 -0
  37. package/dist/src/inbound.js.map +1 -0
  38. package/dist/src/onboarding.d.ts +25 -0
  39. package/dist/src/onboarding.d.ts.map +1 -0
  40. package/dist/src/onboarding.js +49 -0
  41. package/dist/src/onboarding.js.map +1 -0
  42. package/dist/src/outbound.d.ts +17 -0
  43. package/dist/src/outbound.d.ts.map +1 -0
  44. package/dist/src/outbound.js +55 -0
  45. package/dist/src/outbound.js.map +1 -0
  46. package/dist/src/outbound.test.d.ts +2 -0
  47. package/dist/src/outbound.test.d.ts.map +1 -0
  48. package/dist/src/outbound.test.js +175 -0
  49. package/dist/src/outbound.test.js.map +1 -0
  50. package/dist/src/probe.d.ts +15 -0
  51. package/dist/src/probe.d.ts.map +1 -0
  52. package/dist/src/probe.js +55 -0
  53. package/dist/src/probe.js.map +1 -0
  54. package/dist/src/runtime.d.ts +22 -0
  55. package/dist/src/runtime.d.ts.map +1 -0
  56. package/dist/src/runtime.js +33 -0
  57. package/dist/src/runtime.js.map +1 -0
  58. package/dist/src/send.d.ts +27 -0
  59. package/dist/src/send.d.ts.map +1 -0
  60. package/dist/src/send.js +103 -0
  61. package/dist/src/send.js.map +1 -0
  62. package/dist/src/state.d.ts +7 -0
  63. package/dist/src/state.d.ts.map +1 -0
  64. package/dist/src/state.js +109 -0
  65. package/dist/src/state.js.map +1 -0
  66. package/dist/src/text.d.ts +46 -0
  67. package/dist/src/text.d.ts.map +1 -0
  68. package/dist/src/text.js +192 -0
  69. package/dist/src/text.js.map +1 -0
  70. package/dist/src/text.test.d.ts +2 -0
  71. package/dist/src/text.test.d.ts.map +1 -0
  72. package/dist/src/text.test.js +110 -0
  73. package/dist/src/text.test.js.map +1 -0
  74. package/dist/src/token.d.ts +40 -0
  75. package/dist/src/token.d.ts.map +1 -0
  76. package/dist/src/token.js +154 -0
  77. package/dist/src/token.js.map +1 -0
  78. package/dist/src/token.test.d.ts +2 -0
  79. package/dist/src/token.test.d.ts.map +1 -0
  80. package/dist/src/token.test.js +74 -0
  81. package/dist/src/token.test.js.map +1 -0
  82. package/dist/src/types.d.ts +320 -0
  83. package/dist/src/types.d.ts.map +1 -0
  84. package/dist/src/types.js +2 -0
  85. package/dist/src/types.js.map +1 -0
  86. package/dist/src/webhook.d.ts +6 -0
  87. package/dist/src/webhook.d.ts.map +1 -0
  88. package/dist/src/webhook.js +381 -0
  89. package/dist/src/webhook.js.map +1 -0
  90. package/dist/src/webhook.test.d.ts +2 -0
  91. package/dist/src/webhook.test.d.ts.map +1 -0
  92. package/dist/src/webhook.test.js +737 -0
  93. package/dist/src/webhook.test.js.map +1 -0
  94. package/openclaw.plugin.json +83 -0
  95. package/package.json +103 -0
@@ -0,0 +1,154 @@
1
+ /**
2
+ * access_token lifecycle management for wechat-mp
3
+ *
4
+ * Provides centralized token caching, proactive refresh, and error handling.
5
+ */
6
+ // ============================================================================
7
+ // Token Cache
8
+ // ============================================================================
9
+ const ACCESS_TOKEN_CACHE = new Map();
10
+ const TOKEN_REFRESH_TIMERS = new Map();
11
+ const INVALID_ACCESS_TOKEN_ERRCODES = new Set([40001, 40014, 42001, 42007]);
12
+ /**
13
+ * Build cache key for account
14
+ */
15
+ function buildCacheKey(account) {
16
+ return `${account.accountId}:${account.config.appId}`;
17
+ }
18
+ /**
19
+ * Get a cached access_token or fetch a new one.
20
+ * @throws Error if appId/appSecret not configured or API call fails
21
+ */
22
+ export async function getAccessToken(account) {
23
+ const key = buildCacheKey(account);
24
+ // Check cache first
25
+ const cached = ACCESS_TOKEN_CACHE.get(key);
26
+ if (cached && Date.now() < cached.expiresAt) {
27
+ return cached.token;
28
+ }
29
+ // Fetch new token from WeChat API
30
+ const result = await fetchAccessToken(account);
31
+ // Cache token with 5 minutes before expiry buffer
32
+ const bufferMs = 5 * 60 * 1000;
33
+ const expiresInMs = Math.max((result.expiresIn - 300) * 1000, 60 * 1000);
34
+ const entry = {
35
+ token: result.token,
36
+ expiresAt: Date.now() + expiresInMs,
37
+ };
38
+ ACCESS_TOKEN_CACHE.set(key, entry);
39
+ // Schedule proactive refresh
40
+ scheduleTokenRefresh(account, expiresInMs - bufferMs);
41
+ return result.token;
42
+ }
43
+ /**
44
+ * Fetch access_token from WeChat API
45
+ */
46
+ async function fetchAccessToken(account) {
47
+ if (!account.config.appId || !account.config.appSecret) {
48
+ throw new Error(`appId or appSecret not configured for account ${account.accountId}`);
49
+ }
50
+ const url = new URL("https://api.weixin.qq.com/cgi-bin/token");
51
+ url.searchParams.set("grant_type", "client_credential");
52
+ url.searchParams.set("appid", account.config.appId);
53
+ url.searchParams.set("secret", account.config.appSecret);
54
+ const response = await fetch(url.toString());
55
+ const data = (await response.json());
56
+ if (data.errcode !== undefined && data.errcode !== 0) {
57
+ throw new Error(`getAccessToken failed for ${account.accountId}: ${data.errmsg ?? "unknown error"} (errcode=${data.errcode})`);
58
+ }
59
+ if (!data.access_token) {
60
+ throw new Error(`getAccessToken returned empty access_token for ${account.accountId}`);
61
+ }
62
+ return {
63
+ token: data.access_token,
64
+ expiresIn: data.expires_in ?? 7200,
65
+ };
66
+ }
67
+ /**
68
+ * Clear token cache for an account
69
+ */
70
+ export function clearAccessTokenCache(account) {
71
+ const key = buildCacheKey(account);
72
+ ACCESS_TOKEN_CACHE.delete(key);
73
+ // Clear scheduled refresh
74
+ const timer = TOKEN_REFRESH_TIMERS.get(key);
75
+ if (timer) {
76
+ clearTimeout(timer);
77
+ TOKEN_REFRESH_TIMERS.delete(key);
78
+ }
79
+ }
80
+ /**
81
+ * Clear all token caches
82
+ */
83
+ export function clearAllAccessTokenCache() {
84
+ ACCESS_TOKEN_CACHE.clear();
85
+ for (const timer of TOKEN_REFRESH_TIMERS.values()) {
86
+ clearTimeout(timer);
87
+ }
88
+ TOKEN_REFRESH_TIMERS.clear();
89
+ }
90
+ /**
91
+ * Check if a token needs refresh (expires within 5 minutes)
92
+ */
93
+ export function shouldRefreshToken(account) {
94
+ const key = buildCacheKey(account);
95
+ const cached = ACCESS_TOKEN_CACHE.get(key);
96
+ if (!cached)
97
+ return false;
98
+ const bufferMs = 5 * 60 * 1000;
99
+ return Date.now() >= cached.expiresAt - bufferMs;
100
+ }
101
+ /**
102
+ * Get token cache status
103
+ */
104
+ export function getTokenCacheStatus(account) {
105
+ const key = buildCacheKey(account);
106
+ const cached = ACCESS_TOKEN_CACHE.get(key);
107
+ if (!cached) {
108
+ return { cached: false };
109
+ }
110
+ return {
111
+ cached: true,
112
+ expiresAt: cached.expiresAt,
113
+ valid: Date.now() < cached.expiresAt,
114
+ };
115
+ }
116
+ /**
117
+ * Force refresh token (clear cache and fetch new)
118
+ */
119
+ export async function refreshToken(account) {
120
+ clearAccessTokenCache(account);
121
+ return getAccessToken(account);
122
+ }
123
+ /**
124
+ * Schedule proactive token refresh
125
+ */
126
+ function scheduleTokenRefresh(account, delayMs) {
127
+ const key = buildCacheKey(account);
128
+ // Clear existing timer
129
+ const existing = TOKEN_REFRESH_TIMERS.get(key);
130
+ if (existing) {
131
+ clearTimeout(existing);
132
+ }
133
+ if (delayMs <= 0) {
134
+ return;
135
+ }
136
+ const timer = setTimeout(async () => {
137
+ TOKEN_REFRESH_TIMERS.delete(key);
138
+ try {
139
+ await refreshToken(account);
140
+ }
141
+ catch {
142
+ // Retry with exponential backoff
143
+ scheduleTokenRefresh(account, Math.min(delayMs * 2, 60 * 60 * 1000));
144
+ }
145
+ }, delayMs);
146
+ TOKEN_REFRESH_TIMERS.set(key, timer);
147
+ }
148
+ /**
149
+ * Check if error code indicates invalid token
150
+ */
151
+ export function isInvalidTokenError(errcode) {
152
+ return INVALID_ACCESS_TOKEN_ERRCODES.has(errcode);
153
+ }
154
+ //# sourceMappingURL=token.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"token.js","sourceRoot":"","sources":["../../src/token.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,+EAA+E;AAC/E,cAAc;AACd,+EAA+E;AAE/E,MAAM,kBAAkB,GAAG,IAAI,GAAG,EAAiC,CAAC;AACpE,MAAM,oBAAoB,GAAG,IAAI,GAAG,EAA0B,CAAC;AAC/D,MAAM,6BAA6B,GAAG,IAAI,GAAG,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC;AAO5E;;GAEG;AACH,SAAS,aAAa,CAAC,OAAgC;IACrD,OAAO,GAAG,OAAO,CAAC,SAAS,IAAI,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;AACxD,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,OAAgC;IACnE,MAAM,GAAG,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC;IAEnC,oBAAoB;IACpB,MAAM,MAAM,GAAG,kBAAkB,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC3C,IAAI,MAAM,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC,SAAS,EAAE,CAAC;QAC5C,OAAO,MAAM,CAAC,KAAK,CAAC;IACtB,CAAC;IAED,kCAAkC;IAClC,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC,OAAO,CAAC,CAAC;IAE/C,kDAAkD;IAClD,MAAM,QAAQ,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;IAC/B,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,SAAS,GAAG,GAAG,CAAC,GAAG,IAAI,EAAE,EAAE,GAAG,IAAI,CAAC,CAAC;IAEzE,MAAM,KAAK,GAA0B;QACnC,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,WAAW;KACpC,CAAC;IACF,kBAAkB,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IAEnC,6BAA6B;IAC7B,oBAAoB,CAAC,OAAO,EAAE,WAAW,GAAG,QAAQ,CAAC,CAAC;IAEtD,OAAO,MAAM,CAAC,KAAK,CAAC;AACtB,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,gBAAgB,CAAC,OAAgC;IAC9D,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC;QACvD,MAAM,IAAI,KAAK,CAAC,iDAAiD,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC;IACxF,CAAC;IAED,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,yCAAyC,CAAC,CAAC;IAC/D,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,YAAY,EAAE,mBAAmB,CAAC,CAAC;IACxD,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACpD,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IAEzD,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC;IAC7C,MAAM,IAAI,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAsF,CAAC;IAE1H,IAAI,IAAI,CAAC,OAAO,KAAK,SAAS,IAAI,IAAI,CAAC,OAAO,KAAK,CAAC,EAAE,CAAC;QACrD,MAAM,IAAI,KAAK,CAAC,6BAA6B,OAAO,CAAC,SAAS,KAAK,IAAI,CAAC,MAAM,IAAI,eAAe,aAAa,IAAI,CAAC,OAAO,GAAG,CAAC,CAAC;IACjI,CAAC;IAED,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC;QACvB,MAAM,IAAI,KAAK,CAAC,kDAAkD,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC;IACzF,CAAC;IAED,OAAO;QACL,KAAK,EAAE,IAAI,CAAC,YAAY;QACxB,SAAS,EAAE,IAAI,CAAC,UAAU,IAAI,IAAI;KACnC,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,qBAAqB,CAAC,OAAgC;IACpE,MAAM,GAAG,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC;IACnC,kBAAkB,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAE/B,0BAA0B;IAC1B,MAAM,KAAK,GAAG,oBAAoB,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC5C,IAAI,KAAK,EAAE,CAAC;QACV,YAAY,CAAC,KAAK,CAAC,CAAC;QACpB,oBAAoB,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IACnC,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,wBAAwB;IACtC,kBAAkB,CAAC,KAAK,EAAE,CAAC;IAC3B,KAAK,MAAM,KAAK,IAAI,oBAAoB,CAAC,MAAM,EAAE,EAAE,CAAC;QAClD,YAAY,CAAC,KAAK,CAAC,CAAC;IACtB,CAAC;IACD,oBAAoB,CAAC,KAAK,EAAE,CAAC;AAC/B,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAAC,OAAgC;IACjE,MAAM,GAAG,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC;IACnC,MAAM,MAAM,GAAG,kBAAkB,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC3C,IAAI,CAAC,MAAM;QAAE,OAAO,KAAK,CAAC;IAE1B,MAAM,QAAQ,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;IAC/B,OAAO,IAAI,CAAC,GAAG,EAAE,IAAI,MAAM,CAAC,SAAS,GAAG,QAAQ,CAAC;AACnD,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,mBAAmB,CACjC,OAAgC;IAEhC,MAAM,GAAG,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC;IACnC,MAAM,MAAM,GAAG,kBAAkB,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC3C,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;IAC3B,CAAC;IACD,OAAO;QACL,MAAM,EAAE,IAAI;QACZ,SAAS,EAAE,MAAM,CAAC,SAAS;QAC3B,KAAK,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC,SAAS;KACrC,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,OAAgC;IACjE,qBAAqB,CAAC,OAAO,CAAC,CAAC;IAC/B,OAAO,cAAc,CAAC,OAAO,CAAC,CAAC;AACjC,CAAC;AAED;;GAEG;AACH,SAAS,oBAAoB,CAAC,OAAgC,EAAE,OAAe;IAC7E,MAAM,GAAG,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC;IAEnC,uBAAuB;IACvB,MAAM,QAAQ,GAAG,oBAAoB,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC/C,IAAI,QAAQ,EAAE,CAAC;QACb,YAAY,CAAC,QAAQ,CAAC,CAAC;IACzB,CAAC;IAED,IAAI,OAAO,IAAI,CAAC,EAAE,CAAC;QACjB,OAAO;IACT,CAAC;IAED,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,IAAI,EAAE;QAClC,oBAAoB,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACjC,IAAI,CAAC;YACH,MAAM,YAAY,CAAC,OAAO,CAAC,CAAC;QAC9B,CAAC;QAAC,MAAM,CAAC;YACP,iCAAiC;YACjC,oBAAoB,CAAC,OAAO,EAAE,IAAI,CAAC,GAAG,CAAC,OAAO,GAAG,CAAC,EAAE,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,CAAC;QACvE,CAAC;IACH,CAAC,EAAE,OAAO,CAAC,CAAC;IAEZ,oBAAoB,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;AACvC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,mBAAmB,CAAC,OAAe;IACjD,OAAO,6BAA6B,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;AACpD,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=token.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"token.test.d.ts","sourceRoot":"","sources":["../../src/token.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,74 @@
1
+ import { afterEach, describe, expect, it, vi } from "vitest";
2
+ import { clearAccessTokenCache, clearAllAccessTokenCache, getAccessToken, getTokenCacheStatus, isInvalidTokenError, refreshToken, shouldRefreshToken, } from "./token.js";
3
+ function createAccount(overrides) {
4
+ return {
5
+ accountId: "default",
6
+ name: "WeChat MP (default)",
7
+ enabled: true,
8
+ configured: true,
9
+ canSendActive: true,
10
+ config: {
11
+ appId: "wx-test-appid",
12
+ appSecret: "secret",
13
+ token: "token",
14
+ encodingAESKey: "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFG",
15
+ webhookPath: "/wechat-mp",
16
+ messageMode: "safe",
17
+ replyMode: "passive",
18
+ },
19
+ ...overrides,
20
+ };
21
+ }
22
+ afterEach(() => {
23
+ clearAllAccessTokenCache();
24
+ vi.unstubAllGlobals();
25
+ vi.restoreAllMocks();
26
+ });
27
+ describe("wechat-mp token", () => {
28
+ it("fetches and caches access token", async () => {
29
+ const fetchMock = vi.fn(async () => ({
30
+ json: async () => ({
31
+ access_token: "token-1",
32
+ expires_in: 7200,
33
+ }),
34
+ }));
35
+ vi.stubGlobal("fetch", fetchMock);
36
+ const account = createAccount();
37
+ const first = await getAccessToken(account);
38
+ const second = await getAccessToken(account);
39
+ expect(first).toBe("token-1");
40
+ expect(second).toBe("token-1");
41
+ expect(fetchMock).toHaveBeenCalledTimes(1);
42
+ expect(getTokenCacheStatus(account).cached).toBe(true);
43
+ });
44
+ it("refreshes after cache clear", async () => {
45
+ const fetchMock = vi
46
+ .fn()
47
+ .mockResolvedValueOnce({ json: async () => ({ access_token: "token-1", expires_in: 7200 }) })
48
+ .mockResolvedValueOnce({ json: async () => ({ access_token: "token-2", expires_in: 7200 }) });
49
+ vi.stubGlobal("fetch", fetchMock);
50
+ const account = createAccount();
51
+ expect(await getAccessToken(account)).toBe("token-1");
52
+ clearAccessTokenCache(account);
53
+ expect(await refreshToken(account)).toBe("token-2");
54
+ expect(fetchMock).toHaveBeenCalledTimes(2);
55
+ });
56
+ it("identifies invalid token errcodes", () => {
57
+ expect(isInvalidTokenError(40001)).toBe(true);
58
+ expect(isInvalidTokenError(42001)).toBe(true);
59
+ expect(isInvalidTokenError(12345)).toBe(false);
60
+ });
61
+ it("reports refresh need from cache status", async () => {
62
+ const fetchMock = vi.fn(async () => ({
63
+ json: async () => ({
64
+ access_token: "token-1",
65
+ expires_in: 60,
66
+ }),
67
+ }));
68
+ vi.stubGlobal("fetch", fetchMock);
69
+ const account = createAccount();
70
+ await getAccessToken(account);
71
+ expect(typeof shouldRefreshToken(account)).toBe("boolean");
72
+ });
73
+ });
74
+ //# sourceMappingURL=token.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"token.test.js","sourceRoot":"","sources":["../../src/token.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,320 @@
1
+ import type { IncomingMessage, ServerResponse } from "http";
2
+ /**
3
+ * ============================================================================
4
+ * TARGET AND SESSION KEY CONVENTIONS
5
+ * ============================================================================
6
+ *
7
+ * External Target Format (user-facing):
8
+ * - Primary: `user:<openid>` (openid-only, uses default account)
9
+ * - With account: `user:<openid>@<accountId>` (explicit account)
10
+ * - Legacy: `wechat-mp:user:<openid>` or `wechat-mp:user:<openid>@<accountId>`
11
+ *
12
+ * Internal Session Key Format (stable, internal):
13
+ * - Pattern: `dm:<appId>:<openid>`
14
+ * - The appId provides namespace isolation for multi-tenant scenarios
15
+ * - The openid is the stable user identifier from WeChat
16
+ *
17
+ * Why split external/internal:
18
+ * - External: User-friendly, can omit account, follows OpenClaw conventions
19
+ * - Internal: Stable, includes appId for multi-account isolation
20
+ *
21
+ * Account Resolution:
22
+ * - If accountId is provided: use accounts.<accountId> with root fallback
23
+ * - If no accountId: use root config as "default" account
24
+ * - Multi-account schema is day-one ready but setup CLI focuses on single account
25
+ */
26
+ /**
27
+ * WeChat MP DM policy for controlling direct message acceptance.
28
+ */
29
+ export type WechatMpDmPolicy = "open" | "pairing" | "allowlist" | "disabled";
30
+ /**
31
+ * WeChat MP message encryption mode.
32
+ * - plain: No encryption
33
+ * - safe: Full encryption
34
+ * - compat: Compatible mode (both encrypted and plain supported)
35
+ */
36
+ export type WechatMpMessageMode = "plain" | "safe" | "compat";
37
+ /**
38
+ * WeChat MP reply mode.
39
+ * - passive: Reply within 5-second webhook timeout (passive reply)
40
+ * - active: Use customer service API for active sending
41
+ */
42
+ export type WechatMpReplyMode = "passive" | "active";
43
+ /**
44
+ * WeChat MP active delivery mode.
45
+ * - merged: Buffer all chunks and send one final active message
46
+ * - split: Send each chunk as its own active message
47
+ */
48
+ export type WechatMpActiveDeliveryMode = "merged" | "split";
49
+ /**
50
+ * Per-account configuration for WeChat MP.
51
+ */
52
+ export type WechatMpAccountConfig = {
53
+ name?: string;
54
+ enabled?: boolean;
55
+ appId?: string;
56
+ appSecret?: string;
57
+ encodingAESKey?: string;
58
+ token?: string;
59
+ webhookPath?: string;
60
+ messageMode?: WechatMpMessageMode;
61
+ replyMode?: WechatMpReplyMode;
62
+ activeDeliveryMode?: WechatMpActiveDeliveryMode;
63
+ /** Whether to render markdown-friendly text; default true. Set false to disable. */
64
+ renderMarkdown?: boolean;
65
+ welcomeText?: string;
66
+ dmPolicy?: WechatMpDmPolicy;
67
+ allowFrom?: string[];
68
+ };
69
+ /**
70
+ * Root configuration for WeChat MP channel.
71
+ * Supports multi-account via accounts object.
72
+ */
73
+ export type WechatMpConfig = WechatMpAccountConfig & {
74
+ accounts?: Record<string, WechatMpAccountConfig>;
75
+ defaultAccount?: string;
76
+ };
77
+ /**
78
+ * Plugin configuration interface (partial).
79
+ */
80
+ export interface PluginConfig {
81
+ session?: {
82
+ store?: unknown;
83
+ };
84
+ channels?: Record<string, unknown> & {
85
+ "wechat-mp"?: WechatMpConfig;
86
+ };
87
+ [key: string]: unknown;
88
+ }
89
+ /**
90
+ * Resolved account with all configuration merged and validated.
91
+ */
92
+ export type ResolvedWechatMpAccount = {
93
+ accountId: string;
94
+ name?: string;
95
+ enabled: boolean;
96
+ configured: boolean;
97
+ appId?: string;
98
+ appSecret?: string;
99
+ encodingAESKey?: string;
100
+ token?: string;
101
+ canSendActive: boolean;
102
+ config: WechatMpAccountConfig;
103
+ };
104
+ /**
105
+ * WeChat MP access token cache entry.
106
+ */
107
+ export type AccessTokenCacheEntry = {
108
+ token: string;
109
+ expiresAt: number;
110
+ };
111
+ /**
112
+ * WeChat MP inbound text message structure.
113
+ */
114
+ export type WechatMpTextMessage = {
115
+ ToUserName: string;
116
+ FromUserName: string;
117
+ CreateTime: number;
118
+ MsgType: "text";
119
+ Content: string;
120
+ MsgId: string;
121
+ };
122
+ /**
123
+ * WeChat MP inbound event message structure.
124
+ */
125
+ export type WechatMpEventMessage = {
126
+ ToUserName: string;
127
+ FromUserName: string;
128
+ CreateTime: number;
129
+ MsgType: "event";
130
+ Event: string;
131
+ EventKey?: string;
132
+ Ticket?: string;
133
+ };
134
+ /**
135
+ * WeChat MP inbound image message structure.
136
+ */
137
+ export type WechatMpImageMessage = {
138
+ ToUserName: string;
139
+ FromUserName: string;
140
+ CreateTime: number;
141
+ MsgType: "image";
142
+ PicUrl: string;
143
+ MediaId: string;
144
+ MsgId: string;
145
+ };
146
+ /**
147
+ * Union type for all WeChat MP inbound messages.
148
+ */
149
+ export type WechatMpInboundMessage = WechatMpTextMessage | WechatMpEventMessage | WechatMpImageMessage | (Record<string, unknown> & {
150
+ MsgType: string;
151
+ });
152
+ /**
153
+ * WeChat MP account state for tracking runtime status.
154
+ */
155
+ export type WechatMpAccountState = {
156
+ configured?: boolean;
157
+ running?: boolean;
158
+ webhookPath?: string;
159
+ lastStartAt?: number;
160
+ lastStopAt?: number;
161
+ lastInboundAt?: number;
162
+ lastOutboundAt?: number;
163
+ lastIntentfulAt?: number;
164
+ lastError?: string;
165
+ lastMessageId?: string;
166
+ lastEvent?: string;
167
+ lastFromUserName?: string;
168
+ };
169
+ /**
170
+ * WeChat MP persisted state structure.
171
+ */
172
+ export type WechatMpPersistedState = {
173
+ version: 1;
174
+ processedMsgIds: Record<string, number>;
175
+ accounts: Record<string, WechatMpAccountState>;
176
+ };
177
+ export type WechatMpInboundEventName = "subscribe" | "unsubscribe" | "scan" | "click" | "view";
178
+ export type WechatMpInboundCandidate = {
179
+ accountId: string;
180
+ openId: string;
181
+ appId?: string;
182
+ target: string;
183
+ sessionKey?: string;
184
+ createTime: number;
185
+ msgType: "text" | "event";
186
+ msgId?: string;
187
+ dedupeKey: string;
188
+ encrypted: boolean;
189
+ hasUserIntent: boolean;
190
+ content?: string;
191
+ event?: WechatMpInboundEventName;
192
+ eventKey?: string;
193
+ ticket?: string;
194
+ toUserName?: string;
195
+ raw: WechatMpInboundMessage;
196
+ };
197
+ /**
198
+ * Webhook target registration parameters.
199
+ */
200
+ export type WebhookTarget = {
201
+ account: ResolvedWechatMpAccount;
202
+ config: PluginConfig;
203
+ runtime: {
204
+ log: (message: string) => void;
205
+ error: (message: string) => void;
206
+ };
207
+ path: string;
208
+ statusSink?: (patch: Record<string, unknown>) => void;
209
+ };
210
+ /**
211
+ * Plugin runtime interface defining host capabilities needed by the plugin.
212
+ */
213
+ export interface PluginRuntime {
214
+ log?: (message: string) => void;
215
+ error?: (message: string) => void;
216
+ channel?: {
217
+ routing?: {
218
+ resolveAgentRoute?: (params: {
219
+ cfg: unknown;
220
+ channel: string;
221
+ accountId?: string;
222
+ peer: {
223
+ kind: string;
224
+ id: string;
225
+ };
226
+ }) => {
227
+ sessionKey: string;
228
+ accountId: string;
229
+ agentId?: string;
230
+ mainSessionKey?: string;
231
+ };
232
+ };
233
+ reply?: {
234
+ dispatchReplyWithBufferedBlockDispatcher?: (params: {
235
+ ctx: unknown;
236
+ cfg: unknown;
237
+ dispatcherOptions: {
238
+ deliver: (payload: {
239
+ text?: string;
240
+ }) => Promise<void>;
241
+ onError?: (err: unknown, info: {
242
+ kind: string;
243
+ }) => void;
244
+ };
245
+ }) => Promise<void>;
246
+ finalizeInboundContext?: (ctx: unknown) => unknown;
247
+ resolveEnvelopeFormatOptions?: (cfg: unknown) => unknown;
248
+ formatAgentEnvelope?: (params: {
249
+ channel: string;
250
+ from: string;
251
+ previousTimestamp?: number;
252
+ envelope?: unknown;
253
+ body: string;
254
+ }) => string;
255
+ };
256
+ session?: {
257
+ resolveStorePath?: (store: unknown, params: {
258
+ agentId?: string;
259
+ }) => string | undefined;
260
+ readSessionUpdatedAt?: (params: {
261
+ storePath?: string;
262
+ sessionKey: string;
263
+ }) => number | null;
264
+ recordInboundSession?: (params: {
265
+ storePath: string;
266
+ sessionKey: string;
267
+ ctx: unknown;
268
+ updateLastRoute?: {
269
+ sessionKey: string;
270
+ channel: string;
271
+ to: string;
272
+ accountId?: string;
273
+ threadId?: string | number;
274
+ };
275
+ onRecordError?: (err: unknown) => void;
276
+ }) => Promise<void>;
277
+ };
278
+ text?: {
279
+ resolveMarkdownTableMode?: (params: {
280
+ cfg: unknown;
281
+ channel: string;
282
+ accountId?: string;
283
+ }) => unknown;
284
+ convertMarkdownTables?: (text: string, mode: unknown) => string;
285
+ };
286
+ };
287
+ [key: string]: unknown;
288
+ }
289
+ type HttpRouteMatch = "exact" | "prefix";
290
+ type HttpRouteAuth = "gateway" | "plugin";
291
+ /**
292
+ * HTTP route registration parameters.
293
+ */
294
+ export type HttpRouteParams = {
295
+ path: string;
296
+ auth: HttpRouteAuth;
297
+ match?: HttpRouteMatch;
298
+ handler: (req: IncomingMessage, res: ServerResponse) => Promise<boolean> | boolean;
299
+ };
300
+ /**
301
+ * Moltbot plugin API interface for host registration.
302
+ */
303
+ export interface MoltbotPluginApi {
304
+ registerChannel: (opts: {
305
+ plugin: unknown;
306
+ }) => void;
307
+ registerCli?: (registrar: (ctx: {
308
+ program: unknown;
309
+ config?: PluginConfig;
310
+ }) => void | Promise<void>, opts?: {
311
+ commands?: string[];
312
+ }) => void;
313
+ registerHttpHandler?: (handler: (req: IncomingMessage, res: ServerResponse) => Promise<boolean> | boolean) => void;
314
+ registerHttpRoute?: (params: HttpRouteParams) => void;
315
+ config?: PluginConfig;
316
+ runtime?: unknown;
317
+ [key: string]: unknown;
318
+ }
319
+ export {};
320
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,6 @@
1
+ import type { IncomingMessage, ServerResponse } from "http";
2
+ import type { PluginConfig, WebhookTarget } from "./types.js";
3
+ export declare function registerWechatMpWebhookTarget(target: WebhookTarget): () => void;
4
+ export declare function handleWechatMpWebhookRequest(req: IncomingMessage, res: ServerResponse): Promise<boolean>;
5
+ export declare function collectWechatMpWebhookTargets(cfg: PluginConfig): WebhookTarget[];
6
+ //# sourceMappingURL=webhook.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"webhook.d.ts","sourceRoot":"","sources":["../../src/webhook.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,MAAM,CAAC;AAc5D,OAAO,KAAK,EAAE,YAAY,EAA2B,aAAa,EAA4B,MAAM,YAAY,CAAC;AAiPjH,wBAAgB,6BAA6B,CAAC,MAAM,EAAE,aAAa,GAAG,MAAM,IAAI,CAa/E;AAED,wBAAsB,4BAA4B,CAChD,GAAG,EAAE,eAAe,EACpB,GAAG,EAAE,cAAc,GAClB,OAAO,CAAC,OAAO,CAAC,CAoKlB;AAED,wBAAgB,6BAA6B,CAAC,GAAG,EAAE,YAAY,GAAG,aAAa,EAAE,CA6BhF"}