import type { AnyMessageContent, WAPresence } from '@whiskeysockets/baileys'; import { recordChannelActivity } from '../../infra/channel-activity.js'; import { toWhatsappJid } from '../../utils.js'; import type { ActiveWebSendOptions } from '../active-listener.js'; export function createWebSendApi(params: { sock: { sendMessage: (jid: string, content: AnyMessageContent) => Promise; sendPresenceUpdate: ( presence: WAPresence, jid?: string ) => Promise; }; defaultAccountId: string; }) { return { sendMessage: async ( to: string, text: string, mediaBuffer?: Buffer, mediaType?: string, sendOptions?: ActiveWebSendOptions, location?: { latitude: number; longitude: number; name?: string; address?: string; accuracy?: number; } ): Promise<{ messageId: string }> => { const jid = toWhatsappJid(to); let payload: AnyMessageContent; // Location messages take precedence if (location) { payload = { location: { degreesLatitude: location.latitude, degreesLongitude: location.longitude, name: location.name, address: location.address, accuracyInMeters: location.accuracy, }, }; } else if (mediaBuffer && mediaType) { if (mediaType.startsWith('image/')) { payload = { image: mediaBuffer, caption: text || undefined, mimetype: mediaType, }; } else if (mediaType.startsWith('audio/')) { payload = { audio: mediaBuffer, ptt: true, mimetype: mediaType }; } else if (mediaType.startsWith('video/')) { const gifPlayback = sendOptions?.gifPlayback; payload = { video: mediaBuffer, caption: text || undefined, mimetype: mediaType, ...(gifPlayback ? { gifPlayback: true } : {}), }; } else { payload = { document: mediaBuffer, fileName: 'file', caption: text || undefined, mimetype: mediaType, }; } } else { payload = { text }; } const result = await params.sock.sendMessage(jid, payload); const accountId = sendOptions?.accountId ?? params.defaultAccountId; recordChannelActivity({ channel: 'whatsapp', accountId, direction: 'outbound', }); const messageId = typeof result === 'object' && result && 'key' in result ? String((result as { key?: { id?: string } }).key?.id ?? 'unknown') : 'unknown'; return { messageId }; }, sendPoll: async ( to: string, poll: { question: string; options: string[]; maxSelections?: number } ): Promise<{ messageId: string }> => { const jid = toWhatsappJid(to); const result = await params.sock.sendMessage(jid, { poll: { name: poll.question, values: poll.options, selectableCount: poll.maxSelections ?? 1, }, } as AnyMessageContent); recordChannelActivity({ channel: 'whatsapp', accountId: params.defaultAccountId, direction: 'outbound', }); const messageId = typeof result === 'object' && result && 'key' in result ? String((result as { key?: { id?: string } }).key?.id ?? 'unknown') : 'unknown'; return { messageId }; }, sendReaction: async ( chatJid: string, messageId: string, emoji: string, fromMe: boolean, participant?: string ): Promise => { const jid = toWhatsappJid(chatJid); await params.sock.sendMessage(jid, { react: { text: emoji, key: { remoteJid: jid, id: messageId, fromMe, participant: participant ? toWhatsappJid(participant) : undefined, }, }, } as AnyMessageContent); }, sendComposingTo: async (to: string): Promise => { const jid = toWhatsappJid(to); await params.sock.sendPresenceUpdate('composing', jid); }, } as const; }