@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.
- package/README.md +74 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +59 -0
- package/dist/index.js.map +1 -0
- package/dist/src/api.d.ts +101 -0
- package/dist/src/api.d.ts.map +1 -0
- package/dist/src/api.js +142 -0
- package/dist/src/api.js.map +1 -0
- package/dist/src/channel.d.ts +296 -0
- package/dist/src/channel.d.ts.map +1 -0
- package/dist/src/channel.js +341 -0
- package/dist/src/channel.js.map +1 -0
- package/dist/src/config.d.ts +69 -0
- package/dist/src/config.d.ts.map +1 -0
- package/dist/src/config.js +167 -0
- package/dist/src/config.js.map +1 -0
- package/dist/src/crypto.d.ts +117 -0
- package/dist/src/crypto.d.ts.map +1 -0
- package/dist/src/crypto.js +270 -0
- package/dist/src/crypto.js.map +1 -0
- package/dist/src/crypto.test.d.ts +2 -0
- package/dist/src/crypto.test.d.ts.map +1 -0
- package/dist/src/crypto.test.js +76 -0
- package/dist/src/crypto.test.js.map +1 -0
- package/dist/src/dispatch.d.ts +15 -0
- package/dist/src/dispatch.d.ts.map +1 -0
- package/dist/src/dispatch.js +193 -0
- package/dist/src/dispatch.js.map +1 -0
- package/dist/src/dispatch.test.d.ts +2 -0
- package/dist/src/dispatch.test.d.ts.map +1 -0
- package/dist/src/dispatch.test.js +231 -0
- package/dist/src/dispatch.test.js.map +1 -0
- package/dist/src/inbound.d.ts +7 -0
- package/dist/src/inbound.d.ts.map +1 -0
- package/dist/src/inbound.js +82 -0
- package/dist/src/inbound.js.map +1 -0
- package/dist/src/onboarding.d.ts +25 -0
- package/dist/src/onboarding.d.ts.map +1 -0
- package/dist/src/onboarding.js +49 -0
- package/dist/src/onboarding.js.map +1 -0
- package/dist/src/outbound.d.ts +17 -0
- package/dist/src/outbound.d.ts.map +1 -0
- package/dist/src/outbound.js +55 -0
- package/dist/src/outbound.js.map +1 -0
- package/dist/src/outbound.test.d.ts +2 -0
- package/dist/src/outbound.test.d.ts.map +1 -0
- package/dist/src/outbound.test.js +175 -0
- package/dist/src/outbound.test.js.map +1 -0
- package/dist/src/probe.d.ts +15 -0
- package/dist/src/probe.d.ts.map +1 -0
- package/dist/src/probe.js +55 -0
- package/dist/src/probe.js.map +1 -0
- package/dist/src/runtime.d.ts +22 -0
- package/dist/src/runtime.d.ts.map +1 -0
- package/dist/src/runtime.js +33 -0
- package/dist/src/runtime.js.map +1 -0
- package/dist/src/send.d.ts +27 -0
- package/dist/src/send.d.ts.map +1 -0
- package/dist/src/send.js +103 -0
- package/dist/src/send.js.map +1 -0
- package/dist/src/state.d.ts +7 -0
- package/dist/src/state.d.ts.map +1 -0
- package/dist/src/state.js +109 -0
- package/dist/src/state.js.map +1 -0
- package/dist/src/text.d.ts +46 -0
- package/dist/src/text.d.ts.map +1 -0
- package/dist/src/text.js +192 -0
- package/dist/src/text.js.map +1 -0
- package/dist/src/text.test.d.ts +2 -0
- package/dist/src/text.test.d.ts.map +1 -0
- package/dist/src/text.test.js +110 -0
- package/dist/src/text.test.js.map +1 -0
- package/dist/src/token.d.ts +40 -0
- package/dist/src/token.d.ts.map +1 -0
- package/dist/src/token.js +154 -0
- package/dist/src/token.js.map +1 -0
- package/dist/src/token.test.d.ts +2 -0
- package/dist/src/token.test.d.ts.map +1 -0
- package/dist/src/token.test.js +74 -0
- package/dist/src/token.test.js.map +1 -0
- package/dist/src/types.d.ts +320 -0
- package/dist/src/types.d.ts.map +1 -0
- package/dist/src/types.js +2 -0
- package/dist/src/types.js.map +1 -0
- package/dist/src/webhook.d.ts +6 -0
- package/dist/src/webhook.d.ts.map +1 -0
- package/dist/src/webhook.js +381 -0
- package/dist/src/webhook.js.map +1 -0
- package/dist/src/webhook.test.d.ts +2 -0
- package/dist/src/webhook.test.d.ts.map +1 -0
- package/dist/src/webhook.test.js +737 -0
- package/dist/src/webhook.test.js.map +1 -0
- package/openclaw.plugin.json +83 -0
- 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":"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"}
|
|
@@ -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":"AAAA,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAE7D,OAAO,EACL,qBAAqB,EACrB,wBAAwB,EACxB,cAAc,EACd,mBAAmB,EACnB,mBAAmB,EACnB,YAAY,EACZ,kBAAkB,GACnB,MAAM,YAAY,CAAC;AAGpB,SAAS,aAAa,CAAC,SAA4C;IACjE,OAAO;QACL,SAAS,EAAE,SAAS;QACpB,IAAI,EAAE,qBAAqB;QAC3B,OAAO,EAAE,IAAI;QACb,UAAU,EAAE,IAAI;QAChB,aAAa,EAAE,IAAI;QACnB,MAAM,EAAE;YACN,KAAK,EAAE,eAAe;YACtB,SAAS,EAAE,QAAQ;YACnB,KAAK,EAAE,OAAO;YACd,cAAc,EAAE,6CAA6C;YAC7D,WAAW,EAAE,YAAY;YACzB,WAAW,EAAE,MAAM;YACnB,SAAS,EAAE,SAAS;SACrB;QACD,GAAG,SAAS;KACb,CAAC;AACJ,CAAC;AAED,SAAS,CAAC,GAAG,EAAE;IACb,wBAAwB,EAAE,CAAC;IAC3B,EAAE,CAAC,gBAAgB,EAAE,CAAC;IACtB,EAAE,CAAC,eAAe,EAAE,CAAC;AACvB,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,iBAAiB,EAAE,GAAG,EAAE;IAC/B,EAAE,CAAC,iCAAiC,EAAE,KAAK,IAAI,EAAE;QAC/C,MAAM,SAAS,GAAG,EAAE,CAAC,EAAE,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;YACnC,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC;gBACjB,YAAY,EAAE,SAAS;gBACvB,UAAU,EAAE,IAAI;aACjB,CAAC;SACH,CAAC,CAAC,CAAC;QACJ,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,SAAoC,CAAC,CAAC;QAE7D,MAAM,OAAO,GAAG,aAAa,EAAE,CAAC;QAChC,MAAM,KAAK,GAAG,MAAM,cAAc,CAAC,OAAO,CAAC,CAAC;QAC5C,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,OAAO,CAAC,CAAC;QAE7C,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAC9B,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAC/B,MAAM,CAAC,SAAS,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;QAC3C,MAAM,CAAC,mBAAmB,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACzD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6BAA6B,EAAE,KAAK,IAAI,EAAE;QAC3C,MAAM,SAAS,GAAG,EAAE;aACjB,EAAE,EAAE;aACJ,qBAAqB,CAAC,EAAE,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC,EAAE,YAAY,EAAE,SAAS,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;aAC5F,qBAAqB,CAAC,EAAE,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC,EAAE,YAAY,EAAE,SAAS,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC;QAChG,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,SAAoC,CAAC,CAAC;QAE7D,MAAM,OAAO,GAAG,aAAa,EAAE,CAAC;QAChC,MAAM,CAAC,MAAM,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACtD,qBAAqB,CAAC,OAAO,CAAC,CAAC;QAC/B,MAAM,CAAC,MAAM,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACpD,MAAM,CAAC,SAAS,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;IAC7C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mCAAmC,EAAE,GAAG,EAAE;QAC3C,MAAM,CAAC,mBAAmB,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC9C,MAAM,CAAC,mBAAmB,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC9C,MAAM,CAAC,mBAAmB,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACjD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wCAAwC,EAAE,KAAK,IAAI,EAAE;QACtD,MAAM,SAAS,GAAG,EAAE,CAAC,EAAE,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;YACnC,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC;gBACjB,YAAY,EAAE,SAAS;gBACvB,UAAU,EAAE,EAAE;aACf,CAAC;SACH,CAAC,CAAC,CAAC;QACJ,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,SAAoC,CAAC,CAAC;QAE7D,MAAM,OAAO,GAAG,aAAa,EAAE,CAAC;QAChC,MAAM,cAAc,CAAC,OAAO,CAAC,CAAC;QAC9B,MAAM,CAAC,OAAO,kBAAkB,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAC7D,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -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 @@
|
|
|
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"}
|