// whatsapp.js import axios from 'axios'; import { config } from './config.js'; import { log } from './logger.js'; /* ✉️ Enviar texto -------------------------------------------------------- */ export async function sendText(to, content) { log('info', `Enviando mensaje a ${to}: "${content}"`); const { data } = await axios.post(`${config.API_URL}/sendText`, { args: { to, content } }); log('debug', 'Respuesta de /sendText →', data); return data; } /* 🗨️ Traer todos los mensajes cargados en el chat ------------------------ */ export async function fetchChatMessages(chatId) { try { const { data } = await axios.post(`${config.API_URL}/getAllMessagesInChat`, { args: { chatId, includeMe: 'true', includeNotifications: 'false' } }); return data?.response ?? []; } catch (e) { log('error', 'Fallo /getAllMessagesInChat:', e.response?.data ?? e.message); return []; } } /* ⏳ Esperar gateway ------------------------------------------------------ */ export async function waitForGateway() { for (let i = 1; i <= config.MAX_ATTEMPTS; i++) { try { await axios.get(`${config.API_URL}/api-docs`); log('info', '🟢 whatsapp-gateway listo'); return; } catch { log('warn', `Gateway no responde (intento ${i}/${config.MAX_ATTEMPTS})…`); await new Promise(r => setTimeout(r, config.RETRY_MS)); } } throw new Error('whatsapp-gateway no respondió a tiempo'); } /* 🧹 Limpiar webhooks anteriores ----------------------------------------- */ export async function clearWebhooks() { try { const { data } = await axios.post(`${config.API_URL}/listWebhooks`); const hooks = data?.response ?? []; if (!hooks.length) { log('info', 'Sin webhooks previos que limpiar'); return; } log('info', `Eliminando ${hooks.length} webhooks…`); const results = await Promise.allSettled( hooks.map(h => axios.post(`${config.API_URL}/removeWebhook`, { args: { webhookId: h.id } })) ); results.forEach((r, i) => { const id = hooks[i].id; if (r.status === 'fulfilled' && r.value?.data?.response === true) { log('debug', `✔️ Eliminado webhook ${id}`); } else { log('warn', `⚠️ Falló eliminar webhook ${id}`); } }); const ok = results.filter(r => r.status === 'fulfilled' && r.value?.data?.response === true).length; log('info', `Limpieza OK (${ok}/${hooks.length} eliminados)`); } catch (e) { log('error', 'Fallo limpiando webhooks:', e.response?.data ?? e.message); } } // --- Registro del webhook con todos los eventos disponibles ---------- export async function registerWebhook() { const url = `http://nucleo-bot:${config.PORT}/webhook`; const eventConfig = { onAck: false, // ❌ onAddedToGroup: true, onAnyMessage: true, onBattery: true, onBroadcast: true, onButton: true, onCallState: false, // ❌ onChatDeleted: true, onChatOpened: true, onChatState: true, onContactAdded: true, onGlobalParticipantsChanged: true, onGroupApprovalRequest: true, onGroupChange: true, onIncomingCall: false, // ❌ onLabel: true, onLogout: true, onMessage: false, // ❌ onMessageDeleted: true, onNewProduct: true, onOrder: true, onPlugged: false, // ❌ onPollVote: true, onReaction: true, onRemovedFromGroup: false, // ❌ onStateChanged: false, // ❌ onStory: false, // ❌ }; // usa el config de eventos para filtrar los habilitados (el config de arriba) const allEvents = Object.entries(eventConfig) .filter(([_, enabled]) => enabled) .map(([event]) => event); const { data } = await axios.post(`${config.API_URL}/registerWebhook`, { args: { url, events: allEvents, id: 'nucleo-bot' } }); log('info', '✔️ Webhook registrado:', data); } export async function setTypingStatus(chatId, status) { try { const { data } = await axios.post(`${config.API_URL}/simulateTyping`, { args: { to: chatId, on: status } }); log('debug', 'Respuesta de /setChatState →', data); } catch (e) { log('error', 'Fallo /setChatState:', e.response?.data ?? e.message); } }