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 } / ` ) ;
} ) ;