@elizaos/plugin-wechat 2.0.0-alpha.537 → 2.0.3-beta.5

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/src/index.ts CHANGED
@@ -1,4 +1,15 @@
1
+ import {
2
+ type Content,
3
+ getConnectorAccountManager,
4
+ type IAgentRuntime,
5
+ type Memory,
6
+ type MessageConnectorTarget,
7
+ stringToUuid,
8
+ type TargetInfo,
9
+ type UUID,
10
+ } from "@elizaos/core";
1
11
  import { WechatChannel } from "./channel";
12
+ import { createWechatConnectorAccountProvider } from "./connector-account-provider";
2
13
  import { deliverIncomingWechatMessage } from "./runtime-bridge";
3
14
  import type { WechatConfig, WechatMessageContext } from "./types";
4
15
 
@@ -37,17 +48,337 @@ export interface Plugin {
37
48
  config: Record<string, unknown>,
38
49
  runtime: unknown,
39
50
  ) => Promise<void | (() => Promise<void>)>;
51
+ dispose?: () => Promise<void> | void;
52
+ /**
53
+ * Declarative auto-enable conditions consumed by the runtime's
54
+ * plugin-auto-enable engine. Mirrors the shape on `@elizaos/core` Plugin.
55
+ */
56
+ autoEnable?: {
57
+ envKeys?: string[];
58
+ connectorKeys?: string[];
59
+ shouldEnable?: (
60
+ env: Record<string, string | undefined>,
61
+ config: Record<string, unknown>,
62
+ ) => boolean;
63
+ };
40
64
  }
41
65
 
42
66
  let channel: WechatChannel | null = null;
43
67
 
