mirror of
https://github.com/cheveguerra/bot-whatsapp.git
synced 2026-04-18 03:29:15 +00:00
307 lines
8.2 KiB
JavaScript
307 lines
8.2 KiB
JavaScript
/**
|
|
* ⚡⚡⚡ DECLARAMOS LAS LIBRERIAS y CONSTANTES A USAR! ⚡⚡⚡
|
|
*/
|
|
const fs = require('fs');
|
|
const mimeDb = require('mime-db')
|
|
const express = require('express');
|
|
const moment = require('moment');
|
|
const ora = require('ora');
|
|
const chalk = require('chalk');
|
|
const ExcelJS = require('exceljs');
|
|
const qrcode = require('qrcode-terminal');
|
|
const { flowConversation } = require('./conversation')
|
|
const { Client, MessageMedia } = require('whatsapp-web.js');
|
|
const app = express();
|
|
app.use(express.urlencoded({ extended: true }))
|
|
const SESSION_FILE_PATH = './session.json';
|
|
let client;
|
|
let sessionData;
|
|
|
|
/**
|
|
* Guardamos archivos multimedia que nuestro cliente nos envie!
|
|
* @param {*} media
|
|
*/
|
|
const saveMedia = (media) => {
|
|
|
|
const extensionProcess = mimeDb[media.mimetype]
|
|
const ext = extensionProcess.extensions[0]
|
|
fs.writeFile(`./media/${media.filename}.${ext}`, media.data, { encoding: 'base64' }, function (err) {
|
|
console.log('** Archivo Media Guardado **');
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Enviamos archivos multimedia a nuestro cliente
|
|
* @param {*} number
|
|
* @param {*} fileName
|
|
*/
|
|
const sendMedia = (number, fileName) => {
|
|
number = number.replace('@c.us', '');
|
|
number = `${number}@c.us`
|
|
const media = MessageMedia.fromFilePath(`./mediaSend/${fileName}`);
|
|
client.sendMessage(number, media);
|
|
}
|
|
|
|
/**
|
|
* Enviamos un mensaje simple (texto) a nuestro cliente
|
|
* @param {*} number
|
|
*/
|
|
const sendMessage = (number = null, text = null) => {
|
|
number = number.replace('@c.us', '');
|
|
number = `${number}@c.us`
|
|
const message = text || `Hola soy un BOT recuerda https://www.youtube.com/leifermendez`;
|
|
client.sendMessage(number, message);
|
|
readChat(number, message)
|
|
console.log(`${chalk.red('⚡⚡⚡ Enviando mensajes....')}`);
|
|
}
|
|
|
|
/**
|
|
* Escuchamos cuando entre un mensaje
|
|
*/
|
|
const listenMessage = () => {
|
|
client.on('message', async msg => {
|
|
const { from, to, body } = msg;
|
|
//34691015468@c.us
|
|
console.log(msg.hasMedia);
|
|
if (msg.hasMedia) {
|
|
const media = await msg.downloadMedia();
|
|
saveMedia(media);
|
|
// do something with the media data here
|
|
}
|
|
|
|
await greetCustomer(from);
|
|
|
|
console.log(body);
|
|
|
|
await replyAsk(from, body);
|
|
|
|
// await readChat(from, body)
|
|
// console.log(`${chalk.red('⚡⚡⚡ Enviando mensajes....')}`);
|
|
// console.log('Guardar este número en tu Base de Datos:', from);
|
|
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Response a pregunta
|
|
*/
|
|
|
|
const replyAsk = (from, answer) => new Promise((resolve, reject) => {
|
|
console.log(`---------->`, answer);
|
|
if (answer === 'Quieromeme') {
|
|
sendMedia(from, 'meme-1.png')
|
|
resolve(true)
|
|
}
|
|
|
|
})
|
|
|
|
/**
|
|
* Revisamos si tenemos credenciales guardadas para inciar sessio
|
|
* este paso evita volver a escanear el QRCODE
|
|
*/
|
|
const withSession = () => {
|
|
// Si exsite cargamos el archivo con las credenciales
|
|
const spinner = ora(`Cargando ${chalk.yellow('Validando session con Whatsapp...')}`);
|
|
sessionData = require(SESSION_FILE_PATH);
|
|
spinner.start();
|
|
client = new Client({
|
|
session: sessionData
|
|
});
|
|
|
|
client.on('ready', () => {
|
|
console.log('Client is ready!');
|
|
spinner.stop();
|
|
|
|
// sendMessage();
|
|
// sendMedia();
|
|
|
|
connectionReady();
|
|
|
|
});
|
|
|
|
|
|
|
|
client.on('auth_failure', () => {
|
|
spinner.stop();
|
|
console.log('** Error de autentificacion vuelve a generar el QRCODE (Borrar el archivo session.json) **');
|
|
})
|
|
|
|
|
|
client.initialize();
|
|
}
|
|
|
|
/**
|
|
* Generamos un QRCODE para iniciar sesion
|
|
*/
|
|
const withOutSession = () => {
|
|
console.log('No tenemos session guardada');
|
|
client = new Client();
|
|
client.on('qr', qr => {
|
|
qrcode.generate(qr, { small: true });
|
|
});
|
|
|
|
client.on('ready', () => {
|
|
console.log('Client is ready!');
|
|
connectionReady();
|
|
});
|
|
|
|
client.on('auth_failure', () => {
|
|
console.log('** Error de autentificacion vuelve a generar el QRCODE **');
|
|
})
|
|
|
|
|
|
client.on('authenticated', (session) => {
|
|
// Guardamos credenciales de de session para usar luego
|
|
sessionData = session;
|
|
fs.writeFile(SESSION_FILE_PATH, JSON.stringify(session), function (err) {
|
|
if (err) {
|
|
console.log(err);
|
|
}
|
|
});
|
|
});
|
|
|
|
client.initialize();
|
|
}
|
|
|
|
const connectionReady = () => {
|
|
listenMessage();
|
|
readExcel();
|
|
}
|
|
|
|
/**
|
|
* Difundir mensaje a clientes
|
|
*/
|
|
const readExcel = async () => {
|
|
const pathExcel = `./chats/clientes-saludar.xlsx`;
|
|
const workbook = new ExcelJS.Workbook();
|
|
await workbook.xlsx.readFile(pathExcel);
|
|
const worksheet = workbook.getWorksheet(1);
|
|
const columnNumbers = worksheet.getColumn('A');
|
|
columnNumbers.eachCell((cell, rowNumber) => {
|
|
const numberCustomer = cell.value
|
|
|
|
const columnDate = worksheet.getRow(rowNumber);
|
|
let prevDate = columnDate.getCell(2).value;
|
|
prevDate = moment.unix(prevDate);
|
|
const diffMinutes = moment().diff(prevDate, 'minutes');
|
|
|
|
// Si ha pasado mas de 60 minuitos podemos enviar nuevamente
|
|
if (diffMinutes > 60) {
|
|
sendMessage(numberCustomer)
|
|
columnDate.getCell(2).value = moment().format('X')
|
|
columnDate.commit();
|
|
|
|
}
|
|
});
|
|
|
|
workbook.xlsx.writeFile(pathExcel);
|
|
|
|
}
|
|
|
|
|
|
/**
|
|
* Guardar historial de conversacion
|
|
* @param {*} number
|
|
* @param {*} message
|
|
*/
|
|
const readChat = async (number, message) => {
|
|
const pathExcel = `./chats/${number}.xlsx`;
|
|
const workbook = new ExcelJS.Workbook();
|
|
const today = moment().format('DD-MM-YYYY hh:mm')
|
|
|
|
if (fs.existsSync(pathExcel)) {
|
|
/**
|
|
* Si existe el archivo de conversacion lo actualizamos
|
|
*/
|
|
const workbook = new ExcelJS.Workbook();
|
|
workbook.xlsx.readFile(pathExcel)
|
|
.then(() => {
|
|
const worksheet = workbook.getWorksheet(1);
|
|
const lastRow = worksheet.lastRow;
|
|
var getRowInsert = worksheet.getRow(++(lastRow.number));
|
|
getRowInsert.getCell('A').value = today;
|
|
getRowInsert.getCell('B').value = message;
|
|
getRowInsert.commit();
|
|
workbook.xlsx.writeFile(pathExcel);
|
|
});
|
|
|
|
} else {
|
|
/**
|
|
* NO existe el archivo de conversacion lo creamos
|
|
*/
|
|
const worksheet = workbook.addWorksheet('Chats');
|
|
worksheet.columns = [
|
|
{ header: 'Fecha', key: 'number_customer' },
|
|
{ header: 'Mensajes', key: 'message' }
|
|
];
|
|
worksheet.addRow([today, message]);
|
|
workbook.xlsx.writeFile(pathExcel)
|
|
.then(() => {
|
|
|
|
console.log("saved");
|
|
})
|
|
.catch((err) => {
|
|
console.log("err", err);
|
|
});
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Saludos a primera respuesta
|
|
* @param {*} req
|
|
* @param {*} res
|
|
*/
|
|
|
|
const greetCustomer = (from) => new Promise((resolve, reject) => {
|
|
from = from.replace('@c.us', '');
|
|
|
|
const pathExcel = `./chats/${from}@c.us.xlsx`;
|
|
if (!fs.existsSync(pathExcel)) {
|
|
const firstMessage = [
|
|
'👋 Ey! que pasa bro',
|
|
'Recuerda subscribirte a mi canal de YT',
|
|
'https://www.youtube.com/leifermendez',
|
|
'de regalo te dejo algunos de mis cursos',
|
|
'🔴 Aprende ANGULAR desde cero 2021 ⮕ https://bit.ly/367tJ32',
|
|
'✅ Aprende NODE desde cero 2021 ⮕ https://bit.ly/3od1Bl6',
|
|
'🔵 (Socket.io) NODE (Tutorial) ⮕ https://bit.ly/3pg1Q02',
|
|
'------',
|
|
'------',
|
|
'Veo que es la primera vez que nos escribes ¿Quieres que te envie un MEME?',
|
|
'Responde Quieromeme'
|
|
].join(' ')
|
|
|
|
sendMessage(from, firstMessage)
|
|
sendMedia(from, 'curso-1-1.png')
|
|
sendMedia(from, 'curso-2.png')
|
|
sendMedia(from, 'curso-3.png')
|
|
}
|
|
resolve(true)
|
|
})
|
|
|
|
/**
|
|
* Controladores
|
|
*/
|
|
|
|
const sendMessagePost = (req, res) => {
|
|
const { message, number } = req.body
|
|
console.log(message, number);
|
|
sendMessage(number, message)
|
|
res.send({ status: 'Enviado!' })
|
|
}
|
|
|
|
/**
|
|
* Rutas
|
|
*/
|
|
|
|
app.post('/send', sendMessagePost);
|
|
|
|
/**
|
|
* Revisamos si existe archivo con credenciales!
|
|
*/
|
|
(fs.existsSync(SESSION_FILE_PATH)) ? withSession() : withOutSession();
|
|
|
|
|
|
app.listen(9000, () => {
|
|
console.log('Server ready!');
|
|
}) |