Spaces:
Paused
Paused
| // src/services/whatsappService.js | |
| const { randomDelay, sleep } = require('../utils'); | |
| const logger = require('../logger'); | |
| const config = require('../config'); | |
| let sockInstance = null; | |
| /** | |
| * Initializes the WhatsApp Service with the Baileys socket instance. | |
| * Should be called once after connection is established. | |
| * @param {object} sock - The Baileys socket instance. | |
| */ | |
| function initialize(sock) { | |
| if (!sockInstance) { | |
| sockInstance = sock; | |
| logger.info('WhatsApp Service Initialized.'); | |
| } | |
| } | |
| /** | |
| * Sends a presence update (typing, paused, available, unavailable). | |
| * @param {'composing' | 'paused' | 'available' | 'unavailable'} status - The presence status. | |
| * @param {string} jid - The target JID. | |
| */ | |
| async function sendPresenceUpdate(status, jid) { | |
| if (!sockInstance) return logger.error('WhatsApp Service not initialized for sendPresenceUpdate'); | |
| try { | |
| await sockInstance.sendPresenceUpdate(status, jid); | |
| } catch (err) { | |
| logger.error({ err, jid, status }, '[WhatsAppService] Failed to send presence update'); | |
| } | |
| } | |
| /** | |
| * Marks specific messages as read. | |
| * @param {Array<object>} keys - An array of message key objects. | |
| */ | |
| async function readReceipt(keys) { | |
| if (!sockInstance) return logger.error('WhatsApp Service not initialized for readReceipt'); | |
| try { | |
| await sockInstance.readMessages(keys); | |
| // Log the first key for brevity if needed | |
| if (keys && keys[0]) { | |
| logger.debug({ jid: keys[0].remoteJid, msgId: keys[0].id }, `[WhatsAppService] Marked message(s) as read`); | |
| } | |
| } catch (err) { | |
| const jid = keys && keys[0] ? keys[0].remoteJid : 'unknown'; | |
| logger.warn({ err, jid }, '[WhatsAppService] Failed to mark message(s) as read'); | |
| } | |
| } | |
| /** | |
| * Sends a message with simulated typing and random delay. | |
| * @param {string} jid - The target JID. | |
| * @param {object} message - The Baileys message object (e.g., { text: 'Hello' }). | |
| * @param {object} [options={}] - Options object. | |
| * @param {number} [options.minDelay] - Minimum delay (defaults to config.defaultMinDelay). | |
| * @param {number} [options.maxDelay] - Maximum delay (defaults to config.defaultMaxDelay). | |
| * @returns {Promise<object|null>} - The result from Baileys sendMessage or null on init error. | |
| */ | |
| async function sendMessageWithTyping(jid, message, options = {}) { | |
| if (!sockInstance) { | |
| logger.error({ jid, message }, 'WhatsApp Service not initialized for sendMessage'); | |
| return null; // Indicate failure | |
| } | |
| // Use provided delays or fall back to config defaults | |
| const minDelayMs = options.minDelay ?? config.defaultMinDelay; | |
| const maxDelayMs = options.maxDelay ?? config.defaultMaxDelay; | |
| try { | |
| await sendPresenceUpdate('composing', jid); | |
| await randomDelay(minDelayMs, maxDelayMs); | |
| await sendPresenceUpdate('paused', jid); // Clear composing state before sending | |
| const result = await sockInstance.sendMessage(jid, message); | |
| logger.debug({ jid, msgContent: message.text || '[Non-Text]' }, '[WhatsAppService] Message sent'); | |
| return result; | |
| } catch (err) { | |
| logger.error({ err, jid, msgContent: message.text || '[Non-Text]' }, '[WhatsAppService] Failed to send message'); | |
| // Re-throw error for the calling handler to potentially manage | |
| // Avoid sending another message from here to prevent loops | |
| throw err; | |
| } | |
| } | |
| module.exports = { | |
| initialize, | |
| sendMessageWithTyping, | |
| readReceipt, | |
| // Only export specific actions needed by handlers | |
| }; | |