68
+ type RuntimeWithWechatConnector = {
69
+ registerMessageConnector?: (registration: Record<string, unknown>) => void;
70
+ getMessageConnectors?: () => Array<{
71
+ source?: string;
72
+ fetchMessages?: (
73
+ context: { runtime: IAgentRuntime; target?: TargetInfo },
74
+ params?: WechatConnectorReadParams,
75
+ ) => Promise<Memory[]>;
76
+ }>;
77
+ registerSendHandler?: (
78
+ source: string,
79
+ handler: (
80
+ runtime: IAgentRuntime,
81
+ target: TargetInfo,
82
+ content: Content,
83
+ ) => Promise<void>,
84
+ ) => void;
85
+ };
86
+
87
+ type WechatConnectorReadParams = {
88
+ target?: TargetInfo;
89
+ limit?: number;
90
+ query?: string;
91
+ };
92
+
93
+ function readRuntimeSetting(runtime: unknown, key: string): string | undefined {
94
+ const value = (
95
+ runtime as { getSetting?: (setting: string) => unknown }
96
+ ).getSetting?.(key);
97
+ return typeof value === "string" && value.trim() ? value.trim() : undefined;
98
+ }
99
+
100
+ function resolveWechatConfig(
101
+ config: Record<string, unknown>,
102
+ runtime: unknown,
103
+ ): WechatConfig | undefined {
104
+ const explicit = (config as { connectors?: { wechat?: WechatConfig } })
105
+ ?.connectors?.wechat;
106
+ if (explicit) return explicit;
107
+ const apiKey = readRuntimeSetting(runtime, "WECHAT_API_KEY");
108
+ const proxyUrl = readRuntimeSetting(runtime, "WECHAT_PROXY_URL");
109
+ if (!apiKey && !proxyUrl) return undefined;
110
+ return {
111
+ apiKey,
112
+ proxyUrl,
113
+ };
114
+ }
115
+
116
+ function normalizeConnectorLimit(
117
+ limit: number | undefined,
118
+ fallback = 50,
119
+ ): number {
120
+ if (!Number.isFinite(limit) || !limit || limit <= 0) {
121
+ return fallback;
122
+ }
123
+ return Math.min(Math.floor(limit), 200);
124
+ }
125
+
126
+ function getConfiguredAccountIds(config: WechatConfig): string[] {
127
+ if (config.accounts && typeof config.accounts === "object") {
128
+ return Object.entries(config.accounts)
129
+ .filter(
130
+ ([, account]) => account.enabled !== false && Boolean(account.apiKey),
131
+ )
132
+ .map(([id]) => id);
133
+ }
134
+ return config.apiKey ? ["default"] : [];
135
+ }
136
+
137
+ function resolveWechatAccountId(
138
+ config: WechatConfig,
139
+ target?: TargetInfo,
140
+ ): string {
141
+ const metadata = (
142
+ target as (TargetInfo & { metadata?: Record<string, unknown> }) | undefined
143
+ )?.metadata;
144
+ const accountId =
145
+ typeof metadata?.accountId === "string" && metadata.accountId.trim()
146
+ ? metadata.accountId.trim()
147
+ : undefined;
148
+ if (accountId) {
149
+ return accountId;
150
+ }
151
+ return (
152
+ channel?.getAccountIds()[0] ??
153
+ getConfiguredAccountIds(config)[0] ??
154
+ "default"
155
+ );
156
+ }
157
+
158
+ function wechatTarget(
159
+ accountId: string,
160
+ wxid: string,
161
+ name: string | undefined,
162
+ kind: "user" | "group",
163
+ score = 0.55,
164
+ ): MessageConnectorTarget {
165
+ return {
166
+ target: {
167
+ source: "wechat",
168
+ channelId: wxid,
169
+ roomId: stringToUuid(`wechat:room:${accountId}:${wxid}`) as UUID,
170
+ metadata: { accountId },
171
+ } as TargetInfo,
172
+ label: name || wxid,
173
+ kind,
174
+ score,
175
+ contexts: ["social", "connectors"],
176
+ metadata: { accountId, wxid },
177
+ };
178
+ }
179
+
180
+ async function listWechatTargets(
181
+ config: WechatConfig,
182
+ ): Promise<MessageConnectorTarget[]> {
183
+ if (!channel) {
184
+ return [];
185
+ }
186
+ const targets: MessageConnectorTarget[] = [];
187
+ for (const accountId of channel.getAccountIds()) {
188
+ const contacts = await channel.listContacts(accountId).catch(() => null);
189
+ if (!contacts) {
190
+ continue;
191
+ }
192
+ targets.push(
193
+ ...contacts.friends.map((friend) =>
194
+ wechatTarget(accountId, friend.wxid, friend.name, "user"),
195
+ ),
196
+ ...contacts.chatrooms.map((chatroom) =>
197
+ wechatTarget(accountId, chatroom.wxid, chatroom.name, "group"),
198
+ ),
199
+ );
200
+ }
201
+ if (targets.length > 0) {
202
+ return targets;
203
+ }
204
+ return getConfiguredAccountIds(config).map((accountId) =>
205
+ wechatTarget(
206
+ accountId,
207
+ accountId,
208
+ `WeChat account ${accountId}`,
209
+ "user",
210
+ 0.25,
211
+ ),
212
+ );
213
+ }
214
+
215
+ function filterMemoriesByQuery(
216
+ memories: Memory[],
217
+ query: string,
218
+ limit: number,
219
+ ): Memory[] {
220
+ const normalized = query.trim().toLowerCase();
221
+ if (!normalized) {
222
+ return memories.slice(0, limit);
223
+ }
224
+ return memories
225
+ .filter((memory) => {
226
+ const text =
227
+ typeof memory.content?.text === "string" ? memory.content.text : "";
228
+ return text.toLowerCase().includes(normalized);
229
+ })
230
+ .slice(0, limit);
231
+ }
232
+
233
+ function registerWechatMessageConnector(
234
+ runtime: unknown,
235
+ config: WechatConfig,
236
+ ): void {
237
+ const connectorRuntime = runtime as RuntimeWithWechatConnector;
238
+ const sendHandler = async (
239
+ _runtime: IAgentRuntime,
240
+ target: TargetInfo,
241
+ content: Content,
242
+ ): Promise<void> => {
243
+ if (!channel) {
244
+ throw new Error("[wechat] Channel is not available");
245
+ }
246
+ const text = typeof content.text === "string" ? content.text.trim() : "";
247
+ if (!text) {
248
+ return;
249
+ }
250
+ const accountId = resolveWechatAccountId(config, target);
251
+ const to = String(target.channelId ?? target.entityId ?? "").trim();
252
+ if (!to) {
253
+ throw new Error("[wechat] target is missing channelId/entityId");
254
+ }
255
+ await channel.sendText(accountId, to, text);
256
+ };
257
+
258
+ if (typeof connectorRuntime.registerMessageConnector === "function") {
259
+ connectorRuntime.registerMessageConnector({
260
+ source: "wechat",
261
+ label: "WeChat",
262
+ description:
263
+ "WeChat connector for sending and reading stored DM/group messages.",
264
+ capabilities: [
265
+ "send_message",
266
+ "resolve_targets",
267
+ "list_rooms",
268
+ "chat_context",
269
+ ],
270
+ supportedTargetKinds: ["user", "group", "room"],
271
+ contexts: ["social", "connectors"],
272
+ resolveTargets: async (query: string) => {
273
+ const normalized = query.trim().toLowerCase();
274
+ return (await listWechatTargets(config))
275
+ .map((target) => {
276
+ const haystack =
277
+ `${target.label ?? ""} ${target.target.channelId ?? ""}`.toLowerCase();
278
+ return {
279
+ ...target,
280
+ score:
281
+ normalized && haystack.includes(normalized)
282
+ ? 0.8
283
+ : (target.score ?? 0.4),
284
+ };
285
+ })
286
+ .filter((target) => !normalized || (target.score ?? 0) >= 0.8)
287
+ .slice(0, 25);
288
+ },
289
+ listRecentTargets: async () =>
290
+ (await listWechatTargets(config)).slice(0, 10),
291
+ listRooms: async () => listWechatTargets(config),
292
+ fetchMessages: async (
293
+ context: { runtime: IAgentRuntime; target?: TargetInfo },
294
+ params?: WechatConnectorReadParams,
295
+ ) => {
296
+ const limit = normalizeConnectorLimit(params?.limit);
297
+ const target = params?.target ?? context.target;
298
+ if (target?.roomId) {
299
+ return context.runtime.getMemories({
300
+ tableName: "messages",
301
+ roomId: target.roomId,
302
+ limit,
303
+ orderBy: "createdAt",
304
+ orderDirection: "desc",
305
+ });
306
+ }
307
+ const targets = (await listWechatTargets(config)).slice(0, 10);
308
+ const chunks = await Promise.all(
309
+ targets
310
+ .map((candidate) => candidate.target.roomId)
311
+ .filter((roomId): roomId is UUID => Boolean(roomId))
312
+ .map((roomId) =>
313
+ context.runtime.getMemories({
314
+ tableName: "messages",
315
+ roomId,
316
+ limit,
317
+ orderBy: "createdAt",
318
+ orderDirection: "desc",
319
+ }),
320
+ ),
321
+ );
322
+ return chunks
323
+ .flat()
324
+ .sort((left, right) => (right.createdAt ?? 0) - (left.createdAt ?? 0))
325
+ .slice(0, limit);
326
+ },
327
+ searchMessages: async (
328
+ context: { runtime: IAgentRuntime; target?: TargetInfo },
329
+ params: WechatConnectorReadParams & { query: string },
330
+ ) => {
331
+ const limit = normalizeConnectorLimit(params.limit);
332
+ const registration = connectorRuntime
333
+ .getMessageConnectors?.()
334
+ .find((connector) => connector.source === "wechat") as
335
+ | {
336
+ fetchMessages?: (
337
+ context: { runtime: IAgentRuntime; target?: TargetInfo },
338
+ params?: WechatConnectorReadParams,
339
+ ) => Promise<Memory[]>;
340
+ }
341
+ | undefined;
342
+ const messages =
343
+ (await registration?.fetchMessages?.(context, {
344
+ target: params.target ?? context.target,
345
+ limit: Math.max(limit, 100),
346
+ })) ?? [];
347
+ return filterMemoriesByQuery(messages, params.query, limit);
348
+ },
349
+ sendHandler,
350
+ });
351
+ return;
352
+ }
353
+
354
+ connectorRuntime.registerSendHandler?.("wechat", sendHandler);
355
+ }
356
+
44
357
  const wechatPlugin: Plugin = {
45
358
  name: "wechat",
46
359
  description: "WeChat messaging via proxy API",
47
360
 
361
+ // Self-declared auto-enable: activate when the "wechat" connector is
362
+ // configured under config.connectors. The hardcoded CONNECTOR_PLUGINS map
363
+ // in plugin-auto-enable-engine.ts still serves as a fallback.
364
+ autoEnable: {
365
+ connectorKeys: ["wechat"],
366
+ },
367
+
48
368
  async init(config: Record<string, unknown>, runtime: unknown) {
49
- const wechatConfig = (config as { connectors?: { wechat?: WechatConfig } })
50
- ?.connectors?.wechat;
369
+ try {
370
+ const manager = getConnectorAccountManager(runtime as IAgentRuntime);
371
+ manager.registerProvider(
372
+ createWechatConnectorAccountProvider(runtime as IAgentRuntime),
373
+ );
374
+ } catch (err) {
375
+ console.warn(
376
+ "[wechat] Failed to register provider with ConnectorAccountManager:",
377
+ err instanceof Error ? err.message : String(err),
378
+ );
379
+ }
380
+
381
+ const wechatConfig = resolveWechatConfig(config, runtime);
51
382
 
52
383
  if (!wechatConfig) {
53
384
  console.warn("[wechat] No wechat config found in connectors — skipping");
@@ -77,6 +408,7 @@ const wechatPlugin: Plugin = {
77
408
  });
78
409
 
79
410
  await channel.start();
411
+ registerWechatMessageConnector(runtime, wechatConfig);
80
412
  console.log("[wechat] Plugin initialized");
81
413
 
82
414
  // Return cleanup function
@@ -88,6 +420,13 @@ const wechatPlugin: Plugin = {
88
420
  }
89
421
  };
90
422
  },
