Spaces:
Building
Building
// 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 }; | |