const express = require('express'); const { Client, LocalAuth } = require('whatsapp-web.js'); const qrcode = require('qrcode-terminal'); const app = express(); const PORT = process.env.PORT || 5001; app.use(express.json()); // Initialize WhatsApp Web Client with LocalAuth to persist session const client = new Client({ authStrategy: new LocalAuth({ dataPath: './.wwebjs_auth' }), puppeteer: { headless: true, executablePath: process.env.PUPPETEER_EXECUTABLE_PATH || '/usr/bin/chromium-browser', args: [ '--no-sandbox', '--disable-setuid-sandbox', '--disable-dev-shm-usage', '--disable-accelerated-2d-canvas', '--disable-gpu', '--no-first-run', '--disable-extensions', '--disable-background-networking', '--disable-default-apps', '--disable-background-timer-throttling', '--disable-renderer-backgrounding', '--disable-backgrounding-occluded-windows' ] } }); let isReady = false; // Event: QR Code generation client.on('qr', (qr) => { console.log('\n=================================================================='); console.log('SCAN THIS QR CODE WITH YOUR WHATSAPP APP TO LOG IN:'); console.log('==================================================================\n'); qrcode.generate(qr, { small: true }); console.log('\n=================================================================='); console.log('[WhatsApp Bot] QR code generated. Waiting for scan...'); }); // Log loading progress client.on('loading_screen', (percent, message) => { console.log(`[WhatsApp Bot] Loading: ${percent}% - ${message}`); }); client.on('authenticated', () => { console.log('[WhatsApp Bot] Authenticated successfully!'); }); // Event: Successfully logged in & authenticated client.on('ready', () => { console.log('\n[WhatsApp Bot] Client is ready and authenticated!'); isReady = true; }); client.on('auth_failure', (msg) => { console.error('[WhatsApp Bot] Authentication failure:', msg); }); client.on('disconnected', (reason) => { console.log('[WhatsApp Bot] Client was logged out:', reason); isReady = false; }); // HTTP REST Endpoint to send messages app.post('/send-message', async (req, res) => { if (!isReady) { return res.status(503).json({ success: false, error: 'WhatsApp Web client is not ready. Please scan the QR code in the server terminal.' }); } const { to, message } = req.body; if (!to || !message) { return res.status(400).json({ success: false, error: "Missing 'to' or 'message' fields in JSON payload." }); } try { let targetJid = to; // 1. Check if 'to' is a WhatsApp group invite link or invite code if (to.includes('chat.whatsapp.com') || /^[A-Za-z0-9]{20,24}$/.test(to)) { let inviteCode = to; if (to.includes('chat.whatsapp.com/')) { inviteCode = to.split('chat.whatsapp.com/')[1].split('?')[0].trim(); } console.log(`[WhatsApp Bot] Attempting to join group via invite code: ${inviteCode}`); try { const groupChatId = await client.acceptInvite(inviteCode); targetJid = groupChatId; console.log(`[WhatsApp Bot] Successfully joined/resolved group. JID: ${targetJid}`); } catch (err) { console.warn(`[WhatsApp Bot] Accept invite failed (bot might already be in the group):`, err.message); // Fallback: If joining failed, attempt to find by code if we can't join return res.status(400).json({ success: false, error: `Failed to join group via invite code: ${err.message}` }); } } // 2. Format phone number to standard JID format if it is a plain phone number if (!targetJid.includes('@')) { // Strip any prefix, plus, space, parentheses, or dashes let cleanPhone = targetJid.replace('whatsapp:', '').replace(/[+\s()-]/g, '').trim(); targetJid = `${cleanPhone}@c.us`; } console.log(`[WhatsApp Bot] Sending message to target JID: ${targetJid}`); const response = await client.sendMessage(targetJid, message); res.json({ success: true, messageId: response.id._serialized, recipient: targetJid }); } catch (error) { console.error(`[WhatsApp Bot] Failed to send message:`, error); res.status(500).json({ success: false, error: error.message || error }); } }); // Health check endpoint app.get('/status', (req, res) => { res.json({ service: 'whatsapp-gateway', ready: isReady, authenticated: client.info ? true : false }); }); app.listen(PORT, () => { console.log(`[WhatsApp Bot Gateway] REST API running at http://localhost:${PORT}`); }); console.log('[WhatsApp Bot] Initializing client...'); client.initialize();