moltbot-wecom 1.0.2 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/clawdbot.plugin.json +42 -0
  2. package/dist/index.d.ts +29 -0
  3. package/dist/index.d.ts.map +1 -0
  4. package/dist/index.js +31 -0
  5. package/dist/src/accounts.d.ts +15 -0
  6. package/dist/src/accounts.d.ts.map +1 -0
  7. package/dist/src/accounts.js +90 -0
  8. package/dist/src/channel.d.ts +8 -0
  9. package/dist/src/channel.d.ts.map +1 -0
  10. package/dist/src/channel.js +365 -0
  11. package/dist/src/config-schema.d.ts +211 -0
  12. package/dist/src/config-schema.d.ts.map +1 -0
  13. package/dist/src/config-schema.js +21 -0
  14. package/dist/src/dedup.d.ts +8 -0
  15. package/dist/src/dedup.d.ts.map +1 -0
  16. package/dist/src/dedup.js +24 -0
  17. package/dist/src/group-filter.d.ts +15 -0
  18. package/dist/src/group-filter.d.ts.map +1 -0
  19. package/dist/src/group-filter.js +43 -0
  20. package/dist/src/probe.d.ts +10 -0
  21. package/dist/src/probe.d.ts.map +1 -0
  22. package/dist/src/probe.js +70 -0
  23. package/dist/src/receive.d.ts +26 -0
  24. package/dist/src/receive.d.ts.map +1 -0
  25. package/dist/src/receive.js +282 -0
  26. package/dist/src/runtime.d.ts +7 -0
  27. package/dist/src/runtime.d.ts.map +1 -0
  28. package/dist/src/runtime.js +13 -0
  29. package/dist/src/send.d.ts +26 -0
  30. package/dist/src/send.d.ts.map +1 -0
  31. package/dist/src/send.js +75 -0
  32. package/dist/src/status-issues.d.ts +7 -0
  33. package/dist/src/status-issues.d.ts.map +1 -0
  34. package/dist/src/status-issues.js +47 -0
  35. package/dist/src/types.d.ts +79 -0
  36. package/dist/src/types.d.ts.map +1 -0
  37. package/dist/src/types.js +4 -0
  38. package/package.json +28 -11
  39. package/moltbot.plugin.json +0 -27
  40. package/plugin.js +0 -243
