// ╔══════════════════════════════════════════════════════════════════════╗ // ║ PlatformAdapter — DO NOT CHANGE ║ // ║ ║ // ║ Defines the contract for messaging platform integrations. ║ // ║ WahaPlatformAdapter implements it by delegating to send.ts. ║ // ║ ║ // ║ Purpose: Decouples channel.ts from WAHA-specific implementation. ║ // ║ Swapping transport = new adapter class only, no channel.ts edits. ║ // ║ ║ // ║ Created: Phase 32, Plan 02 (2026-03-20). ║ // ╚══════════════════════════════════════════════════════════════════════╝ import { sendWahaText, sendWahaMediaBatch, sendWahaPoll, sendWahaReaction, editWahaMessage, deleteWahaMessage, pinWahaMessage, unpinWahaMessage, setWahaPresenceStatus, getWahaPresence, getWahaGroups, getWahaGroupParticipants, getWahaContacts, getWahaContact, } from "./send.js"; import type { CoreConfig } from "./types.js"; // --------------------------------------------------------------------------- // PlatformAdapter interface // --------------------------------------------------------------------------- /** * Minimal interface covering the core messaging operations that channel.ts * dispatches through the ChannelMessageActionAdapter. * * Kept PRACTICAL — only operations needed for core send/receive dispatch. * WAHA-specific extras (group management, labels, etc.) remain on * WahaPlatformAdapter and are accessed via direct imports in channel.ts. */ export interface PlatformAdapter { // Core messaging sendText(params: { to: string; text: string; accountId?: string; replyToId?: string }): Promise<{ id: string }>; sendMedia(params: { to: string; mediaUrls: string[]; caption?: string; accountId?: string; replyToId?: string }): Promise; sendPoll(params: { to: string; question: string; options: string[]; multipleAnswers?: boolean; accountId?: string }): Promise<{ id: string }>; sendReaction(params: { messageId: string; reaction: string; accountId?: string }): Promise; // Message management editMessage(params: { chatId: string; messageId: string; text: string; accountId?: string }): Promise; deleteMessage(params: { chatId: string; messageId: string; accountId?: string }): Promise; pinMessage(params: { chatId: string; messageId: string; accountId?: string }): Promise; unpinMessage(params: { chatId: string; messageId: string; accountId?: string }): Promise; // Presence setPresence(params: { status: "online" | "offline"; accountId?: string }): Promise; getPresence(params: { contactId: string; accountId?: string }): Promise; // Groups getGroups(params: { accountId?: string }): Promise; getGroupParticipants(params: { groupId: string; accountId?: string }): Promise; // Contacts getContacts(params: { accountId?: string }): Promise; getContact(params: { contactId: string; accountId?: string }): Promise; } // --------------------------------------------------------------------------- // WahaPlatformAdapter // --------------------------------------------------------------------------- /** * WAHA implementation of PlatformAdapter. * Delegates to send.ts functions — no business logic here. */ export class WahaPlatformAdapter implements PlatformAdapter { private readonly cfg: CoreConfig; constructor(opts: { cfg: CoreConfig }) { this.cfg = opts.cfg; } // Core messaging async sendText(params: { to: string; text: string; accountId?: string; replyToId?: string }): Promise<{ id: string }> { const result = await sendWahaText({ cfg: this.cfg, to: params.to, text: params.text, accountId: params.accountId, replyToId: params.replyToId, }); return { id: (result as any)?.key?.id ?? "" }; } async sendMedia(params: { to: string; mediaUrls: string[]; caption?: string; accountId?: string; replyToId?: string }): Promise { await sendWahaMediaBatch({ cfg: this.cfg, to: params.to, mediaUrls: params.mediaUrls, caption: params.caption, accountId: params.accountId, replyToId: params.replyToId, }); } async sendPoll(params: { to: string; question: string; options: string[]; multipleAnswers?: boolean; accountId?: string }): Promise<{ id: string }> { const result = await sendWahaPoll({ cfg: this.cfg, chatId: params.to, name: params.question, options: params.options, multipleAnswers: params.multipleAnswers, accountId: params.accountId, }); return { id: (result as any)?.key?.id ?? "" }; } async sendReaction(params: { messageId: string; reaction: string; accountId?: string }): Promise { await sendWahaReaction({ cfg: this.cfg, messageId: params.messageId, emoji: params.reaction, accountId: params.accountId, }); } // Message management async editMessage(params: { chatId: string; messageId: string; text: string; accountId?: string }): Promise { await editWahaMessage({ cfg: this.cfg, chatId: params.chatId, messageId: params.messageId, text: params.text, accountId: params.accountId, }); } async deleteMessage(params: { chatId: string; messageId: string; accountId?: string }): Promise { await deleteWahaMessage({ cfg: this.cfg, chatId: params.chatId, messageId: params.messageId, accountId: params.accountId, }); } async pinMessage(params: { chatId: string; messageId: string; accountId?: string }): Promise { await pinWahaMessage({ cfg: this.cfg, chatId: params.chatId, messageId: params.messageId, accountId: params.accountId, }); } async unpinMessage(params: { chatId: string; messageId: string; accountId?: string }): Promise { await unpinWahaMessage({ cfg: this.cfg, chatId: params.chatId, messageId: params.messageId, accountId: params.accountId, }); } // Presence async setPresence(params: { status: "online" | "offline"; accountId?: string }): Promise { await setWahaPresenceStatus({ cfg: this.cfg, status: params.status, accountId: params.accountId, }); } async getPresence(params: { contactId: string; accountId?: string }): Promise { return getWahaPresence({ cfg: this.cfg, contactId: params.contactId, accountId: params.accountId, }); } // Groups async getGroups(params: { accountId?: string }): Promise { return getWahaGroups({ cfg: this.cfg, accountId: params.accountId, }); } async getGroupParticipants(params: { groupId: string; accountId?: string }): Promise { return getWahaGroupParticipants({ cfg: this.cfg, groupId: params.groupId, accountId: params.accountId, }); } // Contacts async getContacts(params: { accountId?: string }): Promise { return getWahaContacts({ cfg: this.cfg, accountId: params.accountId, }); } async getContact(params: { contactId: string; accountId?: string }): Promise { return getWahaContact({ cfg: this.cfg, contactId: params.contactId, accountId: params.accountId, }); } } // --------------------------------------------------------------------------- // Factory // --------------------------------------------------------------------------- /** * Create a PlatformAdapter for the given config. * Returns a WahaPlatformAdapter — the only implementation for now. */ export function createPlatformAdapter(cfg: CoreConfig): PlatformAdapter { return new WahaPlatformAdapter({ cfg }); }