const express = require('express'); const fs = require('fs'); const path = require('path'); const qri = require('qr-image'); const { default: makeWASocket, useMultiFileAuthState, DisconnectReason, proto, generateWAMessageFromContent, prepareWAMessageMedia } = require('@whiskeysockets/baileys'); const Boom = require('@hapi/boom'); const app = express(); app.use(express.json()); const sessionDir = path.join(__dirname, 'sessions'); // Function to generate API key function generateApiKey() { return Math.random().toString(36).substr(2, 16); } // Function to validate IP address format and ensure it's not a private or reserved IP function isValidIp(ip) { const ipv4Regex = /^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/; if (!ipv4Regex.test(ip)) return false; const octets = ip.split('.').map(Number); return !( (octets[0] === 10) || (octets[0] === 172 && octets[1] >= 16 && octets[1] <= 31) || (octets[0] === 192 && octets[1] === 168) || (ip === '127.0.0.1') ); } // Handle checkState request app.get('/checkState', async (req, res) => { const { ip } = req.query; if (ip && isValidIp(ip)) { const sessionFile = path.join(sessionDir, `${ip}.json`); let apiKey; if (fs.existsSync(sessionFile)) { const sessionData = JSON.parse(fs.readFileSync(sessionFile, 'utf8')); apiKey = sessionData.apiKey; } else { apiKey = generateApiKey(); if (!fs.existsSync(sessionDir)) { fs.mkdirSync(sessionDir, { recursive: true }); } const sessionData = { ip, apiKey }; fs.writeFileSync(sessionFile, JSON.stringify(sessionData, null, 2)); connectToWhatsApp(apiKey, ip); // Start WhatsApp connection } res.cookie('apiKey', apiKey, { maxAge: 365 * 24 * 60 * 60 * 1000, httpOnly: false, sameSite: 'None', secure: true }); res.status(200).json({ message: 'Server is running successfully', server: 'running', apiKey: apiKey }); } else { res.status(401).json({ message: 'Invalid IP' }); } }); app.get('/qrCode', (req, res) => { const { apiKey } = req.query; if (apiKey) { const qrFile = path.join(sessionDir, `${apiKey}_qr.svg`); if (fs.existsSync(qrFile)) { res.sendFile(qrFile); } else { res.status(404).send('QR code not found'); } } else { res.status(400).send('API key is required'); } }); // Handle user credentials storage app.post('/storeCredentials', (req, res) => { const { apiKey, credentials } = req.body; if (!apiKey || !credentials) { return res.status(400).json({ message: 'API key and credentials are required' }); } const credentialsDir = path.join(sessionDir, apiKey); const credentialsFile = path.join(credentialsDir, 'creds.json'); if (!fs.existsSync(credentialsDir)) { fs.mkdirSync(credentialsDir, { recursive: true }); } fs.writeFileSync(credentialsFile, JSON.stringify(credentials, null, 2)); res.status(200).json({ message: 'Credentials stored successfully' }); }); // Serve login page app.use(express.static(path.join(__dirname, 'public'))); async function connectToWhatsApp(apiKey, ip) { const { state, saveCreds } = await useMultiFileAuthState(path.join(sessionDir, apiKey)); const sock = makeWASocket({ auth: state, printQRInTerminal: true }); sock.ev.on('connection.update', async (update) => { const { connection, lastDisconnect, qr } = update; if (connection === 'close') { const shouldReconnect = (lastDisconnect.error instanceof Boom) ? lastDisconnect.error.output.statusCode !== DisconnectReason.loggedOut : true; console.log('Connection closed due to', lastDisconnect.error, ', reconnecting', shouldReconnect); if (shouldReconnect) { connectToWhatsApp(apiKey, ip); } } else if (connection === 'open') { console.log('Connected to WhatsApp'); } else if (qr) { // Generate QR code and save to file const qrImage = qri.imageSync(qr, { type: 'svg' }); fs.writeFileSync(path.join(sessionDir, `${apiKey}_qr.svg`), qrImage); } }); sock.ev.on('messages.upsert', async (m) => { console.log(JSON.stringify(m, undefined, 2)); if (m.messages && m.messages.length > 0) { const message = m.messages[0]; const text = message.message?.conversation || ''; console.log('Received message:', text); await sock.sendMessage(message.key.remoteJid, { text: 'Hello there!' }); } }); // Save session to file fs.writeFileSync(path.join(sessionDir, `${ip}.json`), JSON.stringify({ apiKey, ip, session: sock.state }, null, 2)); } const PORT = 7860; app.listen(PORT, () => { console.log(`Server is running on port ${PORT}`); });