@elizaos/plugin-wechat 2.0.3-beta.6 → 2.0.3-beta.7

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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/bot.ts","../src/callback-server.ts","../src/proxy-client.ts","../src/reply-dispatcher.ts","../src/utils/qrcode.ts","../src/channel.ts","../src/connector-account-provider.ts","../src/runtime-bridge.ts"],"sourcesContent":["import {\n type Content,\n getConnectorAccountManager,\n type IAgentRuntime,\n type Memory,\n type MessageConnectorTarget,\n stringToUuid,\n type TargetInfo,\n type UUID,\n} from \"@elizaos/core\";\nimport { WechatChannel } from \"./channel\";\nimport { createWechatConnectorAccountProvider } from \"./connector-account-provider\";\nimport { deliverIncomingWechatMessage } from \"./runtime-bridge\";\nimport type { WechatConfig, WechatMessageContext } from \"./types\";\n\nexport const WECHAT_PLUGIN_PACKAGE = \"@elizaos/plugin-wechat\" as const;\n\nexport function isWechatConnectorConfigured(\n config: WechatConfig | Record<string, unknown> | null | undefined,\n): boolean {\n if (!config || config.enabled === false) {\n return false;\n }\n\n if (config.apiKey) {\n return true;\n }\n\n const accounts = config.accounts;\n if (accounts && typeof accounts === \"object\") {\n return Object.values(\n accounts as Record<string, Record<string, unknown>>,\n ).some((account) => {\n if (account.enabled === false) {\n return false;\n }\n return Boolean(account.apiKey);\n });\n }\n\n return false;\n}\n\nexport interface Plugin {\n name: string;\n description: string;\n init?: (\n config: Record<string, unknown>,\n runtime: unknown,\n ) => Promise<void | (() => Promise<void>)>;\n dispose?: () => Promise<void> | void;\n /**\n * Declarative auto-enable conditions consumed by the runtime's\n * plugin-auto-enable engine. Mirrors the shape on `@elizaos/core` Plugin.\n */\n autoEnable?: {\n envKeys?: string[];\n connectorKeys?: string[];\n shouldEnable?: (\n env: Record<string, string | undefined>,\n config: Record<string, unknown>,\n ) => boolean;\n };\n}\n\nlet channel: WechatChannel | null = null;\n\ntype RuntimeWithWechatConnector = {\n registerMessageConnector?: (registration: Record<string, unknown>) => void;\n getMessageConnectors?: () => Array<{\n source?: string;\n fetchMessages?: (\n context: { runtime: IAgentRuntime; target?: TargetInfo },\n params?: WechatConnectorReadParams,\n ) => Promise<Memory[]>;\n }>;\n registerSendHandler?: (\n source: string,\n handler: (\n runtime: IAgentRuntime,\n target: TargetInfo,\n content: Content,\n ) => Promise<void>,\n ) => void;\n};\n\ntype WechatConnectorReadParams = {\n target?: TargetInfo;\n limit?: number;\n query?: string;\n};\n\nfunction readRuntimeSetting(runtime: unknown, key: string): string | undefined {\n const value = (\n runtime as { getSetting?: (setting: string) => unknown }\n ).getSetting?.(key);\n return typeof value === \"string\" && value.trim() ? value.trim() : undefined;\n}\n\nfunction resolveWechatConfig(\n config: Record<string, unknown>,\n runtime: unknown,\n): WechatConfig | undefined {\n const explicit = (config as { connectors?: { wechat?: WechatConfig } })\n ?.connectors?.wechat;\n if (explicit) return explicit;\n const apiKey = readRuntimeSetting(runtime, \"WECHAT_API_KEY\");\n const proxyUrl = readRuntimeSetting(runtime, \"WECHAT_PROXY_URL\");\n if (!apiKey && !proxyUrl) return undefined;\n return {\n apiKey,\n proxyUrl,\n };\n}\n\nfunction normalizeConnectorLimit(\n limit: number | undefined,\n fallback = 50,\n): number {\n if (!Number.isFinite(limit) || !limit || limit <= 0) {\n return fallback;\n }\n return Math.min(Math.floor(limit), 200);\n}\n\nfunction getConfiguredAccountIds(config: WechatConfig): string[] {\n if (config.accounts && typeof config.accounts === \"object\") {\n return Object.entries(config.accounts)\n .filter(\n ([, account]) => account.enabled !== false && Boolean(account.apiKey),\n )\n .map(([id]) => id);\n }\n return config.apiKey ? [\"default\"] : [];\n}\n\nfunction resolveWechatAccountId(\n config: WechatConfig,\n target?: TargetInfo,\n): string {\n const metadata = (\n target as (TargetInfo & { metadata?: Record<string, unknown> }) | undefined\n )?.metadata;\n const accountId =\n typeof metadata?.accountId === \"string\" && metadata.accountId.trim()\n ? metadata.accountId.trim()\n : undefined;\n if (accountId) {\n return accountId;\n }\n return (\n channel?.getAccountIds()[0] ??\n getConfiguredAccountIds(config)[0] ??\n \"default\"\n );\n}\n\nfunction wechatTarget(\n accountId: string,\n wxid: string,\n name: string | undefined,\n kind: \"user\" | \"group\",\n score = 0.55,\n): MessageConnectorTarget {\n return {\n target: {\n source: \"wechat\",\n channelId: wxid,\n roomId: stringToUuid(`wechat:room:${accountId}:${wxid}`) as UUID,\n metadata: { accountId },\n } as TargetInfo,\n label: name || wxid,\n kind,\n score,\n contexts: [\"social\", \"connectors\"],\n metadata: { accountId, wxid },\n };\n}\n\nasync function listWechatTargets(\n config: WechatConfig,\n): Promise<MessageConnectorTarget[]> {\n if (!channel) {\n return [];\n }\n const targets: MessageConnectorTarget[] = [];\n for (const accountId of channel.getAccountIds()) {\n const contacts = await channel.listContacts(accountId).catch(() => null);\n if (!contacts) {\n continue;\n }\n targets.push(\n ...contacts.friends.map((friend) =>\n wechatTarget(accountId, friend.wxid, friend.name, \"user\"),\n ),\n ...contacts.chatrooms.map((chatroom) =>\n wechatTarget(accountId, chatroom.wxid, chatroom.name, \"group\"),\n ),\n );\n }\n if (targets.length > 0) {\n return targets;\n }\n return getConfiguredAccountIds(config).map((accountId) =>\n wechatTarget(\n accountId,\n accountId,\n `WeChat account ${accountId}`,\n \"user\",\n 0.25,\n ),\n );\n}\n\nfunction filterMemoriesByQuery(\n memories: Memory[],\n query: string,\n limit: number,\n): Memory[] {\n const normalized = query.trim().toLowerCase();\n if (!normalized) {\n return memories.slice(0, limit);\n }\n return memories\n .filter((memory) => {\n const text =\n typeof memory.content?.text === \"string\" ? memory.content.text : \"\";\n return text.toLowerCase().includes(normalized);\n })\n .slice(0, limit);\n}\n\nfunction registerWechatMessageConnector(\n runtime: unknown,\n config: WechatConfig,\n): void {\n const connectorRuntime = runtime as RuntimeWithWechatConnector;\n const sendHandler = async (\n _runtime: IAgentRuntime,\n target: TargetInfo,\n content: Content,\n ): Promise<void> => {\n if (!channel) {\n throw new Error(\"[wechat] Channel is not available\");\n }\n const text = typeof content.text === \"string\" ? content.text.trim() : \"\";\n if (!text) {\n return;\n }\n const accountId = resolveWechatAccountId(config, target);\n const to = String(target.channelId ?? target.entityId ?? \"\").trim();\n if (!to) {\n throw new Error(\"[wechat] target is missing channelId/entityId\");\n }\n await channel.sendText(accountId, to, text);\n };\n\n if (typeof connectorRuntime.registerMessageConnector === \"function\") {\n connectorRuntime.registerMessageConnector({\n source: \"wechat\",\n label: \"WeChat\",\n description:\n \"WeChat connector for sending and reading stored DM/group messages.\",\n capabilities: [\n \"send_message\",\n \"resolve_targets\",\n \"list_rooms\",\n \"chat_context\",\n ],\n supportedTargetKinds: [\"user\", \"group\", \"room\"],\n contexts: [\"social\", \"connectors\"],\n resolveTargets: async (query: string) => {\n const normalized = query.trim().toLowerCase();\n return (await listWechatTargets(config))\n .map((target) => {\n const haystack =\n `${target.label ?? \"\"} ${target.target.channelId ?? \"\"}`.toLowerCase();\n return {\n ...target,\n score:\n normalized && haystack.includes(normalized)\n ? 0.8\n : (target.score ?? 0.4),\n };\n })\n .filter((target) => !normalized || (target.score ?? 0) >= 0.8)\n .slice(0, 25);\n },\n listRecentTargets: async () =>\n (await listWechatTargets(config)).slice(0, 10),\n listRooms: async () => listWechatTargets(config),\n fetchMessages: async (\n context: { runtime: IAgentRuntime; target?: TargetInfo },\n params?: WechatConnectorReadParams,\n ) => {\n const limit = normalizeConnectorLimit(params?.limit);\n const target = params?.target ?? context.target;\n if (target?.roomId) {\n return context.runtime.getMemories({\n tableName: \"messages\",\n roomId: target.roomId,\n limit,\n orderBy: \"createdAt\",\n orderDirection: \"desc\",\n });\n }\n const targets = (await listWechatTargets(config)).slice(0, 10);\n const chunks = await Promise.all(\n targets\n .map((candidate) => candidate.target.roomId)\n .filter((roomId): roomId is UUID => Boolean(roomId))\n .map((roomId) =>\n context.runtime.getMemories({\n tableName: \"messages\",\n roomId,\n limit,\n orderBy: \"createdAt\",\n orderDirection: \"desc\",\n }),\n ),\n );\n return chunks\n .flat()\n .sort((left, right) => (right.createdAt ?? 0) - (left.createdAt ?? 0))\n .slice(0, limit);\n },\n searchMessages: async (\n context: { runtime: IAgentRuntime; target?: TargetInfo },\n params: WechatConnectorReadParams & { query: string },\n ) => {\n const limit = normalizeConnectorLimit(params.limit);\n const registration = connectorRuntime\n .getMessageConnectors?.()\n .find((connector) => connector.source === \"wechat\") as\n | {\n fetchMessages?: (\n context: { runtime: IAgentRuntime; target?: TargetInfo },\n params?: WechatConnectorReadParams,\n ) => Promise<Memory[]>;\n }\n | undefined;\n const messages =\n (await registration?.fetchMessages?.(context, {\n target: params.target ?? context.target,\n limit: Math.max(limit, 100),\n })) ?? [];\n return filterMemoriesByQuery(messages, params.query, limit);\n },\n sendHandler,\n });\n return;\n }\n\n connectorRuntime.registerSendHandler?.(\"wechat\", sendHandler);\n}\n\nconst wechatPlugin: Plugin = {\n name: \"wechat\",\n description: \"WeChat messaging via proxy API\",\n\n // Self-declared auto-enable: activate when the \"wechat\" connector is\n // configured under config.connectors. The hardcoded CONNECTOR_PLUGINS map\n // in plugin-auto-enable-engine.ts still serves as a fallback.\n autoEnable: {\n connectorKeys: [\"wechat\"],\n },\n\n async init(config: Record<string, unknown>, runtime: unknown) {\n try {\n const manager = getConnectorAccountManager(runtime as IAgentRuntime);\n manager.registerProvider(\n createWechatConnectorAccountProvider(runtime as IAgentRuntime),\n );\n } catch (err) {\n console.warn(\n \"[wechat] Failed to register provider with ConnectorAccountManager:\",\n err instanceof Error ? err.message : String(err),\n );\n }\n\n const wechatConfig = resolveWechatConfig(config, runtime);\n\n if (!wechatConfig) {\n console.warn(\"[wechat] No wechat config found in connectors — skipping\");\n return;\n }\n\n if (wechatConfig.enabled === false) {\n console.log(\"[wechat] Plugin disabled via config\");\n return;\n }\n\n channel = new WechatChannel({\n config: wechatConfig,\n onMessage: async (accountId: string, msg: WechatMessageContext) => {\n await deliverIncomingWechatMessage({\n runtime,\n accountId,\n message: msg,\n sendText: async (replyAccountId, to, text) => {\n if (!channel) {\n throw new Error(\"[wechat] Channel is not available for replies\");\n }\n await channel.sendText(replyAccountId, to, text);\n },\n });\n },\n });\n\n await channel.start();\n registerWechatMessageConnector(runtime, wechatConfig);\n console.log(\"[wechat] Plugin initialized\");\n\n // Return cleanup function\n return async () => {\n if (channel) {\n await channel.stop();\n channel = null;\n console.log(\"[wechat] Plugin stopped\");\n }\n };\n },\n async dispose() {\n if (channel) {\n await channel.stop();\n channel = null;\n console.log(\"[wechat] Plugin disposed\");\n }\n },\n};\n\nexport default wechatPlugin;\nexport { Bot } from \"./bot\";\nexport { WechatChannel } from \"./channel\";\nexport { ProxyClient } from \"./proxy-client\";\nexport { ReplyDispatcher } from \"./reply-dispatcher\";\nexport { deliverIncomingWechatMessage } from \"./runtime-bridge\";\nexport type { WechatConfig, WechatMessageContext } from \"./types\";\nexport { wechatPlugin };\n","import type { WechatMessageContext } from \"./types\";\n\nconst DEFAULT_DEDUP_WINDOW_MS = 30 * 60 * 1000; // 30 minutes\nconst DEDUP_MAX_ENTRIES = 1000;\nconst DEDUP_CLEANUP_INTERVAL_MS = 5 * 60 * 1000; // 5 minutes\n\nexport interface BotOptions {\n onMessage: (msg: WechatMessageContext) => void | Promise<void>;\n featuresGroups?: boolean;\n featuresImages?: boolean;\n /** Deduplication window in milliseconds. Defaults to 30 minutes. */\n dedupWindowMs?: number;\n}\n\nexport class Bot {\n private readonly seen = new Map<string, number>();\n private readonly onMessage: (\n msg: WechatMessageContext,\n ) => void | Promise<void>;\n private readonly featuresGroups: boolean;\n private readonly featuresImages: boolean;\n private readonly dedupWindowMs: number;\n private cleanupTimer: ReturnType<typeof setInterval> | null = null;\n\n constructor(options: BotOptions) {\n this.onMessage = options.onMessage;\n this.featuresGroups = options.featuresGroups ?? true;\n this.featuresImages = options.featuresImages ?? true;\n this.dedupWindowMs = options.dedupWindowMs ?? DEFAULT_DEDUP_WINDOW_MS;\n\n this.cleanupTimer = setInterval(\n () => this.cleanup(),\n DEDUP_CLEANUP_INTERVAL_MS,\n );\n }\n\n handleIncoming(message: WechatMessageContext): void {\n // Deduplication\n if (this.isDuplicate(message.id)) {\n return;\n }\n\n // Feature gate: groups\n if (message.group && !this.featuresGroups) {\n return;\n }\n\n // Feature gate: images\n if (message.type === \"image\" && !this.featuresImages) {\n return;\n }\n\n // Skip unsupported types\n if (message.type === \"unknown\") {\n return;\n }\n\n void Promise.resolve(this.onMessage(message)).catch((error: unknown) => {\n console.error(\"[wechat] Failed to process inbound message:\", error);\n });\n }\n\n private isDuplicate(messageId: string): boolean {\n const now = Date.now();\n\n if (this.seen.has(messageId)) {\n return true;\n }\n\n // Evict if at capacity\n if (this.seen.size >= DEDUP_MAX_ENTRIES) {\n this.cleanup();\n }\n\n this.seen.set(messageId, now);\n return false;\n }\n\n private cleanup(): void {\n const cutoff = Date.now() - this.dedupWindowMs;\n for (const [id, ts] of this.seen) {\n if (ts < cutoff) {\n this.seen.delete(id);\n }\n }\n }\n\n stop(): void {\n if (this.cleanupTimer) {\n clearInterval(this.cleanupTimer);\n this.cleanupTimer = null;\n }\n this.seen.clear();\n }\n}\n","import { timingSafeEqual } from \"node:crypto\";\nimport {\n createServer,\n type IncomingMessage,\n type ServerResponse,\n} from \"node:http\";\nimport type { AddressInfo } from \"node:net\";\nimport type { WechatMessageContext, WechatMessageType } from \"./types\";\n\nconst WECHAT_TYPE_MAP: Record<\n number,\n { type: WechatMessageType; scope: \"private\" | \"group\" }\n> = {\n // Private message types\n 60001: { type: \"text\", scope: \"private\" },\n 60002: { type: \"image\", scope: \"private\" },\n 60003: { type: \"voice\", scope: \"private\" },\n 60004: { type: \"video\", scope: \"private\" },\n 60005: { type: \"file\", scope: \"private\" },\n // Group message types\n 80001: { type: \"text\", scope: \"group\" },\n 80002: { type: \"image\", scope: \"group\" },\n 80003: { type: \"voice\", scope: \"group\" },\n 80004: { type: \"video\", scope: \"group\" },\n 80005: { type: \"file\", scope: \"group\" },\n};\n\nconst DEFAULT_MAX_REQUEST_BODY_BYTES = 1024 * 1024;\n\nexport interface CallbackServerOptions {\n port: number;\n accounts: Array<{ accountId: string; apiKey: string }>;\n onMessage: (accountId: string, msg: WechatMessageContext) => void;\n signal?: AbortSignal;\n maxBodyBytes?: number;\n}\n\nexport async function startCallbackServer(\n options: CallbackServerOptions,\n): Promise<{\n close: () => Promise<void>;\n port: number;\n}> {\n const {\n port,\n accounts,\n onMessage,\n signal,\n maxBodyBytes = DEFAULT_MAX_REQUEST_BODY_BYTES,\n } = options;\n\n const server = createServer((req: IncomingMessage, res: ServerResponse) => {\n const account = resolveWebhookAccount(req.url, accounts);\n if (req.method !== \"POST\" || !account) {\n res.writeHead(404);\n res.end(\"Not Found\");\n return;\n }\n\n const incomingKey = readHeaderValue(req.headers[\"x-api-key\"]);\n if (!incomingKey || !safeCompare(incomingKey, account.apiKey)) {\n res.writeHead(401);\n res.end(\"Unauthorized\");\n return;\n }\n\n let body = \"\";\n let bodyBytes = 0;\n req.on(\"data\", (chunk: Buffer) => {\n bodyBytes += chunk.length;\n if (bodyBytes > maxBodyBytes) {\n res.writeHead(413);\n res.end(\"Payload Too Large\");\n req.destroy();\n return;\n }\n body += chunk.toString();\n });\n\n req.on(\"end\", () => {\n if (res.writableEnded) {\n return;\n }\n\n try {\n const payload = JSON.parse(body) as Record<string, unknown>;\n const message = normalizePayload(payload);\n if (message) {\n onMessage(account.accountId, message);\n }\n res.writeHead(200);\n res.end(\"OK\");\n } catch {\n res.writeHead(400);\n res.end(\"Bad Request\");\n }\n });\n\n req.on(\"error\", () => {\n if (res.writableEnded) {\n return;\n }\n\n res.writeHead(400);\n res.end(\"Bad Request\");\n });\n });\n\n await new Promise<void>((resolve, reject) => {\n const handleListening = () => {\n server.off(\"error\", handleError);\n resolve();\n };\n const handleError = (error: Error) => {\n server.off(\"listening\", handleListening);\n reject(error);\n };\n\n server.once(\"listening\", handleListening);\n server.once(\"error\", handleError);\n server.listen(port);\n });\n\n const address = server.address() as AddressInfo | null;\n const listeningPort = address?.port ?? port;\n console.log(`[wechat] Webhook server listening on port ${listeningPort}`);\n\n server.on(\"error\", (err: Error) => {\n if ((err as NodeJS.ErrnoException).code === \"EADDRINUSE\") {\n console.error(\n `[wechat] Port ${listeningPort} already in use — webhook server failed to start`,\n );\n } else {\n console.error(`[wechat] Webhook server error:`, err);\n }\n });\n\n if (signal) {\n signal.addEventListener(\n \"abort\",\n () => {\n void closeServer(server);\n },\n { once: true },\n );\n }\n\n return {\n close: () => closeServer(server),\n port: listeningPort,\n };\n}\n\nfunction resolveWebhookAccount(\n rawUrl: string | undefined,\n accounts: Array<{ accountId: string; apiKey: string }>,\n) {\n if (!rawUrl) {\n return null;\n }\n\n const pathname = new URL(rawUrl, \"http://localhost\").pathname;\n if (pathname === \"/webhook/wechat\" && accounts.length === 1) {\n return accounts[0];\n }\n\n const match = /^\\/webhook\\/wechat\\/([^/]+)$/.exec(pathname);\n if (!match) {\n return null;\n }\n\n const accountId = decodeURIComponent(match[1]);\n return accounts.find((account) => account.accountId === accountId) ?? null;\n}\n\nfunction readHeaderValue(\n value: string | string[] | undefined,\n): string | undefined {\n if (Array.isArray(value)) {\n return value[0];\n }\n return value;\n}\n\nfunction safeCompare(a: string, b: string): boolean {\n const bufA = Buffer.from(a);\n const bufB = Buffer.from(b);\n if (bufA.length !== bufB.length) {\n // Compare against itself to burn constant time, then return false\n timingSafeEqual(bufA, bufA);\n return false;\n }\n return timingSafeEqual(bufA, bufB);\n}\n\nfunction closeServer(server: ReturnType<typeof createServer>): Promise<void> {\n if (!server.listening) {\n return Promise.resolve();\n }\n\n return new Promise((resolve, reject) => {\n server.close((error) => {\n if (error) {\n reject(error);\n return;\n }\n resolve();\n });\n });\n}\n\nexport function normalizePayload(\n payload: Record<string, unknown>,\n): WechatMessageContext | null {\n // Support two payload formats: nested \"raw\" and flattened \"proxy\"\n const data =\n (payload.data as Record<string, unknown>) ??\n (payload.content ? payload : null);\n\n if (!data) {\n console.warn(\"[wechat] Unrecognized webhook payload format\");\n return null;\n }\n\n const typeCode = Number(data.type ?? data.msgType ?? 0);\n const mapping = WECHAT_TYPE_MAP[typeCode];\n\n let msgType: WechatMessageType = \"unknown\";\n let scope: \"private\" | \"group\" = \"private\";\n\n if (mapping) {\n msgType = mapping.type;\n scope = mapping.scope;\n } else if (typeCode >= 60006 && typeCode <= 60010) {\n // Unmapped private media — treat as file\n msgType = \"file\";\n scope = \"private\";\n } else if (typeCode >= 80006 && typeCode <= 80010) {\n // Unmapped group media — treat as file\n msgType = \"file\";\n scope = \"group\";\n }\n\n if (msgType === \"unknown\") {\n console.warn(`[wechat] Unknown message type code: ${typeCode}`);\n return null;\n }\n\n const sender = String(data.sender ?? data.from ?? \"\");\n const recipient = String(data.recipient ?? data.to ?? \"\");\n const content = String(data.content ?? data.text ?? \"\");\n const timestamp = Number(data.timestamp ?? Date.now());\n const msgId = String(data.msgId ?? data.id ?? `${sender}-${timestamp}`);\n\n // Group detection\n const isGroup = scope === \"group\" || sender.includes(\"@chatroom\");\n const threadId = isGroup\n ? String(data.roomId ?? data.threadId ?? sender)\n : undefined;\n const groupSubject = isGroup\n ? String(data.roomName ?? data.groupName ?? threadId ?? \"\")\n : undefined;\n\n // Media URL extraction (images, voice, video, files)\n const mediaTypes = new Set([\"image\", \"voice\", \"video\", \"file\"]);\n const hasMedia = mediaTypes.has(msgType);\n const imageUrl = hasMedia\n ? String(data.imageUrl ?? data.mediaUrl ?? data.url ?? data.fileUrl ?? \"\")\n : undefined;\n\n return {\n id: msgId,\n type: msgType,\n sender,\n recipient,\n content,\n timestamp,\n threadId,\n group: groupSubject ? { subject: groupSubject } : undefined,\n imageUrl: imageUrl || undefined,\n raw: payload,\n };\n}\n","import type {\n AccountStatus,\n ProxyApiResponse,\n ResolvedWechatAccount,\n} from \"./types\";\n\nconst SUCCESS = 1000;\nconst LOGIN_NEEDED = 1001;\nconst REQUEST_TIMEOUT_MS = 30_000;\n\nexport class ProxyClient {\n private readonly apiKey: string;\n private readonly baseUrl: string;\n private readonly accountId: string;\n private readonly deviceType: string;\n\n constructor(account: ResolvedWechatAccount) {\n this.apiKey = account.apiKey;\n this.baseUrl = normalizeProxyUrl(account.proxyUrl);\n this.accountId = account.id;\n this.deviceType = account.deviceType ?? \"ipad\";\n }\n\n private async request<T>(\n path: string,\n body?: Record<string, unknown>,\n ): Promise<ProxyApiResponse<T>> {\n const url = `${this.baseUrl}${path}`;\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n \"X-API-Key\": this.apiKey,\n \"X-Account-ID\": this.accountId,\n \"X-Device-Type\": this.deviceType,\n };\n\n let lastError: Error | undefined;\n for (let attempt = 0; attempt < 3; attempt++) {\n try {\n const res = await fetch(url, {\n method: \"POST\",\n headers,\n body: body ? JSON.stringify(body) : undefined,\n signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS),\n });\n\n if (res.status === 429) {\n const retryAfter = res.headers.get(\"Retry-After\");\n const delay = retryAfter\n ? Number.parseInt(retryAfter, 10) * 1000\n : Math.min(1000 * 2 ** attempt, 8000);\n // Consume the response body to release the connection\n await res.text().catch(() => {});\n await sleep(delay);\n continue;\n }\n\n const json = (await res.json()) as ProxyApiResponse<T>;\n return json;\n } catch (err) {\n lastError = err instanceof Error ? err : new Error(String(err));\n const delay = Math.min(1000 * 2 ** attempt, 8000);\n await sleep(delay);\n }\n }\n\n throw lastError ?? new Error(`Request failed after 3 attempts: ${path}`);\n }\n\n async getStatus(): Promise<AccountStatus> {\n const res = await this.request<AccountStatus>(\"/api/status\");\n if (res.code === LOGIN_NEEDED) {\n return {\n valid: true,\n loginState: \"waiting\",\n };\n }\n if (res.code !== SUCCESS && res.code !== 1002) {\n throw new Error(`getStatus failed: ${res.message ?? res.code}`);\n }\n return requireData(res, \"getStatus\");\n }\n\n async getQRCode(): Promise<string> {\n const res = await this.request<{ qrCodeUrl: string }>(\"/api/qrcode\");\n if (res.code !== SUCCESS) {\n throw new Error(`getQRCode failed: ${res.message ?? res.code}`);\n }\n return requireData(res, \"getQRCode\").qrCodeUrl;\n }\n\n async checkLogin(): Promise<{\n status: \"waiting\" | \"need_verify\" | \"logged_in\";\n verifyUrl?: string;\n wcId?: string;\n nickName?: string;\n }> {\n const res = await this.request<{\n status: \"waiting\" | \"need_verify\" | \"logged_in\";\n verifyUrl?: string;\n wcId?: string;\n nickName?: string;\n }>(\"/api/check-login\");\n if (res.code !== SUCCESS && res.code !== 1002) {\n throw new Error(`checkLogin failed: ${res.message ?? res.code}`);\n }\n return requireData(res, \"checkLogin\");\n }\n\n async sendText(to: string, text: string): Promise<void> {\n const res = await this.request(\"/api/send-text\", { to, text });\n if (res.code === LOGIN_NEEDED) {\n throw new LoginExpiredError();\n }\n if (res.code !== SUCCESS && res.code !== 1002) {\n throw new Error(`sendText failed: ${res.message ?? res.code}`);\n }\n }\n\n async sendImage(to: string, imagePath: string, text?: string): Promise<void> {\n const res = await this.request(\"/api/send-image\", {\n to,\n imagePath,\n text,\n });\n if (res.code === LOGIN_NEEDED) {\n throw new LoginExpiredError();\n }\n if (res.code !== SUCCESS && res.code !== 1002) {\n throw new Error(`sendImage failed: ${res.message ?? res.code}`);\n }\n }\n\n async getContacts(): Promise<{\n friends: Array<{ wxid: string; name: string }>;\n chatrooms: Array<{ wxid: string; name: string }>;\n }> {\n const res = await this.request<{\n friends: Array<{ wxid: string; name: string }>;\n chatrooms: Array<{ wxid: string; name: string }>;\n }>(\"/api/contacts\");\n if (res.code !== SUCCESS) {\n throw new Error(`getContacts failed: ${res.message ?? res.code}`);\n }\n return requireData(res, \"getContacts\");\n }\n\n async registerWebhook(url: string): Promise<void> {\n const res = await this.request(\"/api/webhook/register\", {\n webhookUrl: url,\n });\n if (res.code !== SUCCESS && res.code !== 1002) {\n throw new Error(`registerWebhook failed: ${res.message ?? res.code}`);\n }\n }\n\n get needsLogin(): boolean {\n return false; // Caller checks via getStatus()\n }\n}\n\nexport class LoginExpiredError extends Error {\n constructor() {\n super(\"WeChat login expired — re-login required\");\n this.name = \"LoginExpiredError\";\n }\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nfunction normalizeProxyUrl(proxyUrl: string): string {\n const parsed = new URL(proxyUrl);\n if (parsed.protocol !== \"https:\") {\n throw new Error(\"[wechat] proxyUrl must use https://\");\n }\n if (parsed.username || parsed.password) {\n throw new Error(\"[wechat] proxyUrl must not include credentials\");\n }\n parsed.hash = \"\";\n return parsed.toString().replace(/\\/$/, \"\");\n}\n\nfunction requireData<T>(response: ProxyApiResponse<T>, action: string): T {\n if (response.data === undefined) {\n throw new Error(`${action} failed: missing response data`);\n }\n return response.data;\n}\n","import type { ProxyClient } from \"./proxy-client\";\n\nconst DEFAULT_CHUNK_SIZE = 2000;\n\nexport interface ReplyDispatcherOptions {\n client: ProxyClient;\n chunkSize?: number;\n}\n\nexport class ReplyDispatcher {\n private readonly client: ProxyClient;\n private readonly chunkSize: number;\n\n constructor(options: ReplyDispatcherOptions) {\n this.client = options.client;\n this.chunkSize = options.chunkSize ?? DEFAULT_CHUNK_SIZE;\n }\n\n async sendText(to: string, text: string): Promise<void> {\n const chunks = this.chunk(text);\n for (const chunk of chunks) {\n try {\n await this.client.sendText(to, chunk);\n } catch (err) {\n console.error(`[wechat] Failed to send text to ${to}:`, err);\n throw err;\n }\n }\n }\n\n async sendImage(\n to: string,\n imagePath: string,\n caption?: string,\n ): Promise<void> {\n try {\n await this.client.sendImage(to, imagePath, caption);\n } catch (err) {\n console.error(`[wechat] Failed to send image to ${to}:`, err);\n throw err;\n }\n }\n\n private chunk(text: string): string[] {\n if (text.length <= this.chunkSize) {\n return [text];\n }\n\n const chunks: string[] = [];\n let remaining = text;\n\n while (remaining.length > 0) {\n if (remaining.length <= this.chunkSize) {\n chunks.push(remaining);\n break;\n }\n\n // Try to break at a newline\n let breakAt = remaining.lastIndexOf(\"\\n\", this.chunkSize);\n if (breakAt <= 0) {\n // Try to break at a space\n breakAt = remaining.lastIndexOf(\" \", this.chunkSize);\n }\n if (breakAt <= 0) {\n // Hard break\n breakAt = this.chunkSize;\n }\n\n chunks.push(remaining.slice(0, breakAt));\n remaining = remaining.slice(breakAt).trimStart();\n }\n\n return chunks;\n }\n}\n","/**\n * Display a QR code URL to the terminal.\n * Prints the URL for the user to open in a browser.\n * A vendored text-based QR renderer could be added here later.\n */\nexport function displayQRUrl(url: string): void {\n console.log(\"\");\n console.log(\"╔══════════════════════════════════════════╗\");\n console.log(\"║ Scan this QR code with WeChat to login ║\");\n console.log(\"╠══════════════════════════════════════════╣\");\n console.log(`║ ${url}`);\n console.log(\"╚══════════════════════════════════════════╝\");\n console.log(\"\");\n console.log(\"Open the URL above in your browser to see the QR code.\");\n console.log(\"\");\n}\n","import { Bot } from \"./bot\";\nimport { startCallbackServer } from \"./callback-server\";\nimport { LoginExpiredError, ProxyClient } from \"./proxy-client\";\nimport { ReplyDispatcher } from \"./reply-dispatcher\";\nimport type {\n ResolvedWechatAccount,\n WechatConfig,\n WechatMessageContext,\n} from \"./types\";\nimport { displayQRUrl } from \"./utils/qrcode\";\n\nconst HEALTH_CHECK_INTERVAL_MS = 60_000;\nconst LOGIN_POLL_INTERVAL_MS = 5_000;\nconst LOGIN_TIMEOUT_MS = 5 * 60_000;\n\nexport interface ChannelOptions {\n config: WechatConfig;\n onMessage: (\n accountId: string,\n msg: WechatMessageContext,\n ) => void | Promise<void>;\n}\n\nexport class WechatChannel {\n private readonly config: WechatConfig;\n private readonly onMessage: (\n accountId: string,\n msg: WechatMessageContext,\n ) => void | Promise<void>;\n private readonly accounts = new Map<\n string,\n {\n client: ProxyClient;\n dispatcher: ReplyDispatcher;\n bot: Bot;\n }\n >();\n private readonly callbackServers: Array<{\n close: () => Promise<void>;\n port: number;\n }> = [];\n private readonly loginPromises = new Map<string, Promise<void>>();\n private healthTimer: ReturnType<typeof setInterval> | null = null;\n private abortController: AbortController | null = null;\n\n constructor(options: ChannelOptions) {\n this.config = options.config;\n this.onMessage = options.onMessage;\n }\n\n async start(): Promise<void> {\n this.abortController = new AbortController();\n const resolved = this.resolveAccounts();\n\n if (resolved.length === 0) {\n console.warn(\"[wechat] No configured accounts found\");\n return;\n }\n\n const webhookAccountsByPort = new Map<\n number,\n Array<{ accountId: string; apiKey: string }>\n >();\n for (const account of resolved) {\n const existing = webhookAccountsByPort.get(account.webhookPort) ?? [];\n existing.push({ accountId: account.id, apiKey: account.apiKey });\n webhookAccountsByPort.set(account.webhookPort, existing);\n }\n\n for (const [webhookPort, accounts] of webhookAccountsByPort) {\n try {\n this.callbackServers.push(\n await startCallbackServer({\n port: webhookPort,\n accounts,\n onMessage: (accountId, msg) => this.routeIncoming(accountId, msg),\n signal: this.abortController.signal,\n }),\n );\n } catch (err) {\n const accountIds = accounts.map((a) => a.accountId).join(\", \");\n console.error(\n `[wechat] Failed to bind webhook server on port ${webhookPort} for accounts [${accountIds}]:`,\n err,\n );\n }\n }\n\n // Initialize each account\n for (const account of resolved) {\n const client = new ProxyClient(account);\n const dispatcher = new ReplyDispatcher({ client });\n const bot = new Bot({\n onMessage: (msg) => this.onMessage(account.id, msg),\n featuresGroups: this.config.features?.groups,\n featuresImages: this.config.features?.images,\n });\n\n this.accounts.set(account.id, { client, dispatcher, bot });\n\n // Login flow\n await this.ensureLoggedIn(account.id, client);\n const webhookUrl = `http://localhost:${account.webhookPort}/webhook/wechat/${account.id}`;\n\n try {\n await client.registerWebhook(webhookUrl);\n console.log(\n `[wechat] Account \"${account.id}\" registered webhook at ${webhookUrl}`,\n );\n } catch (err) {\n console.error(\n `[wechat] Failed to register webhook for \"${account.id}\":`,\n err,\n );\n throw new Error(\n `Webhook registration failed for account \"${account.id}\": ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n }\n\n // Periodic health check\n this.healthTimer = setInterval(\n () => this.healthCheck(),\n HEALTH_CHECK_INTERVAL_MS,\n );\n }\n\n async stop(): Promise<void> {\n if (this.healthTimer) {\n clearInterval(this.healthTimer);\n this.healthTimer = null;\n }\n\n for (const [, { bot }] of this.accounts) {\n bot.stop();\n }\n this.accounts.clear();\n\n if (this.abortController) {\n this.abortController.abort();\n this.abortController = null;\n }\n\n const servers = this.callbackServers.splice(0);\n await Promise.all(\n servers.map((server) => server.close().catch(() => undefined)),\n );\n }\n\n async sendText(accountId: string, to: string, text: string): Promise<void> {\n const entry = this.accounts.get(accountId);\n if (!entry) throw new Error(`Unknown account: ${accountId}`);\n\n try {\n await entry.dispatcher.sendText(to, text);\n } catch (err) {\n if (err instanceof LoginExpiredError) {\n await this.ensureLoggedIn(accountId, entry.client);\n await entry.dispatcher.sendText(to, text);\n } else {\n throw err;\n }\n }\n }\n\n async sendImage(\n accountId: string,\n to: string,\n imagePath: string,\n caption?: string,\n ): Promise<void> {\n const entry = this.accounts.get(accountId);\n if (!entry) throw new Error(`Unknown account: ${accountId}`);\n\n try {\n await entry.dispatcher.sendImage(to, imagePath, caption);\n } catch (err) {\n if (err instanceof LoginExpiredError) {\n await this.ensureLoggedIn(accountId, entry.client);\n await entry.dispatcher.sendImage(to, imagePath, caption);\n } else {\n throw err;\n }\n }\n }\n\n getAccountIds(): string[] {\n return Array.from(this.accounts.keys());\n }\n\n async listContacts(accountId: string): Promise<{\n friends: Array<{ wxid: string; name: string }>;\n chatrooms: Array<{ wxid: string; name: string }>;\n }> {\n const entry = this.accounts.get(accountId);\n if (!entry) throw new Error(`Unknown account: ${accountId}`);\n return entry.client.getContacts();\n }\n\n private routeIncoming(accountId: string, msg: WechatMessageContext): void {\n const entry = this.accounts.get(accountId);\n if (!entry) {\n console.warn(\n `[wechat] Received webhook for unknown account \"${accountId}\"`,\n );\n return;\n }\n\n entry.bot.handleIncoming(msg);\n }\n\n private async ensureLoggedIn(\n accountId: string,\n client: ProxyClient,\n ): Promise<void> {\n const existing = this.loginPromises.get(accountId);\n if (existing) {\n return existing;\n }\n\n const promise = this.doLogin(accountId, client).finally(() => {\n this.loginPromises.delete(accountId);\n });\n this.loginPromises.set(accountId, promise);\n return promise;\n }\n\n private async doLogin(accountId: string, client: ProxyClient): Promise<void> {\n const status = await client.getStatus();\n\n if (status.loginState === \"logged_in\") {\n console.log(\n `[wechat] Account \"${accountId}\" logged in as ${status.nickName ?? status.wcId}`,\n );\n return;\n }\n\n console.log(\n `[wechat] Account \"${accountId}\" needs login — generating QR code...`,\n );\n const qrUrl = await client.getQRCode();\n displayQRUrl(qrUrl);\n\n const timeoutMs = this.config.loginTimeoutMs ?? LOGIN_TIMEOUT_MS;\n const deadline = Date.now() + timeoutMs;\n while (Date.now() < deadline) {\n await sleep(LOGIN_POLL_INTERVAL_MS);\n\n if (this.abortController?.signal.aborted) {\n throw new Error(\"Login aborted\");\n }\n\n const result = await client.checkLogin();\n\n if (result.status === \"logged_in\") {\n console.log(\n `[wechat] Account \"${accountId}\" logged in as ${result.nickName ?? result.wcId}`,\n );\n return;\n }\n\n if (result.status === \"need_verify\") {\n console.log(\n `[wechat] Verification needed: ${result.verifyUrl ?? \"check your phone\"}`,\n );\n }\n }\n\n throw new Error(\n `[wechat] Login timed out for account \"${accountId}\" after ${Math.round(timeoutMs / 1000)} seconds`,\n );\n }\n\n private async healthCheck(): Promise<void> {\n for (const [accountId, { client }] of this.accounts) {\n try {\n const status = await client.getStatus();\n if (status.loginState !== \"logged_in\") {\n console.warn(\n `[wechat] Account \"${accountId}\" login expired — attempting re-login`,\n );\n await this.ensureLoggedIn(accountId, client);\n }\n } catch (err) {\n console.error(`[wechat] Health check failed for \"${accountId}\":`, err);\n }\n }\n }\n\n private resolveAccounts(): ResolvedWechatAccount[] {\n const accounts: ResolvedWechatAccount[] = [];\n const rawPort = Number(process.env.ELIZA_WECHAT_WEBHOOK_PORT);\n const envPort =\n Number.isFinite(rawPort) && rawPort > 0 ? rawPort : undefined;\n const defaultPort = envPort ?? this.config.webhookPort ?? 18790;\n const defaultDevice = this.config.deviceType ?? \"ipad\";\n\n if (this.config.accounts) {\n for (const [id, acc] of Object.entries(this.config.accounts)) {\n if (acc.enabled === false) continue;\n accounts.push({\n id,\n apiKey: acc.apiKey,\n proxyUrl: acc.proxyUrl,\n deviceType: acc.deviceType ?? defaultDevice,\n webhookPort: acc.webhookPort ?? defaultPort,\n wcId: acc.wcId,\n nickName: acc.nickName,\n });\n }\n } else if (this.config.apiKey && this.config.proxyUrl) {\n accounts.push({\n id: \"default\",\n apiKey: this.config.apiKey,\n proxyUrl: this.config.proxyUrl,\n deviceType: defaultDevice,\n webhookPort: defaultPort,\n });\n }\n\n return accounts;\n }\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n","/**\n * WeChat ConnectorAccountManager provider.\n *\n * Adapts the multi-account scaffolding (`WechatConfig.accounts`) to the\n * `ConnectorAccountProvider` contract from\n * `@elizaos/core/connectors/account-manager`.\n *\n * Source of truth is the wechat config block (proxy URL + API key per account).\n * AccountKey is the proxy account id (the key in `WechatConfig.accounts`) or\n * `default` for single-account env-only deployments. Role is `AGENT` since\n * wechat proxy creds authenticate the bot, not the user.\n */\n\nimport type {\n ConnectorAccount,\n ConnectorAccountManager,\n ConnectorAccountPatch,\n ConnectorAccountProvider,\n IAgentRuntime,\n} from \"@elizaos/core\";\nimport type { WechatConfig } from \"./types\";\n\nconst WECHAT_PROVIDER_ID = \"wechat\";\nconst WECHAT_DEFAULT_ACCOUNT_ID = \"default\";\n\nfunction getWechatConfig(runtime: IAgentRuntime): WechatConfig | undefined {\n const character = runtime.character?.settings as\n | { connectors?: { wechat?: WechatConfig }; wechat?: WechatConfig }\n | undefined;\n return character?.connectors?.wechat ?? character?.wechat;\n}\n\ninterface WechatResolvedAccount {\n id: string;\n enabled: boolean;\n apiKeyConfigured: boolean;\n proxyUrl?: string;\n wcId?: string;\n nickName?: string;\n name?: string;\n}\n\nfunction listWechatAccounts(runtime: IAgentRuntime): WechatResolvedAccount[] {\n const config = getWechatConfig(runtime);\n const result: WechatResolvedAccount[] = [];\n\n if (!config) {\n // Single-account env-only fallback\n const envApiKey = runtime.getSetting?.(\"WECHAT_API_KEY\") as\n | string\n | undefined;\n const envProxy = runtime.getSetting?.(\"WECHAT_PROXY_URL\") as\n | string\n | undefined;\n if (envApiKey?.trim() || envProxy?.trim()) {\n result.push({\n id: WECHAT_DEFAULT_ACCOUNT_ID,\n enabled: true,\n apiKeyConfigured: Boolean(envApiKey?.trim()),\n proxyUrl: envProxy?.trim() || undefined,\n });\n }\n return result;\n }\n\n if (config.enabled === false) {\n // Plugin disabled — still surface the account as `disabled`.\n if (config.apiKey?.trim() || config.accounts) {\n result.push({\n id: WECHAT_DEFAULT_ACCOUNT_ID,\n enabled: false,\n apiKeyConfigured: Boolean(config.apiKey?.trim()),\n proxyUrl: config.proxyUrl,\n });\n }\n return result;\n }\n\n if (config.apiKey?.trim()) {\n result.push({\n id: WECHAT_DEFAULT_ACCOUNT_ID,\n enabled: true,\n apiKeyConfigured: true,\n proxyUrl: config.proxyUrl,\n });\n }\n\n if (config.accounts && typeof config.accounts === \"object\") {\n for (const [id, account] of Object.entries(config.accounts)) {\n if (!id) continue;\n result.push({\n id: id.trim().toLowerCase(),\n enabled: account.enabled !== false,\n apiKeyConfigured: Boolean(account.apiKey?.trim()),\n proxyUrl: account.proxyUrl,\n wcId: account.wcId,\n nickName: account.nickName,\n name: account.name,\n });\n }\n }\n\n return result;\n}\n\nfunction toConnectorAccount(account: WechatResolvedAccount): ConnectorAccount {\n const now = Date.now();\n return {\n id: account.id,\n provider: WECHAT_PROVIDER_ID,\n label: account.name ?? account.nickName ?? account.id,\n role: \"AGENT\",\n purpose: [\"messaging\"],\n accessGate: \"open\",\n status:\n account.enabled && account.apiKeyConfigured ? \"connected\" : \"disabled\",\n externalId: account.wcId || undefined,\n displayHandle: account.nickName || undefined,\n createdAt: now,\n updatedAt: now,\n metadata: {\n proxyUrl: account.proxyUrl ?? \"\",\n wcId: account.wcId ?? \"\",\n nickName: account.nickName ?? \"\",\n },\n };\n}\n\nexport function createWechatConnectorAccountProvider(\n runtime: IAgentRuntime,\n): ConnectorAccountProvider {\n return {\n provider: WECHAT_PROVIDER_ID,\n label: \"WeChat\",\n listAccounts: async (\n _manager: ConnectorAccountManager,\n ): Promise<ConnectorAccount[]> => {\n const accounts = listWechatAccounts(runtime);\n return accounts.map(toConnectorAccount);\n },\n createAccount: async (\n input: ConnectorAccountPatch,\n _manager: ConnectorAccountManager,\n ) => {\n return {\n ...input,\n provider: WECHAT_PROVIDER_ID,\n role: input.role ?? \"AGENT\",\n purpose: input.purpose ?? [\"messaging\"],\n accessGate: input.accessGate ?? \"open\",\n status: input.status ?? \"pending\",\n };\n },\n patchAccount: async (\n _accountId: string,\n patch: ConnectorAccountPatch,\n _manager: ConnectorAccountManager,\n ) => {\n return { ...patch, provider: WECHAT_PROVIDER_ID };\n },\n deleteAccount: async (\n _accountId: string,\n _manager: ConnectorAccountManager,\n ) => {\n // Provider-layer account deletion returns cleanly; runtime credentials live in character\n // settings; deletion of those is out of band.\n },\n };\n}\n","import { type Content, type Memory, stringToUuid } from \"@elizaos/core\";\nimport type { WechatMessageContext } from \"./types\";\n\ntype ResponseCallback = (content: Content) => Promise<Memory[]>;\n\ntype RuntimeLike = {\n agentId?: string;\n ensureConnection?: (details: Record<string, unknown>) => Promise<unknown>;\n elizaOS?: {\n sendMessage?: (\n runtime: unknown,\n message: Memory,\n options?: { onResponse?: ResponseCallback },\n ) => Promise<{ responseContent?: Content } | undefined>;\n };\n messageService?: {\n handleMessage?: (\n runtime: unknown,\n message: Memory,\n onResponse: ResponseCallback,\n ) => Promise<{ responseContent?: Content } | undefined>;\n };\n emitEvent?: (events: string[], payload: unknown) => Promise<unknown>;\n createMemory?: (memory: Memory, tableName: string) => Promise<unknown>;\n logger?: {\n warn?: (...args: unknown[]) => void;\n error?: (...args: unknown[]) => void;\n };\n};\n\nexport interface IncomingWechatDeliveryOptions {\n runtime: unknown;\n accountId: string;\n message: WechatMessageContext;\n sendText: (accountId: string, to: string, text: string) => Promise<void>;\n}\n\nexport async function deliverIncomingWechatMessage(\n options: IncomingWechatDeliveryOptions,\n): Promise<void> {\n const runtime = options.runtime as RuntimeLike;\n const agentId =\n typeof runtime.agentId === \"string\" && runtime.agentId.length > 0\n ? runtime.agentId\n : stringToUuid(\"wechat-agent\");\n const incomingMemory = buildIncomingMemory(\n agentId,\n options.accountId,\n options.message,\n );\n const replyTarget = resolveReplyTarget(options.message);\n let replyIndex = 0;\n let replyDelivered = false;\n\n const onResponse: ResponseCallback = async (content) => {\n const replyText = extractReplyText(content);\n if (!replyText) {\n return [];\n }\n\n replyDelivered = true;\n await options.sendText(options.accountId, replyTarget, replyText);\n\n const replyMemory = buildReplyMemory(\n agentId,\n options.accountId,\n options.message,\n replyText,\n replyIndex,\n );\n replyIndex += 1;\n\n await runtime.createMemory?.(replyMemory, \"messages\");\n return [replyMemory];\n };\n\n await runtime.ensureConnection?.({\n entityId: incomingMemory.entityId,\n roomId: incomingMemory.roomId,\n worldId: stringToUuid(`wechat:world:${options.accountId}`),\n userName: options.message.sender,\n userId: options.message.sender,\n name: options.message.sender,\n source: \"wechat\",\n type: getChannelType(options.message),\n channelId: resolveChannelId(options.message),\n worldName: \"WeChat\",\n });\n\n if (typeof runtime.elizaOS?.sendMessage === \"function\") {\n const result = await runtime.elizaOS.sendMessage(\n options.runtime,\n incomingMemory,\n { onResponse },\n );\n await maybeHandleResponseContent(result, replyDelivered, onResponse);\n return;\n }\n\n if (typeof runtime.messageService?.handleMessage === \"function\") {\n const result = await runtime.messageService.handleMessage(\n options.runtime,\n incomingMemory,\n onResponse,\n );\n await maybeHandleResponseContent(result, replyDelivered, onResponse);\n return;\n }\n\n if (typeof runtime.emitEvent === \"function\") {\n await runtime.emitEvent([\"MESSAGE_RECEIVED\"], {\n runtime: options.runtime,\n message: incomingMemory,\n callback: onResponse,\n source: \"wechat\",\n });\n return;\n }\n\n runtime.logger?.warn?.(\n \"[wechat] No inbound runtime message pipeline is available\",\n );\n}\n\nfunction buildIncomingMemory(\n agentId: string,\n accountId: string,\n message: WechatMessageContext,\n): Memory {\n return {\n id: stringToUuid(`wechat:incoming:${accountId}:${message.id}`),\n agentId,\n entityId: stringToUuid(`wechat:entity:${accountId}:${message.sender}`),\n roomId: stringToUuid(\n `wechat:room:${accountId}:${resolveChannelId(message)}`,\n ),\n createdAt: message.timestamp,\n content: {\n text: message.content,\n source: \"wechat\",\n channelType: getChannelType(message),\n metadata: {\n accountId,\n sender: message.sender,\n recipient: message.recipient,\n messageType: message.type,\n threadId: message.threadId,\n groupSubject: message.group?.subject,\n imageUrl: message.imageUrl,\n },\n },\n metadata: {\n type: \"message\",\n source: \"wechat\",\n provider: \"wechat\",\n timestamp: message.timestamp,\n entityName: message.sender,\n entityUserName: message.sender,\n fromId: message.sender,\n sourceId: stringToUuid(`wechat:entity:${accountId}:${message.sender}`),\n chatType: getChannelType(message),\n messageIdFull: message.id,\n sender: {\n id: message.sender,\n name: message.sender,\n username: message.sender,\n },\n wechat: {\n id: message.sender,\n userId: message.sender,\n username: message.sender,\n userName: message.sender,\n name: message.sender,\n messageId: message.id,\n accountId,\n recipient: message.recipient,\n threadId: message.threadId,\n groupSubject: message.group?.subject,\n },\n },\n } as Memory;\n}\n\nfunction buildReplyMemory(\n agentId: string,\n accountId: string,\n message: WechatMessageContext,\n text: string,\n replyIndex: number,\n): Memory {\n return {\n id: stringToUuid(`wechat:reply:${accountId}:${message.id}:${replyIndex}`),\n agentId,\n entityId: agentId,\n roomId: stringToUuid(\n `wechat:room:${accountId}:${resolveChannelId(message)}`,\n ),\n createdAt: Date.now(),\n content: {\n text,\n source: \"wechat\",\n channelType: getChannelType(message),\n inReplyTo: message.id,\n metadata: {\n accountId,\n recipient: resolveReplyTarget(message),\n },\n },\n metadata: {\n type: \"message\",\n source: \"wechat\",\n provider: \"wechat\",\n timestamp: Date.now(),\n fromBot: true,\n fromId: agentId,\n sourceId: agentId,\n chatType: getChannelType(message),\n messageIdFull: `wechat:reply:${message.id}:${replyIndex}`,\n wechat: {\n accountId,\n recipient: resolveReplyTarget(message),\n threadId: message.threadId,\n },\n },\n } as Memory;\n}\n\nfunction getChannelType(message: WechatMessageContext): \"DM\" | \"GROUP\" {\n return message.group ? \"GROUP\" : \"DM\";\n}\n\nfunction resolveChannelId(message: WechatMessageContext): string {\n return message.threadId ?? message.sender;\n}\n\nfunction resolveReplyTarget(message: WechatMessageContext): string {\n return message.threadId ?? message.sender;\n}\n\nfunction extractReplyText(content: Content): string | null {\n if (typeof content.text !== \"string\") {\n return null;\n }\n\n const trimmed = content.text.trim();\n return trimmed.length > 0 ? trimmed : null;\n}\n\nasync function maybeHandleResponseContent(\n result: { responseContent?: Content } | undefined,\n replyDelivered: boolean,\n onResponse: ResponseCallback,\n): Promise<void> {\n if (replyDelivered || !result?.responseContent) {\n return;\n }\n\n await onResponse(result.responseContent);\n}\n"],"mappings":"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","names":["stringToUuid","sleep","stringToUuid"]}
@@ -0,0 +1,34 @@
1
+ import type { AccountStatus, ResolvedWechatAccount } from "./types";
2
+ export declare class ProxyClient {
3
+ private readonly apiKey;
4
+ private readonly baseUrl;
5
+ private readonly accountId;
6
+ private readonly deviceType;
7
+ constructor(account: ResolvedWechatAccount);
8
+ private request;
9
+ getStatus(): Promise<AccountStatus>;
10
+ getQRCode(): Promise<string>;
11
+ checkLogin(): Promise<{
12
+ status: "waiting" | "need_verify" | "logged_in";
13
+ verifyUrl?: string;
14
+ wcId?: string;
15
+ nickName?: string;
16
+ }>;
17
+ sendText(to: string, text: string): Promise<void>;
18
+ sendImage(to: string, imagePath: string, text?: string): Promise<void>;
19
+ getContacts(): Promise<{
20
+ friends: Array<{
21
+ wxid: string;
22
+ name: string;
23
+ }>;
24
+ chatrooms: Array<{
25
+ wxid: string;
26
+ name: string;
27
+ }>;
28
+ }>;
29
+ registerWebhook(url: string): Promise<void>;
30
+ get needsLogin(): boolean;
31
+ }
32
+ export declare class LoginExpiredError extends Error {
33
+ constructor();
34
+ }
@@ -0,0 +1,13 @@
1
+ import type { ProxyClient } from "./proxy-client";
2
+ export interface ReplyDispatcherOptions {
3
+ client: ProxyClient;
4
+ chunkSize?: number;
5
+ }
6
+ export declare class ReplyDispatcher {
7
+ private readonly client;
8
+ private readonly chunkSize;
9
+ constructor(options: ReplyDispatcherOptions);
10
+ sendText(to: string, text: string): Promise<void>;
11
+ sendImage(to: string, imagePath: string, caption?: string): Promise<void>;
12
+ private chunk;
13
+ }
@@ -0,0 +1,8 @@
1
+ import type { WechatMessageContext } from "./types";
2
+ export interface IncomingWechatDeliveryOptions {
3
+ runtime: unknown;
4
+ accountId: string;
5
+ message: WechatMessageContext;
6
+ sendText: (accountId: string, to: string, text: string) => Promise<void>;
7
+ }
8
+ export declare function deliverIncomingWechatMessage(options: IncomingWechatDeliveryOptions): Promise<void>;
@@ -0,0 +1,64 @@
1
+ type DeviceType = "ipad" | "mac";
2
+ type LoginStatus = "waiting" | "need_verify" | "logged_in";
3
+ interface WechatAccountConfig {
4
+ enabled?: boolean;
5
+ name?: string;
6
+ apiKey: string;
7
+ proxyUrl: string;
8
+ deviceType?: DeviceType;
9
+ webhookPort?: number;
10
+ webhookUrl?: string;
11
+ wcId?: string;
12
+ nickName?: string;
13
+ }
14
+ export interface WechatConfig {
15
+ enabled?: boolean;
16
+ apiKey?: string;
17
+ proxyUrl?: string;
18
+ webhookPort?: number;
19
+ deviceType?: DeviceType;
20
+ loginTimeoutMs?: number;
21
+ accounts?: Record<string, WechatAccountConfig>;
22
+ features?: {
23
+ images?: boolean;
24
+ groups?: boolean;
25
+ };
26
+ }
27
+ export interface ResolvedWechatAccount {
28
+ id: string;
29
+ apiKey: string;
30
+ proxyUrl: string;
31
+ deviceType: DeviceType;
32
+ webhookPort: number;
33
+ wcId?: string;
34
+ nickName?: string;
35
+ }
36
+ export type WechatMessageType = "text" | "image" | "video" | "file" | "voice" | "unknown";
37
+ export interface WechatMessageContext {
38
+ id: string;
39
+ type: WechatMessageType;
40
+ sender: string;
41
+ recipient: string;
42
+ content: string;
43
+ timestamp: number;
44
+ threadId?: string;
45
+ group?: {
46
+ subject: string;
47
+ };
48
+ imageUrl?: string;
49
+ raw: unknown;
50
+ }
51
+ export interface AccountStatus {
52
+ valid: boolean;
53
+ wcId?: string;
54
+ loginState: LoginStatus;
55
+ nickName?: string;
56
+ tier?: string;
57
+ quota?: number;
58
+ }
59
+ export interface ProxyApiResponse<T> {
60
+ code: number;
61
+ message?: string;
62
+ data?: T;
63
+ }
64
+ export {};
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Display a QR code URL to the terminal.
3
+ * Prints the URL for the user to open in a browser.
4
+ * A vendored text-based QR renderer could be added here later.
5
+ */
6
+ export declare function displayQRUrl(url: string): void;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@elizaos/plugin-wechat",
3
- "version": "2.0.3-beta.6",
3
+ "version": "2.0.3-beta.7",
4
4
  "description": "WeChat connector plugin for elizaOS via proxy API",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -57,13 +57,13 @@
57
57
  "clean": "node ../../packages/scripts/rm-path-recursive.mjs dist"
58
58
  },
59
59
  "peerDependencies": {
60
- "@elizaos/core": "2.0.3-beta.6"
60
+ "@elizaos/core": "2.0.3-beta.7"
61
61
  },
62
62
  "publishConfig": {
63
63
  "access": "public"
64
64
  },
65
65
  "devDependencies": {
66
- "@elizaos/core": "2.0.3-beta.6",
66
+ "@elizaos/core": "2.0.3-beta.7",
67
67
  "tsup": "^8.5.1",
68
68
  "typescript": "^6.0.3",
69
69
  "vitest": "^4.0.18"
@@ -87,5 +87,5 @@
87
87
  "messaging"
88
88
  ],
89
89
  "packageType": "plugin",
90
- "gitHead": "990dc996172b3e0fb525a75052a5ac28a4cd4de5"
90
+ "gitHead": "61094f10458d11055c75b3dd0bae374e3f66bac5"
91
91
  }