File size: 5,030 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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
// src/connection.js
const makeWASocket = require('@whiskeysockets/baileys').default;
const { DisconnectReason, useMultiFileAuthState, fetchLatestBaileysVersion } = require('@whiskeysockets/baileys');
const logger = require('./logger');
const config = require('./config'); // Import config but botJid setting/clearing removed
const whatsapp = require('./services/whatsappService'); // Import service
const { processMessage } = require('./handlers/messageHandler'); // Import main handler
const path = require('path'); // Path is still needed for useMultiFileAuthState path construction

/**
 * Establishes the WhatsApp connection using Baileys, initializes services,
 * and sets up event listeners. Filters groups and channels. (Original Refactored Version)
 */
async function connectWhatsApp() {
    // Define auth folder path relative to src/ directory
    const authFolderPath = path.join(__dirname, '..', 'auth');
    const { state, saveCreds } = await useMultiFileAuthState(authFolderPath);
    const { version } = await fetchLatestBaileysVersion();

    logger.info(`Using Baileys version: ${version.join('.')}`);

    const sock = makeWASocket({
        printQRInTerminal: true,
        auth: state,
        version: version,
        // getMessage: async key => { }, // Define if using message store features
        logger // Pass pino logger to Baileys
    });

    // Initialize WhatsApp Service with sock instance
    whatsapp.initialize(sock);

    // Baileys Event Processing
    sock.ev.process(async (events) => {

        // ** Connection Logic **
        if (events['connection.update']) {
            // (Connection logic remains the same as previous - without auto-delete/auto-restart)
            const { connection, lastDisconnect, qr } = events['connection.update'];
            const statusCode = (lastDisconnect?.error)?.output?.statusCode;

            if (connection === 'close') {
                config.botJid = null; // Clear bot JID on close
                const shouldReconnect = statusCode !== DisconnectReason.loggedOut;
                logger.warn({ err: lastDisconnect?.error, shouldReconnect }, `Connection closed. Status Code: ${statusCode}`);
                if (shouldReconnect) {
                    logger.info("Attempting to reconnect in 5 seconds...");
                    setTimeout(connectWhatsApp, 5000);
                } else {
                    logger.error('Connection closed: Logged Out or Invalid Session. Please delete "auth" folder manually and restart.');
                    process.exit(1);
                }
            } else if (connection === 'open') {
                config.botJid = sock.user?.id;
                logger.info({ botJid: config.botJid }, 'WhatsApp connection opened and service initialized.');
                whatsapp.initialize(sock); // Re-initialize service if needed
            }
             if(qr) {
                 logger.info('QR code received, scan please!');
             }
        }

        // ** Credentials Update **
        if (events['creds.update']) {
            await saveCreds();
        }

        // ** Message Handling **
        if (events['messages.upsert']) {
            const upsert = events['messages.upsert'];
            // logger.trace({ upsert }, 'Received messages.upsert event');

            if (upsert.type === 'notify') {
                for (const msg of upsert.messages) {
                    // --- Basic Message Filtering ---
                    // Ignore messages without content, from self, or status broadcasts
                    if (!msg.message || msg.key.fromMe || msg.key.remoteJid === 'status@broadcast') {
                        // logger.trace({ msgId: msg.key.id }, 'Ignoring message (no content, fromMe, or status broadcast)');
                        continue;
                    }
                    // Ignore group messages
                    if (msg.key.remoteJid.endsWith('@g.us')) {
                        // logger.trace({ msgId: msg.key.id, group: msg.key.remoteJid }, 'Ignoring group message');
                        continue;
                    }
                    // *** ADDED: Ignore channel messages ***
                    if (msg.key.remoteJid.endsWith('@newsletter')) {
                        logger.trace({ msgId: msg.key.id, channel: msg.key.remoteJid }, 'Ignoring channel message');
                        continue;
                    }
                    // *** END ADDED FILTER ***

                    // Delegate processing asynchronously for valid user messages
                    setImmediate(() => {
                         processMessage(msg).catch(err => {
                            logger.error({ err, msgId: msg?.key?.id }, "Error caught in setImmediate for processMessage");
                         });
                    });

                } // end for loop
            } // end if notify
        } // end messages.upsert

    }); // End sock.ev.process

    return sock;
} // End connectWhatsApp

module.exports = { connectWhatsApp };