Spaces:
Paused
Paused
| 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}`); | |
| }); | |