Files
bot-whatsapp/app.js
Leifer Mendez 902431c533 fix buttons
2022-02-23 15:55:56 +01:00

235 lines
6.2 KiB
JavaScript

/**
* ⚡⚡⚡ DECLARAMOS LAS LIBRERIAS y CONSTANTES A USAR! ⚡⚡⚡
*/
require('dotenv').config()
const fs = require('fs');
const express = require('express');
const cors = require('cors')
const qrcode = require('qrcode-terminal');
const { Client } = require('whatsapp-web.js');
const mysqlConnection = require('./config/mysql')
const { middlewareClient } = require('./middleware/client')
const { generateImage, cleanNumber } = require('./controllers/handle')
const { connectionReady, connectionLost } = require('./controllers/connection')
const { saveMedia } = require('./controllers/save')
const { getMessages, responseMessages, bothResponse } = require('./controllers/flows')
const { sendMedia, sendMessage, lastTrigger, sendMessageButton, readChat, sendMediaVoiceNote } = require('./controllers/send')
const app = express();
app.use(cors())
app.use(express.json())
const server = require('http').Server(app)
const io = require('socket.io')(server, {
cors: {
origins: ['http://localhost:4200']
}
})
let socketEvents = {sendQR:() => {} ,sendStatus:() => {}};
io.on('connection', (socket) => {
const CHANNEL = 'main-channel';
socket.join(CHANNEL);
socketEvents = require('./controllers/socket')(socket)
console.log('Se conecto')
})
app.use('/', require('./routes/web'))
const port = process.env.PORT || 3000
const SESSION_FILE_PATH = './session.json';
var client;
var sessionData;
/**
* Escuchamos cuando entre un mensaje
*/
const listenMessage = () => client.on('message', async msg => {
const { from, body, hasMedia } = msg;
// Este bug lo reporto Lucas Aldeco Brescia para evitar que se publiquen estados
if (from === 'status@broadcast') {
return
}
message = body.toLowerCase();
console.log('BODY',message)
const number = cleanNumber(from)
await readChat(number, message)
await sendMediaVoiceNote(client, from, 'PTT-20220223-WA0000.opus')
/**
* Guardamos el archivo multimedia que envia
*/
if (process.env.SAVE_MEDIA && hasMedia) {
const media = await msg.downloadMedia();
saveMedia(media);
}
/**
* Si estas usando dialogflow solo manejamos una funcion todo es IA
*/
if (process.env.DATABASE === 'dialogflow') {
const response = await bothResponse(message);
await sendMessage(client, from, response.replyMessage);
if (response.media) {
sendMedia(client, from, response.media);
}
return
}
/**
* Ver si viene de un paso anterior
* Aqui podemos ir agregando más pasos
* a tu gusto!
*/
const lastStep = await lastTrigger(from) || null;
console.log({ lastStep })
if (lastStep) {
const response = await responseMessages(lastStep)
await sendMessage(client, from, response.replyMessage);
}
/**
* Respondemos al primero paso si encuentra palabras clave
*/
const step = await getMessages(message);
console.log({ step })
if (step) {
const response = await responseMessages(step);
/**
* Si quieres enviar botones
*/
await sendMessage(client, from, response.replyMessage, response.trigger);
if(response.hasOwnProperty('actions')){
const { actions } = response;
await sendMessageButton(client, from, null, actions);
return
}
if (!response.delay && response.media) {
sendMedia(client, from, response.media);
}
if (response.delay && response.media) {
setTimeout(() => {
sendMedia(client, from, response.media);
}, response.delay)
}
return
}
//Si quieres tener un mensaje por defecto
if (process.env.DEFAULT_MESSAGE === 'true') {
const response = await responseMessages('DEFAULT')
await sendMessage(client, from, response.replyMessage, response.trigger);
/**
* Si quieres enviar botones
*/
if(response.hasOwnProperty('actions')){
const { actions } = response;
await sendMessageButton(client, from, null, actions);
}
return
}
});
/**
* 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
console.log(`Validando session con Whatsapp...`)
sessionData = require(SESSION_FILE_PATH);
client = new Client({
session: sessionData,
puppeteer: {
args: [
'--no-sandbox'
],
}
});
client.on('ready', () => {
connectionReady()
listenMessage()
loadRoutes(client);
socketEvents.sendStatus()
});
client.on('auth_failure', () => connectionLost())
client.initialize();
}
/**
* Generamos un QRCODE para iniciar sesion
*/
const withOutSession = () => {
console.log('No tenemos session guardada');
client = new Client({
puppeteer: {
args: [
'--no-sandbox'
],
}
});
client.on('qr', qr => generateImage(qr, () => {
qrcode.generate(qr, { small: true });
console.log(`Ver QR http://localhost:${port}/qr`)
socketEvents.sendQR(qr)
}))
client.on('ready', (a) => {
connectionReady()
listenMessage()
loadRoutes(client);
// socketEvents.sendStatus(client)
});
client.on('auth_failure', () => connectionLost());
client.on('authenticated', (session) => {
sessionData = session;
fs.writeFile(SESSION_FILE_PATH, JSON.stringify(session), function (err) {
if (err) {
console.log(`Ocurrio un error con el archivo: `, err);
}
});
});
client.initialize();
}
/**
* Cargamos rutas de express
*/
const loadRoutes = (client) => {
app.use('/api/', middlewareClient(client), require('./routes/api'))
}
/**
* Revisamos si existe archivo con credenciales!
*/
(fs.existsSync(SESSION_FILE_PATH)) ? withSession() : withOutSession();
/**
* Verificamos si tienes un gesto de db
*/
if (process.env.DATABASE === 'mysql') {
mysqlConnection.connect()
}
server.listen(port, () => {
console.log(`El server esta listo por el puerto ${port}`);
})