import { type BotMessage, type BotReply, type ChannelHandler, type ChannelInstance, type ChannelTransport, createBotMessage, normalizeReply, shouldHandleGroupMessage } from "../../core.js"; export interface WechatIncomingEvent { message?: WechatIncomingEvent; messageId?: string; fromUser?: string; roomId?: string; conversationId?: string; senderId?: string; text?: string; mentions?: string[]; threadId?: string; } export interface WechatOutgoingMessage extends BotReply { channel: "wechat"; conversationId: string; replyToMessageId: string; } export interface WechatChannelConfig { routing?: { groupRequireMention?: boolean; }; transport?: ChannelTransport; } export interface WechatHandleResult { handled: boolean; reason?: "ignored" | "filtered"; message?: BotMessage; reply?: WechatOutgoingMessage | null; } export interface WechatChannel extends ChannelInstance { name: "wechat"; isStarted(): boolean; getSentMessages(): WechatOutgoingMessage[]; handleEvent(event: WechatIncomingEvent): Promise; simulateIncomingText(input: { text: string; senderId?: string; conversationId?: string; isDirectMessage?: boolean; mentions?: string[]; }): Promise; } function unwrapSource(event: WechatIncomingEvent): WechatIncomingEvent { return event.message ?? event; } export function normalizeWechatEvent(event: WechatIncomingEvent): BotMessage | null { const source = unwrapSource(event); const roomId = source.roomId ?? source.conversationId; const senderId = source.fromUser ?? source.senderId; const text = source.text; if (!senderId || typeof text !== "string") { return null; } return createBotMessage({ channel: "wechat", conversationId: roomId ?? senderId, senderId, messageId: source.messageId ?? `wechat-${Date.now()}`, text, isDirectMessage: !roomId, mentions: source.mentions ?? [], threadId: source.threadId, raw: event }); } function createOutgoingMessage(message: BotMessage, reply: BotReply): WechatOutgoingMessage { return { channel: "wechat", conversationId: message.conversationId, replyToMessageId: message.messageId, text: reply.text }; } export function createWechatChannel( config: WechatChannelConfig = {}, handler: ChannelHandler = {} ): WechatChannel { const sentMessages: WechatOutgoingMessage[] = []; let started = false; async function sendReply( message: BotMessage, reply: string | BotReply | null | void ): Promise { const normalizedReply = normalizeReply(reply); if (!normalizedReply) return null; const outgoingMessage = createOutgoingMessage(message, normalizedReply); sentMessages.push(outgoingMessage); await config.transport?.send?.(outgoingMessage); return outgoingMessage; } return { name: "wechat", async start() { started = true; await config.transport?.start?.(); }, async stop() { started = false; await config.transport?.stop?.(); }, isStarted() { return started; }, getSentMessages() { return [...sentMessages]; }, async handleEvent(event) { const message = normalizeWechatEvent(event); if (!message) { return { handled: false, reason: "ignored" }; } const shouldHandle = shouldHandleGroupMessage(message, { requireMention: config.routing?.groupRequireMention ?? false }); if (!shouldHandle) { return { handled: false, reason: "filtered", message }; } const reply = await handler.onMessage?.(message); const outgoingMessage = await sendReply(message, reply); return { handled: true, message, reply: outgoingMessage }; }, async simulateIncomingText({ text, senderId = "wechat-user", conversationId = "wechat-chat", isDirectMessage = true, mentions = [] }) { return this.handleEvent({ messageId: `wechat-${Date.now()}`, fromUser: senderId, roomId: isDirectMessage ? undefined : conversationId, conversationId, text, mentions }); } }; }