@@ -0,0 +1,211 @@
1
+ /**
2
+ * WeCom config Zod schema for validation.
3
+ */
4
+ import { z } from "zod";
5
+ export declare const WeComConfigSchema: z.ZodObject<{
6
+ name: z.ZodOptional<z.ZodString>;
7
+ enabled: z.ZodOptional<z.ZodBoolean>;
8
+ proxyUrl: z.ZodOptional<z.ZodString>;
9
+ proxyToken: z.ZodOptional<z.ZodString>;
10
+ dmPolicy: z.ZodOptional<z.ZodEnum<["pairing", "allowlist", "open", "disabled"]>>;
11
+ allowFrom: z.ZodOptional<z.ZodArray<z.ZodUnion<[z.ZodString, z.ZodNumber]>, "many">>;
12
+ thinkingThresholdMs: z.ZodOptional<z.ZodNumber>;
13
+ botNames: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
14
+ pingIntervalMs: z.ZodOptional<z.ZodNumber>;
15
+ reconnectDelayMs: z.ZodOptional<z.ZodNumber>;
16
+ } & {
17
+ accounts: z.ZodOptional<z.ZodObject<{}, "strip", z.ZodObject<{
18
+ name: z.ZodOptional<z.ZodString>;
19
+ enabled: z.ZodOptional<z.ZodBoolean>;
20
+ proxyUrl: z.ZodOptional<z.ZodString>;
21
+ proxyToken: z.ZodOptional<z.ZodString>;
22
+ dmPolicy: z.ZodOptional<z.ZodEnum<["pairing", "allowlist", "open", "disabled"]>>;
23
+ allowFrom: z.ZodOptional<z.ZodArray<z.ZodUnion<[z.ZodString, z.ZodNumber]>, "many">>;
24
+ thinkingThresholdMs: z.ZodOptional<z.ZodNumber>;
25
+ botNames: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
26
+ pingIntervalMs: z.ZodOptional<z.ZodNumber>;
27
+ reconnectDelayMs: z.ZodOptional<z.ZodNumber>;
28
+ }, "strip", z.ZodTypeAny, {
29
+ name?: string | undefined;
30
+ enabled?: boolean | undefined;
31
+ proxyUrl?: string | undefined;
32
+ proxyToken?: string | undefined;
33
+ dmPolicy?: "pairing" | "allowlist" | "open" | "disabled" | undefined;
34
+ allowFrom?: (string | number)[] | undefined;
35
+ thinkingThresholdMs?: number | undefined;
36
+ botNames?: string[] | undefined;
37
+ pingIntervalMs?: number | undefined;
38
+ reconnectDelayMs?: number | undefined;
39
+ }, {
40
+ name?: string | undefined;
41
+ enabled?: boolean | undefined;
42
+ proxyUrl?: string | undefined;
43
+ proxyToken?: string | undefined;
44
+ dmPolicy?: "pairing" | "allowlist" | "open" | "disabled" | undefined;
45
+ allowFrom?: (string | number)[] | undefined;
46
+ thinkingThresholdMs?: number | undefined;
47
+ botNames?: string[] | undefined;
48
+ pingIntervalMs?: number | undefined;
49
+ reconnectDelayMs?: number | undefined;
50
+ }>, z.objectOutputType<{}, z.ZodObject<{
51
+ name: z.ZodOptional<z.ZodString>;
52
+ enabled: z.ZodOptional<z.ZodBoolean>;
53
+ proxyUrl: z.ZodOptional<z.ZodString>;
54
+ proxyToken: z.ZodOptional<z.ZodString>;
55
+ dmPolicy: z.ZodOptional<z.ZodEnum<["pairing", "allowlist", "open", "disabled"]>>;
56
+ allowFrom: z.ZodOptional<z.ZodArray<z.ZodUnion<[z.ZodString, z.ZodNumber]>, "many">>;
57
+ thinkingThresholdMs: z.ZodOptional<z.ZodNumber>;
58
+ botNames: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
59
+ pingIntervalMs: z.ZodOptional<z.ZodNumber>;
60
+ reconnectDelayMs: z.ZodOptional<z.ZodNumber>;
61
+ }, "strip", z.ZodTypeAny, {
62
+ name?: string | undefined;
63
+ enabled?: boolean | undefined;
64
+ proxyUrl?: string | undefined;
65
+ proxyToken?: string | undefined;
66
+ dmPolicy?: "pairing" | "allowlist" | "open" | "disabled" | undefined;
67
+ allowFrom?: (string | number)[] | undefined;
68
+ thinkingThresholdMs?: number | undefined;
69
+ botNames?: string[] | undefined;
70
+ pingIntervalMs?: number | undefined;
71
+ reconnectDelayMs?: number | undefined;
72
+ }, {
73
+ name?: string | undefined;
74
+ enabled?: boolean | undefined;
75
+ proxyUrl?: string | undefined;
76
+ proxyToken?: string | undefined;
77
+ dmPolicy?: "pairing" | "allowlist" | "open" | "disabled" | undefined;
78
+ allowFrom?: (string | number)[] | undefined;
79
+ thinkingThresholdMs?: number | undefined;
80
+ botNames?: string[] | undefined;
81
+ pingIntervalMs?: number | undefined;
82
+ reconnectDelayMs?: number | undefined;
83
+ }>, "strip">, z.objectInputType<{}, z.ZodObject<{
84
+ name: z.ZodOptional<z.ZodString>;
85
+ enabled: z.ZodOptional<z.ZodBoolean>;
86
+ proxyUrl: z.ZodOptional<z.ZodString>;
87
+ proxyToken: z.ZodOptional<z.ZodString>;
88
+ dmPolicy: z.ZodOptional<z.ZodEnum<["pairing", "allowlist", "open", "disabled"]>>;
89
+ allowFrom: z.ZodOptional<z.ZodArray<z.ZodUnion<[z.ZodString, z.ZodNumber]>, "many">>;
90
+ thinkingThresholdMs: z.ZodOptional<z.ZodNumber>;
91
+ botNames: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
92
+ pingIntervalMs: z.ZodOptional<z.ZodNumber>;
93
+ reconnectDelayMs: z.ZodOptional<z.ZodNumber>;
94
+ }, "strip", z.ZodTypeAny, {
95
+ name?: string | undefined;
96
+ enabled?: boolean | undefined;
97
+ proxyUrl?: string | undefined;
98
+ proxyToken?: string | undefined;
99
+ dmPolicy?: "pairing" | "allowlist" | "open" | "disabled" | undefined;
100
+ allowFrom?: (string | number)[] | undefined;
101
+ thinkingThresholdMs?: number | undefined;
102
+ botNames?: string[] | undefined;
103
+ pingIntervalMs?: number | undefined;
104
+ reconnectDelayMs?: number | undefined;
105
+ }, {
106
+ name?: string | undefined;
107
+ enabled?: boolean | undefined;
108
+ proxyUrl?: string | undefined;
109
+ proxyToken?: string | undefined;
110
+ dmPolicy?: "pairing" | "allowlist" | "open" | "disabled" | undefined;
111
+ allowFrom?: (string | number)[] | undefined;
112
+ thinkingThresholdMs?: number | undefined;
113
+ botNames?: string[] | undefined;
114
+ pingIntervalMs?: number | undefined;
115
+ reconnectDelayMs?: number | undefined;
116
+ }>, "strip">>>;
117
+ defaultAccount: z.ZodOptional<z.ZodString>;
118
+ }, "strip", z.ZodTypeAny, {
119
+ defaultAccount?: string | undefined;
120
+ accounts?: z.objectOutputType<{}, z.ZodObject<{
121
+ name: z.ZodOptional<z.ZodString>;
122
+ enabled: z.ZodOptional<z.ZodBoolean>;
123
+ proxyUrl: z.ZodOptional<z.ZodString>;
124
+ proxyToken: z.ZodOptional<z.ZodString>;
125
+ dmPolicy: z.ZodOptional<z.ZodEnum<["pairing", "allowlist", "open", "disabled"]>>;
126
+ allowFrom: z.ZodOptional<z.ZodArray<z.ZodUnion<[z.ZodString, z.ZodNumber]>, "many">>;
127
+ thinkingThresholdMs: z.ZodOptional<z.ZodNumber>;
128
+ botNames: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
129
+ pingIntervalMs: z.ZodOptional<z.ZodNumber>;
130
+ reconnectDelayMs: z.ZodOptional<z.ZodNumber>;
131
+ }, "strip", z.ZodTypeAny, {
132
+ name?: string | undefined;
133
+ enabled?: boolean | undefined;
134
+ proxyUrl?: string | undefined;
135
+ proxyToken?: string | undefined;
136
+ dmPolicy?: "pairing" | "allowlist" | "open" | "disabled" | undefined;
137
+ allowFrom?: (string | number)[] | undefined;
138
+ thinkingThresholdMs?: number | undefined;
139
+ botNames?: string[] | undefined;
140
+ pingIntervalMs?: number | undefined;
141
+ reconnectDelayMs?: number | undefined;
142
+ }, {
143
+ name?: string | undefined;
144
+ enabled?: boolean | undefined;
145
+ proxyUrl?: string | undefined;
146
+ proxyToken?: string | undefined;
147
+ dmPolicy?: "pairing" | "allowlist" | "open" | "disabled" | undefined;
148
+ allowFrom?: (string | number)[] | undefined;
149
+ thinkingThresholdMs?: number | undefined;
150
+ botNames?: string[] | undefined;
151
+ pingIntervalMs?: number | undefined;
152
+ reconnectDelayMs?: number | undefined;
153
+ }>, "strip"> | undefined;
154
+ name?: string | undefined;
155
+ enabled?: boolean | undefined;
156
+ proxyUrl?: string | undefined;
157
+ proxyToken?: string | undefined;
158
+ dmPolicy?: "pairing" | "allowlist" | "open" | "disabled" | undefined;
159
+ allowFrom?: (string | number)[] | undefined;
160
+ thinkingThresholdMs?: number | undefined;
161
+ botNames?: string[] | undefined;
162
+ pingIntervalMs?: number | undefined;
163
+ reconnectDelayMs?: number | undefined;
164
+ }, {
165
+ defaultAccount?: string | undefined;
166
+ accounts?: z.objectInputType<{}, z.ZodObject<{
167
+ name: z.ZodOptional<z.ZodString>;
168
+ enabled: z.ZodOptional<z.ZodBoolean>;
169
+ proxyUrl: z.ZodOptional<z.ZodString>;
170
+ proxyToken: z.ZodOptional<z.ZodString>;
171
+ dmPolicy: z.ZodOptional<z.ZodEnum<["pairing", "allowlist", "open", "disabled"]>>;
172
+ allowFrom: z.ZodOptional<z.ZodArray<z.ZodUnion<[z.ZodString, z.ZodNumber]>, "many">>;
173
+ thinkingThresholdMs: z.ZodOptional<z.ZodNumber>;
174
+ botNames: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
175
+ pingIntervalMs: z.ZodOptional<z.ZodNumber>;
176
+ reconnectDelayMs: z.ZodOptional<z.ZodNumber>;
177
+ }, "strip", z.ZodTypeAny, {
178
+ name?: string | undefined;
179
+ enabled?: boolean | undefined;
180
+ proxyUrl?: string | undefined;
181
+ proxyToken?: string | undefined;
182
+ dmPolicy?: "pairing" | "allowlist" | "open" | "disabled" | undefined;
183
+ allowFrom?: (string | number)[] | undefined;
184
+ thinkingThresholdMs?: number | undefined;
185
+ botNames?: string[] | undefined;
186
+ pingIntervalMs?: number | undefined;
187
+ reconnectDelayMs?: number | undefined;
188
+ }, {
189
+ name?: string | undefined;
190
+ enabled?: boolean | undefined;
191
+ proxyUrl?: string | undefined;
192
+ proxyToken?: string | undefined;
193
+ dmPolicy?: "pairing" | "allowlist" | "open" | "disabled" | undefined;
194
+ allowFrom?: (string | number)[] | undefined;
195
+ thinkingThresholdMs?: number | undefined;
196
+ botNames?: string[] | undefined;
197
+ pingIntervalMs?: number | undefined;
198
+ reconnectDelayMs?: number | undefined;
199
+ }>, "strip"> | undefined;
200
+ name?: string | undefined;
201
+ enabled?: boolean | undefined;
202
+ proxyUrl?: string | undefined;
203
+ proxyToken?: string | undefined;
204
+ dmPolicy?: "pairing" | "allowlist" | "open" | "disabled" | undefined;
205
+ allowFrom?: (string | number)[] | undefined;
206
+ thinkingThresholdMs?: number | undefined;
207
+ botNames?: string[] | undefined;
208
+ pingIntervalMs?: number | undefined;
209
+ reconnectDelayMs?: number | undefined;
210
+ }>;
211
+ //# sourceMappingURL=config-schema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-schema.d.ts","sourceRoot":"","sources":["../../src/config-schema.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAiBxB,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAG5B,CAAC"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * WeCom config Zod schema for validation.
3
+ */
4
+ import { z } from "zod";
5
+ const allowFromEntry = z.union([z.string(), z.number()]);
6
+ const wecomAccountSchema = z.object({
7
+ name: z.string().optional(),
8
+ enabled: z.boolean().optional(),
9
+ proxyUrl: z.string().optional(),
10
+ proxyToken: z.string().optional(),
11
+ dmPolicy: z.enum(["pairing", "allowlist", "open", "disabled"]).optional(),
12
+ allowFrom: z.array(allowFromEntry).optional(),
13
+ thinkingThresholdMs: z.number().optional(),
14
+ botNames: z.array(z.string()).optional(),
15
+ pingIntervalMs: z.number().optional(),
16
+ reconnectDelayMs: z.number().optional(),
17
+ });
18
+ export const WeComConfigSchema = wecomAccountSchema.extend({
19
+ accounts: z.object({}).catchall(wecomAccountSchema).optional(),
20
+ defaultAccount: z.string().optional(),
21
+ });
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Message deduplication — WeCom may deliver the same event more than once.
3
+ */
4
+ /** Garbage-collect expired entries and check for duplicates. */
5
+ export declare function isDuplicate(messageId: string | undefined | null): boolean;
6
+ /** Clear all dedup state (for testing). */
7
+ export declare function clearDedup(): void;
8
+ //# sourceMappingURL=dedup.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dedup.d.ts","sourceRoot":"","sources":["../../src/dedup.ts"],"names":[],"mappings":"AAAA;;GAEG;AAMH,gEAAgE;AAChE,wBAAgB,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,GAAG,OAAO,CAYzE;AAED,2CAA2C;AAC3C,wBAAgB,UAAU,IAAI,IAAI,CAEjC"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Message deduplication — WeCom may deliver the same event more than once.
3
+ */
4
+ const SEEN_TTL_MS = 10 * 60 * 1000; // 10 minutes
5
+ const seen = new Map();
6
+ /** Garbage-collect expired entries and check for duplicates. */
7
+ export function isDuplicate(messageId) {
8
+ const now = Date.now();
9
+ // GC old entries
10
+ for (const [k, ts] of seen) {
11
+ if (now - ts > SEEN_TTL_MS)
12
+ seen.delete(k);
13
+ }
14
+ if (!messageId)
15
+ return false;
16
+ if (seen.has(messageId))
17
+ return true;
18
+ seen.set(messageId, now);
19
+ return false;
20
+ }
21
+ /** Clear all dedup state (for testing). */
22
+ export function clearDedup() {
23
+ seen.clear();
24
+ }
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Smart group chat reply filter.
3
+ *
4
+ * In group chats, only respond when the message looks like a real
5
+ * question, request, or direct address — avoids spamming.
6
+ */
7
+ /**
8
+ * Determine whether the bot should respond to a group message.
9
+ *
10
+ * @param text - Message text (after stripping @mention placeholders)
11
+ * @param mentions - Array of mention objects from the event
12
+ * @param botNames - Custom bot name list for address detection
13
+ */
14
+ export declare function shouldRespondInGroup(text: string, mentions?: unknown[], botNames?: string[]): boolean;
15
+ //# sourceMappingURL=group-filter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"group-filter.d.ts","sourceRoot":"","sources":["../../src/group-filter.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,MAAM,EACZ,QAAQ,GAAE,OAAO,EAAO,EACxB,QAAQ,CAAC,EAAE,MAAM,EAAE,GAClB,OAAO,CA4BT"}
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Smart group chat reply filter.
3
+ *
4
+ * In group chats, only respond when the message looks like a real
5
+ * question, request, or direct address — avoids spamming.
6
+ */
7
+ /** Default bot name patterns for address detection. */
8
+ const DEFAULT_BOT_NAMES = ["clawdbot", "moltbot", "bot", "助手", "智能体", "小雀"];
9
+ /**
10
+ * Determine whether the bot should respond to a group message.
11
+ *
12
+ * @param text - Message text (after stripping @mention placeholders)
13
+ * @param mentions - Array of mention objects from the event
14
+ * @param botNames - Custom bot name list for address detection
15
+ */
16
+ export function shouldRespondInGroup(text, mentions = [], botNames) {
17
+ // Always respond to @-mentions
18
+ if (mentions.length > 0)
19
+ return true;
20
+ const t = text.toLowerCase();
21
+ // Ends with question mark
22
+ if (/[??]$/.test(text))
23
+ return true;
24
+ // English question words
25
+ if (/\b(why|how|what|when|where|who|help)\b/.test(t))
26
+ return true;
27
+ // Chinese request verbs
28
+ const verbs = [
29
+ "帮", "麻烦", "请", "能否", "可以", "解释", "看看",
30
+ "排查", "分析", "总结", "写", "改", "修", "查", "对比", "翻译",
31
+ ];
32
+ if (verbs.some((k) => text.includes(k)))
33
+ return true;
34
+ // Direct address by bot name
35
+ const names = botNames?.length ? botNames : DEFAULT_BOT_NAMES;
36
+ const namePattern = new RegExp(`^(${names.map(escapeRegex).join("|")})[\\s,:,:]`, "i");
37
+ if (namePattern.test(text))
38
+ return true;
39
+ return false;
40
+ }
41
+ function escapeRegex(s) {
42
+ return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
43
+ }
@@ -0,0 +1,10 @@
1
+ /**
2
+ * WeCom API connectivity probe.
3
+ */
4
+ import type { WeComProbeResult } from "./types.js";
5
+ /**
6
+ * Probe the WeCom proxy by attempting a WebSocket connection.
7
+ * Returns quickly to check if the proxy is reachable.
8
+ */
9
+ export declare function probeWeCom(proxyUrl: string, proxyToken: string, timeoutMs?: number): Promise<WeComProbeResult>;
10
+ //# sourceMappingURL=probe.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"probe.d.ts","sourceRoot":"","sources":["../../src/probe.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAEnD;;;GAGG;AACH,wBAAsB,UAAU,CAC9B,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,EAClB,SAAS,SAAO,GACf,OAAO,CAAC,gBAAgB,CAAC,CAqE3B"}
@@ -0,0 +1,70 @@
1
+ /**
2
+ * WeCom API connectivity probe.
3
+ */
4
+ /**
5
+ * Probe the WeCom proxy by attempting a WebSocket connection.
6
+ * Returns quickly to check if the proxy is reachable.
7
+ */
8
+ export async function probeWeCom(proxyUrl, proxyToken, timeoutMs = 5000) {
9
+ if (!proxyUrl?.trim()) {
10
+ return { ok: false, error: "Missing proxyUrl", elapsedMs: 0 };
11
+ }
12
+ const startTime = Date.now();
13
+ try {
14
+ // Dynamic import for WebSocket (works in both Node and Bun)
15
+ const { default: WebSocket } = await import("ws");
16
+ return new Promise((resolve) => {
17
+ const url = proxyToken
18
+ ? `${proxyUrl}?token=${encodeURIComponent(proxyToken)}`
19
+ : proxyUrl;
20
+ const ws = new WebSocket(url);
21
+ let resolved = false;
22
+ const timeout = setTimeout(() => {
23
+ if (!resolved) {
24
+ resolved = true;
25
+ ws.terminate();
26
+ resolve({
27
+ ok: false,
28
+ error: `Connection timed out after ${timeoutMs}ms`,
29
+ elapsedMs: Date.now() - startTime,
30
+ });
31
+ }
32
+ }, timeoutMs);
33
+ ws.on("open", () => {
34
+ if (!resolved) {
35
+ resolved = true;
36
+ clearTimeout(timeout);
37
+ ws.close();
38
+ resolve({ ok: true, elapsedMs: Date.now() - startTime });
39
+ }
40
+ });
41
+ ws.on("error", (err) => {
42
+ if (!resolved) {
43
+ resolved = true;
44
+ clearTimeout(timeout);
45
+ ws.terminate();
46
+ resolve({
47
+ ok: false,
48
+ error: err instanceof Error ? err.message : String(err),
49
+ elapsedMs: Date.now() - startTime,
50
+ });
51
+ }
52
+ });
53
+ ws.on("close", () => {
54
+ if (!resolved) {
55
+ resolved = true;
56
+ clearTimeout(timeout);
57
+ resolve({ ok: true, elapsedMs: Date.now() - startTime });
58
+ }
59
+ });
60
+ });
61
+ }
62
+ catch (err) {
63
+ const elapsedMs = Date.now() - startTime;
64
+ return {
65
+ ok: false,
66
+ error: err instanceof Error ? err.message : String(err),
67
+ elapsedMs,
68
+ };
69
+ }
70
+ }
@@ -0,0 +1,26 @@
1
+ /**
2
+ * WeCom WebSocket message receive handler.
3
+ *
4
+ * Connects to WeCom via a WebSocket proxy, dispatches incoming
5
+ * messages to Clawdbot's channel reply infrastructure.
6
+ */
7
+ import type { ClawdbotConfig } from "clawdbot/plugin-sdk";
8
+ import type { ResolvedWeComAccount } from "./types.js";
9
+ /** Options for the WeCom provider. */
10
+ export type WeComProviderOptions = {
11
+ account: ResolvedWeComAccount;
12
+ config: ClawdbotConfig;
13
+ log: {
14
+ info: (msg: string) => void;
15
+ error: (msg: string) => void;
16
+ debug?: (msg: string) => void;
17
+ warn?: (msg: string) => void;
18
+ };
19
+ abortSignal?: AbortSignal;
20
+ statusSink?: (patch: Record<string, unknown>) => void;
21
+ };
22
+ /** Start the WeCom WebSocket provider. Returns a stop function. */
23
+ export declare function startWeComProvider(options: WeComProviderOptions): {
24
+ stop: () => void;
25
+ };
26
+ //# sourceMappingURL=receive.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"receive.d.ts","sourceRoot":"","sources":["../../src/receive.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAG1D,OAAO,KAAK,EAAE,oBAAoB,EAAwB,MAAM,YAAY,CAAC;AAM7E,sCAAsC;AACtC,MAAM,MAAM,oBAAoB,GAAG;IACjC,OAAO,EAAE,oBAAoB,CAAC;IAC9B,MAAM,EAAE,cAAc,CAAC;IACvB,GAAG,EAAE;QACH,IAAI,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;QAC5B,KAAK,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;QAC7B,KAAK,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;QAC9B,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;KAC9B,CAAC;IACF,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;CACvD,CAAC;AAWF,mEAAmE;AACnE,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,oBAAoB,GAAG;IAAE,IAAI,EAAE,MAAM,IAAI,CAAA;CAAE,CA4JtF"}