// BACKEND DA API
// BIBLIOTECAS UTILIZADAS PARA COMPOSIĂĂO DA API
const { Client, LocalAuth, MessageMedia } = require('whatsapp-web.js');
const express = require('express');
const socketIO = require('socket.io');
const qrcode = require('qrcode');
const http = require('http');
const fileUpload = require('express-fileupload');
const { body, validationResult } = require('express-validator');
const app = express();
const server = http.createServer(app);
const io = socketIO(server);
// PORTA ONDE O SERVIĂO SERĂ INICIADO
const port = 8001;
const idClient = 'bot-zdg-maratona-grupos';
// NUMEROS AUTORIZADOS
const permissaoBot = ["DDIdddXXXXXXXX@c.us"];
// SERVIĂO EXPRESS
app.use(express.json());
app.use(express.urlencoded({
extended: true
}));
app.use(fileUpload({
debug: true
}));
app.use("/", express.static(__dirname + "/"))
app.get('/', (req, res) => {
res.sendFile('index.html', {
root: __dirname
});
});
// PARĂMETROS DO CLIENT DO WPP
const client = new Client({
authStrategy: new LocalAuth({ clientId: idClient }),
puppeteer: { headless: true,
// CAMINHO DO CHROME PARA WINDOWS (REMOVER O COMENTĂRIO ABAIXO)
// executablePath: 'C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe',
//===================================================================================
// CAMINHO DO CHROME PARA MAC (REMOVER O COMENTĂRIO ABAIXO)
//executablePath: '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome',
//===================================================================================
// CAMINHO DO CHROME PARA LINUX (REMOVER O COMENTĂRIO ABAIXO)
//executablePath: '/usr/bin/google-chrome-stable',
//===================================================================================
args: [
'--no-sandbox',
'--disable-setuid-sandbox',
'--disable-dev-shm-usage',
'--disable-accelerated-2d-canvas',
'--no-first-run',
'--no-zygote',
'--single-process', // <- this one doesn't works in Windows
'--disable-gpu'
] }
});
// INITIALIZE DO CLIENT DO WPP
client.initialize();
// EVENTOS DE CONEXĂO EXPORTADOS PARA O INDEX.HTML VIA SOCKET
io.on('connection', function(socket) {
socket.emit('message', '© BOT-ZDG - Iniciado');
socket.emit('qr', './icon.svg');
client.on('qr', (qr) => {
console.log('QR RECEIVED', qr);
qrcode.toDataURL(qr, (err, url) => {
socket.emit('qr', url);
socket.emit('message', '© BOT-ZDG QRCode recebido, aponte a cùmera seu celular!');
});
});
client.on('ready', async () => {
socket.emit('ready', '© BOT-ZDG Dispositivo pronto!');
socket.emit('message', '© BOT-ZDG Dispositivo pronto!');
socket.emit('qr', './check.svg')
console.log('© BOT-ZDG Dispositivo pronto');
const groups = await client.getChats()
for (const group of groups){
if(group.id.server.includes('g.us')){
socket.emit('message', 'Nome: ' + group.name + ' - ID: ' + group.id._serialized.split('@')[0]);
console.log('Nome: ' + group.name + ' - ID: ' + group.id._serialized.split('@')[0])
}
}
});
client.on('authenticated', () => {
socket.emit('authenticated', '© BOT-ZDG Autenticado!');
socket.emit('message', '© BOT-ZDG Autenticado!');
console.log('© BOT-ZDG Autenticado');
});
client.on('auth_failure', function() {
socket.emit('message', '© BOT-ZDG Falha na autenticação, reiniciando...');
console.error('© BOT-ZDG Falha na autenticação');
});
client.on('change_state', state => {
console.log('© BOT-ZDG Status de conexão: ', state );
});
client.on('disconnected', (reason) => {
socket.emit('message', '© BOT-ZDG Cliente desconectado!');
console.log('© BOT-ZDG Cliente desconectado', reason);
client.initialize();
});
});
// POST text-message
app.post('/text-message', [
body('group').notEmpty(),
body('message').notEmpty(),
], async (req, res) => {
const errors = validationResult(req).formatWith(({
msg
}) => {
return msg;
});
if (!errors.isEmpty()) {
return res.status(422).json({
status: false,
message: errors.mapped()
});
}
const group = req.body.group + "@g.us";
const message = req.body.message;
try {
client.sendMessage(group, message).then(response => {
res.status(200).json({
status: true,
message: 'Mensagem enviada',
response: response
});
}).catch(e => {
res.status(500).json({
status: false,
message: 'Mensagem nĂŁo enviada',
response: e
});
});
} catch(e) {
console.log('Erro: ' + e)
}
});
// POST media-message-url
app.post('/media-message-url', [
body('group').notEmpty(),
body('caption').notEmpty(),
body('url').notEmpty(),
], async (req, res) => {
const errors = validationResult(req).formatWith(({
msg
}) => {
return msg;
});
if (!errors.isEmpty()) {
return res.status(422).json({
status: false,
message: errors.mapped()
});
}
const group = req.body.group + "@g.us";
const cap = req.body.caption;
const media = await MessageMedia.fromUrl(req.body.url);
try {
client.sendMessage(group, media, {caption: cap}).then(response => {
res.status(200).json({
status: true,
message: 'Mensagem enviada',
response: response
});
}).catch(e => {
res.status(500).json({
status: false,
message: 'Mensagem nĂŁo enviada',
response: e
});
});
} catch(e) {
console.log('Erro: ' + e)
}
});
// POST media-message-path
app.post('/media-message-path', [
body('group').notEmpty(),
body('caption').notEmpty(),
body('path').notEmpty(),
], async (req, res) => {
const errors = validationResult(req).formatWith(({
msg
}) => {
return msg;
});
if (!errors.isEmpty()) {
return res.status(422).json({
status: false,
message: errors.mapped()
});
}
const group = req.body.group + "@g.us";
const cap = req.body.caption;
const media = MessageMedia.fromFilePath(req.body.path);
try {
client.sendMessage(group, media, {caption: cap}).then(response => {
res.status(200).json({
status: true,
message: 'Mensagem enviada',
response: response
});
}).catch(e => {
res.status(500).json({
status: false,
message: 'Mensagem nĂŁo enviada',
response: e
});
});
} catch(e) {
console.log('Erro: ' + e)
}
});
// POST record-url
app.post('/record-url', [
body('group').notEmpty(),
body('url').notEmpty(),
], async (req, res) => {
const errors = validationResult(req).formatWith(({
msg
}) => {
return msg;
});
if (!errors.isEmpty()) {
return res.status(422).json({
status: false,
message: errors.mapped()
});
}
const group = req.body.group + "@g.us";
const media = await MessageMedia.fromUrl(req.body.url);
try {
client.sendMessage(group, media, {sendAudioAsVoice: true}).then(response => {
res.status(200).json({
status: true,
message: 'Mensagem enviada',
response: response
});
}).catch(e => {
res.status(500).json({
status: false,
message: 'Mensagem nĂŁo enviada',
response: e
});
});
} catch(e) {
console.log('Erro: ' + e)
}
});
// POST record-path
app.post('/record-path', [
body('group').notEmpty(),
body('path').notEmpty(),
], async (req, res) => {
const errors = validationResult(req).formatWith(({
msg
}) => {
return msg;
});
if (!errors.isEmpty()) {
return res.status(422).json({
status: false,
message: errors.mapped()
});
}
const group = req.body.group + "@g.us";
const media = MessageMedia.fromFilePath(req.body.path);
try {
client.sendMessage(group, media, {sendAudioAsVoice: true}).then(response => {
res.status(200).json({
status: true,
message: 'Mensagem enviada',
response: response
});
}).catch(e => {
res.status(500).json({
status: false,
message: 'Mensagem nĂŁo enviada',
response: e
});
});
} catch(e) {
console.log('Erro: ' + e)
}
});
// POST add-user
app.post('/add-user', [
body('user').notEmpty(),
body('group').notEmpty(),
], async (req, res) => {
const errors = validationResult(req).formatWith(({
msg
}) => {
return msg;
});
if (!errors.isEmpty()) {
return res.status(422).json({
status: false,
message: errors.mapped()
});
}
const user = req.body.user.replace(/\D/g,'');
const group = req.body.group + "@g.us";
try {
const chat = await client.getChatById(group);
console.log('Adicionando ' + user + ' ao grupo ' + group)
const numberDDI = user.substr(0, 2);
const numberDDD = user.substr(2, 2);
const numberUser = user.substr(-8, 8);
if (numberDDI !== "55") {
const numberZDG = user + "@c.us";
await chat.addParticipants([numberZDG])
}
else if (numberDDI === "55" && parseInt(numberDDD) <= 30) {
const numberZDG = "55" + numberDDD + "9" + numberUser + "@c.us";
await chat.addParticipants([numberZDG])
}
else if (numberDDI === "55" && parseInt(numberDDD) > 30) {
const numberZDG = "55" + numberDDD + numberUser + "@c.us";
await chat.addParticipants([numberZDG])
}
return res.status(200).json({
status: true,
message: 'BOT-ZDG: ' + user + ' adicionado',
});
} catch(e){
res.status(500).json({
status: false,
message: 'UsuĂĄrio nĂŁo adicionado.',
response: e
});
}
});
// POST remove-user
app.post('/remove-user', [
body('user').notEmpty(),
body('group').notEmpty(),
], async (req, res) => {
const errors = validationResult(req).formatWith(({
msg
}) => {
return msg;
});
if (!errors.isEmpty()) {
return res.status(422).json({
status: false,
message: errors.mapped()
});
}
const user = req.body.user.replace(/\D/g,'');
const group = req.body.group + "@g.us";
try {
const chat = await client.getChatById(group);
console.log('Adicionando ' + user + ' ao grupo ' + group)
const numberDDI = user.substr(0, 2);
const numberDDD = user.substr(2, 2);
const numberUser = user.substr(-8, 8);
if (numberDDI !== "55") {
const numberZDG = user + "@c.us";
await chat.removeParticipants([numberZDG])
}
else if (numberDDI === "55" && parseInt(numberDDD) <= 30) {
const numberZDG = "55" + numberDDD + "9" + numberUser + "@c.us";
await chat.removeParticipants([numberZDG])
}
else if (numberDDI === "55" && parseInt(numberDDD) > 30) {
const numberZDG = "55" + numberDDD + numberUser + "@c.us";
await chat.removeParticipants([numberZDG])
}
return res.status(200).json({
status: true,
message: 'BOT-ZDG: ' + user + ' removido',
});
} catch(e){
res.status(500).json({
status: false,
message: 'UsuĂĄrio nĂŁo adicionado.',
response: e
});
}
});
// INITIALIZE DO SERVIĂO
server.listen(port, function() {
console.log('© Comunidade ZDG - Aplicativo rodando na porta *: ' + port);
});