import * as ser from '../serialize.js'; const chatParam = { type: 'chat', required: true, description: 'Chat: JID (549...@c.us, ...@g.us), phone number or exact name' }; const simple = (description, fn) => ({ description, params: { chatId: chatParam }, handler: async (ctx, p) => fn(ctx, p.chatId), }); export default { 'chats.list': { description: 'Lists chats, most recent first.', params: { unread: { type: 'boolean', description: 'Only chats with unread messages' }, archived: { type: 'boolean', description: 'true: archived only; false: unarchived only' }, groups: { type: 'boolean', description: 'true: solo grupos; false: solo individuales' }, query: { type: 'string', description: 'Filters by name (case- and accent-insensitive)' }, limit: { type: 'integer', description: 'Maximum number of chats to return' }, }, columns: ['id', 'name', 'unreadCount', 'date', 'lastMessage.body'], handler: async (ctx, p) => { const norm = ctx.normalize; let chats = (await ctx.client.getChats()) .filter((c) => p.unread === undefined || (c.unreadCount > 0) === p.unread) .filter((c) => p.archived === undefined || Boolean(c.archived) === p.archived) .filter((c) => p.groups === undefined || Boolean(c.isGroup) === p.groups) .filter((c) => !p.query || norm(c.name || '').includes(norm(p.query))) .sort((a, b) => (b.timestamp ?? 0) - (a.timestamp ?? 0)); if (p.limit) chats = chats.slice(0, p.limit); return chats.map((c) => ser.chat(c, ctx.ser)); }, }, 'chats.get': { description: 'Details of a chat (includes participants for groups).', params: { chatId: chatParam }, handler: async (ctx, p) => { const c = await ctx.getChat(p.chatId); const out = ser.chat(c, ctx.ser); if (c.isGroup) Object.assign(out, ser.group(c, ctx.ser)); return out; }, }, 'chats.resolve': { description: 'Resolves a JID, number or name to a chatId (useful in scripts).', params: { query: { type: 'string', required: true, description: 'JID, number or name' } }, handler: async (ctx, p) => { const id = await ctx.resolveChat(p.query); return { id, name: ctx.names(id) ?? null }; }, }, 'chats.read': simple('Marks the chat as read (sends read receipts).', async (ctx, id) => ({ ok: await ctx.client.sendSeen(id), })), 'chats.unread': simple('Marks the chat as unread.', async (ctx, id) => { await ctx.client.markChatUnread(id); return { ok: true }; }), 'chats.archive': simple('Archives the chat.', async (ctx, id) => ({ archived: await ctx.client.archiveChat(id) })), 'chats.unarchive': simple('Unarchives the chat.', async (ctx, id) => ({ archived: await ctx.client.unarchiveChat(id) })), 'chats.pin': simple('Pins the chat.', async (ctx, id) => ({ pinned: await ctx.client.pinChat(id) })), 'chats.unpin': simple('Unpins the chat.', async (ctx, id) => ({ pinned: await ctx.client.unpinChat(id) })), 'chats.unmute': simple('Unmutes the chat.', async (ctx, id) => ctx.client.unmuteChat(id)), 'chats.sync': simple('Asks the phone for the chat history (for chats with few loaded messages).', async (ctx, id) => ({ ok: await ctx.client.syncHistory(id) })), 'chats.mute': { description: 'Mutes the chat, forever or until a date.', params: { chatId: chatParam, until: { type: 'string', description: 'ISO 8601 date or epoch seconds; omitted = forever' }, }, handler: async (ctx, p) => { let date; if (p.until) { date = /^\d+$/.test(p.until) ? new Date(Number(p.until) * 1000) : new Date(p.until); if (Number.isNaN(date.getTime())) throw new ctx.WaError('EINVAL', `invalid date: ${p.until}`); } return ctx.client.muteChat(p.chatId, date); }, }, };