423
+ async dispose() {
424
+ if (channel) {
425
+ await channel.stop();
426
+ channel = null;
427
+ console.log("[wechat] Plugin disposed");
428
+ }
429
+ },
91
430
  };
92
431
 
93
432
  export default wechatPlugin;
package/src/types.ts CHANGED
@@ -1,7 +1,7 @@
1
- export type DeviceType = "ipad" | "mac";
2
- export type LoginStatus = "waiting" | "need_verify" | "logged_in";
1
+ type DeviceType = "ipad" | "mac";
2
+ type LoginStatus = "waiting" | "need_verify" | "logged_in";
3
3
 
4
- export interface WechatAccountConfig {
4
+ interface WechatAccountConfig {
5
5
  enabled?: boolean;
6
6
  name?: string;
7
7
  apiKey: string;
package/dist/bot.d.ts DELETED
@@ -1,25 +0,0 @@
1
- import { WechatMessageContext } from "./types.js";
2
-
3
- //#region src/bot.d.ts
4
- interface BotOptions {
5
- onMessage: (msg: WechatMessageContext) => void | Promise<void>;
6
- featuresGroups?: boolean;
7
- featuresImages?: boolean;
8
- /** Deduplication window in milliseconds. Defaults to 30 minutes. */
9
- dedupWindowMs?: number;
10
- }
11
- declare class Bot {
12
- private readonly seen;
13
- private readonly onMessage;
14
- private readonly featuresGroups;
15
- private readonly featuresImages;
16
- private readonly dedupWindowMs;
17
- private cleanupTimer;
18
- constructor(options: BotOptions);
19
- handleIncoming(message: WechatMessageContext): void;
20
- private isDuplicate;
21
- private cleanup;
22
- stop(): void;
23
- }
24
- //#endregion
25
- export { Bot };
package/dist/bot.js DELETED
@@ -1,49 +0,0 @@
1
- //#region src/bot.ts
2
- const DEFAULT_DEDUP_WINDOW_MS = 1800 * 1e3;
3
- const DEDUP_MAX_ENTRIES = 1e3;
4
- const DEDUP_CLEANUP_INTERVAL_MS = 300 * 1e3;
5
- var Bot = class {
6
- seen = /* @__PURE__ */ new Map();
7
- onMessage;
8
- featuresGroups;
9
- featuresImages;
10
- dedupWindowMs;
11
- cleanupTimer = null;
12
- constructor(options) {
13
- this.onMessage = options.onMessage;
14
- this.featuresGroups = options.featuresGroups ?? true;
15
- this.featuresImages = options.featuresImages ?? true;
16
- this.dedupWindowMs = options.dedupWindowMs ?? DEFAULT_DEDUP_WINDOW_MS;
17
- this.cleanupTimer = setInterval(() => this.cleanup(), DEDUP_CLEANUP_INTERVAL_MS);
18
- }
19
- handleIncoming(message) {
20
- if (this.isDuplicate(message.id)) return;
21
- if (message.group && !this.featuresGroups) return;
22
- if (message.type === "image" && !this.featuresImages) return;
23
- if (message.type === "unknown") return;
24
- Promise.resolve(this.onMessage(message)).catch((error) => {
25
- console.error("[wechat] Failed to process inbound message:", error);
26
- });
27
- }
28
- isDuplicate(messageId) {
29
- const now = Date.now();
30
- if (this.seen.has(messageId)) return true;
31
- if (this.seen.size >= DEDUP_MAX_ENTRIES) this.cleanup();
32
- this.seen.set(messageId, now);
33
- return false;
34
- }
35
- cleanup() {
36
- const cutoff = Date.now() - this.dedupWindowMs;
37
- for (const [id, ts] of this.seen) if (ts < cutoff) this.seen.delete(id);
38
- }
39
- stop() {
40
- if (this.cleanupTimer) {
41
- clearInterval(this.cleanupTimer);
42
- this.cleanupTimer = null;
43
- }
44
- this.seen.clear();
45
- }
46
- };
47
-
48
- //#endregion
49
- export { Bot };
@@ -1,207 +0,0 @@
1
- import { timingSafeEqual } from "node:crypto";
2
- import { createServer } from "node:http";
3
-
4
- //#region src/callback-server.ts
5
- const WECHAT_TYPE_MAP = {
6
- 60001: {
7
- type: "text",
8
- scope: "private"
9
- },
10
- 60002: {
11
- type: "image",
12
- scope: "private"
13
- },
14
- 60003: {
15
- type: "voice",
16
- scope: "private"
17
- },
18
- 60004: {
19
- type: "video",
20
- scope: "private"
21
- },
22
- 60005: {
23
- type: "file",
24
- scope: "private"
25
- },
26
- 80001: {
27
- type: "text",
28
- scope: "group"
29
- },
30
- 80002: {
31
- type: "image",
32
- scope: "group"
33
- },
34
- 80003: {
35
- type: "voice",
36
- scope: "group"
37
- },
38
- 80004: {
39
- type: "video",
40
- scope: "group"
41
- },
42
- 80005: {
43
- type: "file",
44
- scope: "group"
45
- }
46
- };
47
- const DEFAULT_MAX_REQUEST_BODY_BYTES = 1024 * 1024;
48
- async function startCallbackServer(options) {
49
- const { port, accounts, onMessage, signal, maxBodyBytes = DEFAULT_MAX_REQUEST_BODY_BYTES } = options;
50
- const server = createServer((req, res) => {
51
- const account = resolveWebhookAccount(req.url, accounts);
52
- if (req.method !== "POST" || !account) {
53
- res.writeHead(404);
54
- res.end("Not Found");
55
- return;
56
- }
57
- const incomingKey = readHeaderValue(req.headers["x-api-key"]);
58
- if (!incomingKey || !safeCompare(incomingKey, account.apiKey)) {
59
- res.writeHead(401);
60
- res.end("Unauthorized");
61
- return;
62
- }
63
- let body = "";
64
- let bodyBytes = 0;
65
- req.on("data", (chunk) => {
66
- bodyBytes += chunk.length;
67
- if (bodyBytes > maxBodyBytes) {
68
- res.writeHead(413);
69
- res.end("Payload Too Large");
70
- req.destroy();
71
- return;
72
- }
73
- body += chunk.toString();
74
- });
75
- req.on("end", () => {
76
- if (res.writableEnded) return;
77
- try {
78
- const message = normalizePayload(JSON.parse(body));
79
- if (message) onMessage(account.accountId, message);
80
- res.writeHead(200);
81
- res.end("OK");
82
- } catch {
83
- res.writeHead(400);
84
- res.end("Bad Request");
85
- }
86
- });
87
- req.on("error", () => {
88
- if (res.writableEnded) return;
89
- res.writeHead(400);
90
- res.end("Bad Request");
91
- });
92
- });
93
- await new Promise((resolve, reject) => {
94
- const handleListening = () => {
95
- server.off("error", handleError);
96
- resolve();
97
- };
98
- const handleError = (error) => {
99
- server.off("listening", handleListening);
100
- reject(error);
101
- };
102
- server.once("listening", handleListening);
103
- server.once("error", handleError);
104
- server.listen(port);
105
- });
106
- const listeningPort = server.address()?.port ?? port;
107
- console.log(`[wechat] Webhook server listening on port ${listeningPort}`);
108
- server.on("error", (err) => {
109
- if (err.code === "EADDRINUSE") console.error(`[wechat] Port ${listeningPort} already in use — webhook server failed to start`);
110
- else console.error(`[wechat] Webhook server error:`, err);
111
- });
112
- if (signal) signal.addEventListener("abort", () => {
113
- closeServer(server);
114
- }, { once: true });
115
- return {
116
- close: () => closeServer(server),
117
- port: listeningPort
118
- };
119
- }
120
- function resolveWebhookAccount(rawUrl, accounts) {
121
- if (!rawUrl) return null;
122
- const pathname = new URL(rawUrl, "http://localhost").pathname;
123
- if (pathname === "/webhook/wechat" && accounts.length === 1) return accounts[0];
124
- const match = /^\/webhook\/wechat\/([^/]+)$/.exec(pathname);
125
- if (!match) return null;
126
- const accountId = decodeURIComponent(match[1]);
127
- return accounts.find((account) => account.accountId === accountId) ?? null;
128
- }
129
- function readHeaderValue(value) {
130
- if (Array.isArray(value)) return value[0];
131
- return value;
132
- }
133
- function safeCompare(a, b) {
134
- const bufA = Buffer.from(a);
135
- const bufB = Buffer.from(b);
136
- if (bufA.length !== bufB.length) {
137
- timingSafeEqual(bufA, bufA);
138
- return false;
139
- }
140
- return timingSafeEqual(bufA, bufB);
141
- }
142
- function closeServer(server) {
143
- if (!server.listening) return Promise.resolve();
144
- return new Promise((resolve, reject) => {
145
- server.close((error) => {
146
- if (error) {
147
- reject(error);
148
- return;
149
- }
150
- resolve();
151
- });
152
- });
153
- }
154
- function normalizePayload(payload) {
155
- const data = payload.data ?? (payload.content ? payload : null);
156
- if (!data) {
157
- console.warn("[wechat] Unrecognized webhook payload format");
158
- return null;
159
- }
160
- const typeCode = Number(data.type ?? data.msgType ?? 0);
161
- const mapping = WECHAT_TYPE_MAP[typeCode];
162
- let msgType = "unknown";
163
- let scope = "private";
164
- if (mapping) {
165
- msgType = mapping.type;
166
- scope = mapping.scope;
167
- } else if (typeCode >= 60006 && typeCode <= 60010) {
168
- msgType = "file";
169
- scope = "private";
170
- } else if (typeCode >= 80006 && typeCode <= 80010) {
171
- msgType = "file";
172
- scope = "group";
173
- }
174
- if (msgType === "unknown") {
175
- console.warn(`[wechat] Unknown message type code: ${typeCode}`);
176
- return null;
177
- }
178
- const sender = String(data.sender ?? data.from ?? "");
179
- const recipient = String(data.recipient ?? data.to ?? "");
180
- const content = String(data.content ?? data.text ?? "");
181
- const timestamp = Number(data.timestamp ?? Date.now());
182
- const msgId = String(data.msgId ?? data.id ?? `${sender}-${timestamp}`);
183
- const isGroup = scope === "group" || sender.includes("@chatroom");
184
- const threadId = isGroup ? String(data.roomId ?? data.threadId ?? sender) : void 0;
185
- const groupSubject = isGroup ? String(data.roomName ?? data.groupName ?? threadId ?? "") : void 0;
186
- const imageUrl = new Set([
187
- "image",
188
- "voice",
189
- "video",
190
- "file"
191
- ]).has(msgType) ? String(data.imageUrl ?? data.mediaUrl ?? data.url ?? data.fileUrl ?? "") : void 0;
192
- return {
193
- id: msgId,
194
- type: msgType,
195
- sender,
196
- recipient,
197
- content,
198
- timestamp,
199
- threadId,
200
- group: groupSubject ? { subject: groupSubject } : void 0,
201
- imageUrl: imageUrl || void 0,
202
- raw: payload
203
- };
204
- }
205
-
206
- //#endregion
207
- export { startCallbackServer };
package/dist/channel.d.ts DELETED
@@ -1,28 +0,0 @@
1
- import { WechatConfig, WechatMessageContext } from "./types.js";
2
-
3
- //#region src/channel.d.ts
4
- interface ChannelOptions {
5
- config: WechatConfig;
6
- onMessage: (accountId: string, msg: WechatMessageContext) => void | Promise<void>;
7
- }
8
- declare class WechatChannel {
9
- private readonly config;
10
- private readonly onMessage;
11
- private readonly accounts;
12
- private readonly callbackServers;
13
- private readonly loginPromises;
14
- private healthTimer;
15
- private abortController;
16
- constructor(options: ChannelOptions);
17
- start(): Promise<void>;
18
- stop(): Promise<void>;
19
- sendText(accountId: string, to: string, text: string): Promise<void>;
20
- sendImage(accountId: string, to: string, imagePath: string, caption?: string): Promise<void>;
21
- private routeIncoming;
22
- private ensureLoggedIn;
23
- private doLogin;
24
- private healthCheck;
25
- private resolveAccounts;
26
- }
27
- //#endregion
28
- export { WechatChannel };