// auth.*, daemon.*, events.*: they work even when the session is not ready. import { WaError } from '../rpc.js'; export const EVENTS = [ 'qr', 'code', 'authenticated', 'auth_failure', 'ready', 'disconnected', 'change_state', 'loading_screen', 'message', 'message_create', 'message_ack', 'message_edit', 'message_revoke_everyone', 'message_revoke_me', 'message_reaction', 'media_uploaded', 'unread_count', 'chat_archived', 'chat_removed', 'contact_changed', 'group_join', 'group_leave', 'group_update', 'group_admin_changed', 'group_membership_request', 'call', 'vote_update', ]; export default { 'auth.status': { description: 'WhatsApp session state (qr, code, authenticated, ready, ...) and linked account.', ready: false, handler: async (ctx) => ctx.status(), }, 'auth.pair': { description: 'Requests a pairing code by phone number (alternative to the QR). ' + 'Enter it on the phone: Linked devices > Link with phone number instead.', ready: false, params: { phone: { type: 'string', required: true, description: 'Number in international format, digits only (e.g. 5491122334455)' }, notify: { type: 'boolean', default: true, description: 'Show a notification on the phone' }, }, handler: async (ctx, p) => { const st = ctx.status().state; if (st === 'ready' || st === 'authenticated') { throw new WaError('EINVAL', 'the session is already linked'); } await ctx.waitState(['qr', 'code'], 60000); const code = await ctx.client.requestPairingCode(p.phone.replace(/\D/g, ''), p.notify); return { code }; }, }, 'auth.logout': { description: 'Logs out (unlinks this device) and deletes the local session.', handler: async (ctx) => { await ctx.client.logout(); return { ok: true }; }, }, 'daemon.status': { description: 'Daemon process information.', ready: false, handler: async (ctx) => ctx.daemonInfo(), }, 'daemon.stop': { description: 'Stops the daemon (closes the browser; the session stays saved).', ready: false, handler: async (ctx) => { setImmediate(() => ctx.shutdown('daemon.stop')); return { ok: true }; }, }, 'events.watch': { description: 'Real-time event stream (NDJSON). Each event: {event, account, time, data}.', ready: false, stream: true, params: { events: { type: 'array', default: ['message'], description: `Eventos a escuchar, o ["all"]. Disponibles: ${EVENTS.join(', ')}` }, replay: { type: 'boolean', default: false, description: 'On connect, resend the current state (last qr/code, ready)' }, }, handler: async (ctx, p, conn) => { const unknown = p.events.filter((e) => e !== 'all' && !EVENTS.includes(e)); if (unknown.length) throw new WaError('EINVAL', `eventos desconocidos: ${unknown.join(', ')}`); ctx.subscribe(conn, p.events.includes('all') ? null : new Set(p.events), p.replay); return ctx.STREAM; }, }, };