// src/handlers/messageHandler.js const logger = require('../logger'); const config = require('../config'); const whatsapp = require('../services/whatsappService'); const { User } = require('../database'); const { handleAdminCommand } = require('./adminHandler'); const { handleRegistration } = require('./registrationHandler'); const { handleRegisteredUser } = require('./registeredUserHandler'); /** * Processes an incoming message, filters, marks as read (non-blocking), * and routes to the appropriate handler. * @param {object} msg - The Baileys message object. */ async function processMessage(msg) { // Define jid early for potential use in top-level catch const jid = msg?.key?.remoteJid || 'unknown'; try { const messageContent = msg.message?.conversation || msg.message?.extendedTextMessage?.text || ''; // Ignore empty text messages if (!messageContent.trim() && !msg.message?.buttonsResponseMessage) { logger.trace({ jid }, "[MessageHandler] Ignoring empty message content."); return; } // --- Mark as Read (Fire-and-Forget) --- // Call readReceipt WITHOUT 'await'. This lets the function run // in the background without blocking further execution. // If it times out, it will log a warning (due to the try/catch // inside whatsappService.readReceipt) but won't crash the app here. whatsapp.readReceipt([msg.key]); // --- End Mark as Read --- // --- Routing --- logger.info({ jid, msg: messageContent }, `[MessageHandler] Processing received message`); // 1. Check if Admin Command if (config.adminJids.length > 0 && config.adminJids.includes(jid)) { const commandHandled = await handleAdminCommand(jid, messageContent); if (commandHandled) { logger.info({ jid, msg: messageContent }, `[MessageHandler] Admin command handled.`); return; // Stop processing } logger.debug({ jid }, "[MessageHandler] Message from admin JID not a known admin command, proceeding."); } // 2. Check DB for User Status let dbUser = await User.findOne({ remoteJid: jid }); // 3. Route to appropriate handler if (dbUser && dbUser.isRegistered) { logger.debug({ jid }, "[MessageHandler] Routing to RegisteredUserHandler."); await handleRegisteredUser(jid, messageContent, dbUser); } else { logger.debug({ jid }, "[MessageHandler] Routing to RegistrationHandler."); await handleRegistration(jid, messageContent); } } catch (error) { // Catch errors from DB check or handler execution logger.error({ jid, err: error }, `[MessageHandler] Error processing message`); try { // Use default delay for error message if (jid !== 'unknown') { await whatsapp.sendMessageWithTyping(jid, { text: "Sorry, an internal error occurred. Please try again." }); } } catch (sendError) { logger.error({ jid, err: sendError }, `[MessageHandler] CRITICAL: Failed to send error notification`); } } } module.exports = { processMessage };