File size: 3,267 Bytes
14960b8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
// 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 };