You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

215 lines
8.2 KiB

const express = require('express');
const venom = require('venom-bot');
const jwt = require('jsonwebtoken');
const bcrypt = require('bcryptjs');
const app = express();
let botClient;
app.use(express.json({ limit: '10mb' }));
const { session_name, browser_args, port } = require('./config.js');
const { send_message, send_image, get_all_chats, base64ToFile } = require('./utils.js');
// Secret key for JWT
const secretKey = 'kopikopi'; // Replace with your own secret key
const users = [{ username: 'dhyn', password: '$2a$10$CgymXA8sNRdVPA6StSyOIeyvk57L.z/n22sOd37/PMwzHXnWY2Wsm' }]; // In-memory user storage (for simplicity)
venom
.create(
//session
session_name, //Pass the name of the client you want to start the bot
//catchQR
(base64Qrimg, asciiQR, attempts, urlCode) => {
console.log('Number of attempts to read the qrcode: ', attempts);
console.log('Terminal qrcode: ', asciiQR);
console.log('base64 image string qrcode: ', base64Qrimg);
console.log('urlCode (data-ref): ', urlCode);
},
// statusFind
(statusSession, session) => {
console.log('Status Session: ', statusSession); //return isLogged || notLogged || browserClose || qrReadSuccess || qrReadFail || autocloseCalled || desconnectedMobile || deleteToken || chatsAvailable || deviceNotConnected || serverWssNotConnected || noOpenBrowser || initBrowser || openBrowser || connectBrowserWs || initWhatsapp || erroPageWhatsapp || successPageWhatsapp || waitForLogin || waitChat || successChat
//Create session wss return "serverClose" case server for close
console.log('Session name: ', session);
},
// options
{
browserPathExecutable: '/usr/bin/google-chrome-stable', // browser executable path
folderNameToken: 'tokens', //folder name when saving tokens
mkdirFolderToken: '', //folder directory tokens, just inside the venom folder, example: { mkdirFolderToken: '/node_modules', } //will save the tokens folder in the node_modules directory
headless: 'new', // you should no longer use boolean false or true, now use false, true or 'new' learn more https://developer.chrome.com/articles/new-headless/
devtools: false, // Open devtools by default
debug: false, // Opens a debug session
logQR: true, // Logs QR automatically in terminal
browserWS: '', // If u want to use browserWSEndpoint
browserArgs: ['--no-sandbox', browser_args], // Original parameters ---Parameters to be added into the chrome browser instance
addBrowserArgs: [], // Add broserArgs without overwriting the project's original
puppeteerOptions: {}, // Will be passed to puppeteer.launch
disableSpins: true, // Will disable Spinnies animation, useful for containers (docker) for a better log
disableWelcome: true, // Will disable the welcoming message which appears in the beginning
updatesLog: true, // Logs info updates automatically in terminal
autoClose: 60000, // Automatically closes the venom-bot only when scanning the QR code (default 60 seconds, if you want to turn it off, assign 0 or false)
createPathFileToken: false, // creates a folder when inserting an object in the client's browser, to work it is necessary to pass the parameters in the function create browserSessionToken
addProxy: [''], // Add proxy server exemple : [e1.p.webshare.io:01, e1.p.webshare.io:01]
userProxy: '', // Proxy login username
userPass: '' // Proxy password
},
// BrowserInstance
(browser, waPage) => {
console.log('Browser PID:', browser.process().pid);
waPage.screenshot({ path: 'screenshot.png' });
}
)
.then((client) => {
botClient = client
start(client);
})
.catch((erro) => {
console.log(erro);
});
function start(client) {
client.onMessage((message) => {
if (message.body === 'Hi' && message.isGroupMsg === false) {
client
.sendText(message.from, 'Welcome!')
.then((result) => {
console.log('Result: ', result); //return object success
})
.catch((erro) => {
console.error('Error when sending: ', erro); //return object error
});
}
});
}
// Register route
// app.post('/register', async (req, res) => {
// const { username, password } = req.body;
// if (users.find(user => user.username === username)) {
// return res.status(400).json({ error: 'User already exists' });
// }
// const hashedPassword = await bcrypt.hash(password, 10);
// users.push({ username, password: hashedPassword });
// res.status(201).json({ message: 'User registered successfully' });
// });
// Login route
app.post('/login', async (req, res) => {
const { username, password } = req.body;
const user = users.find(user => user.username === username);
if (!user) {
return res.status(401).json({ error: 'Invalid credentials' });
}
const isPasswordValid = await bcrypt.compare(password, user.password);
if (!isPasswordValid) {
return res.status(401).json({ error: 'Invalid credentials' });
}
const token = jwt.sign({ username: user.username }, secretKey, { expiresIn: '1h' });
res.status(200).json({ token });
});
app.get('/', (req, res) => {
res.send('Hello World!');
});
app.get('/get-all-chats', authenticate, (req, res) => {
var result = get_all_chats(botClient);
console.log('================ /botmon/get-all-chats');
result.then(function(data) {
if (data.code === 200) {
return res.status(200).json({status: 'success', result: data.result});
} else {
return res.status(500).json({status: 'error', result: data.result});
}
});
});
app.post('/send-message', authenticate, (req, res) => {
const { to, message } = req.body;
console.log('================ /botmon/send-message');
if (!botClient) {
return res.status(500).json({ error: 'Bot is not initialized' });
}
console.log('to', to);
console.log('message', message);
var result = send_message(botClient, to, message);
result.then(function(data) {
if (data.code === 200) {
return res.status(200).json({status: 'success', result: data.result});
} else {
return res.status(500).json({status: 'error', result: data.result});
}
});
});
app.post('/send-image', authenticate, (req, res) => {
const { to, name, caption, image_data } = req.body;
console.log('================ /botmon/send-image');
if (!botClient) {
return res.status(500).json({ error: 'Bot is not initialized' });
}
const now = new Date();
const formattedDate = `${now.getFullYear()}${String(now.getMonth() + 1).padStart(2, '0')}${String(now.getDate()).padStart(2, '0')}`;
const formattedTime = `${String(now.getHours()).padStart(2, '0')}${String(now.getMinutes()).padStart(2, '0')}${String(now.getSeconds()).padStart(2, '0')}`;
const path = 'assets/images/' + name + '-' + formattedDate + formattedTime + '.png';
console.log('to', to);
console.log('name', name);
console.log('caption', caption);
const base64_image = "data:image/png;base64," + image_data
if (base64ToFile(base64_image, path) === false) {
return res.status(500).json({ error: 'Error writing image to file'});
}
var result = send_image(botClient, to, base64_image, name, caption);
result.then(function(data) {
if (data.code === 200) {
return res.status(200).json({status: 'success', result: data.result});
} else {
return res.status(500).json({status: 'error', result: data.result});
}
})
});
// Middleware to protect routes
function authenticate(req, res, next) {
const token = req.headers['authorization'];
if (!token) {
return res.status(401).json({ error: 'No token provided' });
}
jwt.verify(token, secretKey, (err, decoded) => {
if (err) {
return res.status(401).json({ error: 'Failed to authenticate token' });
}
req.user = decoded;
next();
});
}
// Start the Express server
app.listen(port, () => {
console.log(`Server running at http://localhost:${port}/`);
});