mirror of
https://github.com/cheveguerra/botLeiferAurik-Mod_2.0.git
synced 2026-04-21 05:09:23 +00:00
Compare commits
19 Commits
BotPruebas
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| b00bc21234 | |||
| 4e3766755d | |||
| db29cc23e6 | |||
| 056b937a11 | |||
| 22925c6389 | |||
| 2b652ca6f3 | |||
| 9f159eec7a | |||
| 22de88798f | |||
| 51620a501a | |||
| 41e0edfb49 | |||
| e5c0c0e724 | |||
| 2fd9226770 | |||
| 754f0259d4 | |||
| 16698cc4e3 | |||
| b2ae1b768d | |||
| fa336c7f2d | |||
| fafcb41ecc | |||
| e779d24553 | |||
| 9054f66ec3 |
5
.env
5
.env
@@ -1,5 +1,5 @@
|
||||
###### DATABASE: none, mysql, dialogflow
|
||||
###### PROVIDER: wwebjs, baileys
|
||||
######DATABASE: none, mysql, dialogflow
|
||||
|
||||
DEFAULT_MESSAGE=false
|
||||
SAVE_MEDIA=true
|
||||
PORT=3005
|
||||
@@ -13,4 +13,3 @@ KEEP_DIALOG_FLOW=false
|
||||
MULTI_DEVICE=true
|
||||
DIALOGFLOW_MEDIA_FOR_SLOT_FILLING=false
|
||||
GDRIVE_FOLDER_ID=
|
||||
PROVIDER=baileys
|
||||
4
.gitignore
vendored
4
.gitignore
vendored
@@ -9,9 +9,5 @@ mediaSend/*
|
||||
!mediaSend/.gitkeep
|
||||
!mediaSend/nota-de-voz.mp3
|
||||
.wwebjs_auth
|
||||
/baileys_sessions/*
|
||||
bot.qr.png
|
||||
backup
|
||||
backup/*
|
||||
/implementaciones/credenciales.json
|
||||
|
||||
|
||||
7
.vscode/launch.json
vendored
Normal file
7
.vscode/launch.json
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
// Use IntelliSense to learn about possible attributes.
|
||||
// Hover to view descriptions of existing attributes.
|
||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": []
|
||||
}
|
||||
13
README.md
13
README.md
@@ -4,7 +4,7 @@
|
||||
Este proyecto es un clon de la **version 1** (legacy) de [Leifer Mendez](https://github.com/leifermendez/bot-whatsapp) y tiene las siguientes modificaciones:
|
||||
|
||||
- Permite **submenus**.
|
||||
- Un submenú es un paso que **sólo se dispara** cuando el paso anterior (regla) es el especificado, los submenus se definen agregando el parametro "```pasoRequerido```" en el **response.json**, entonces si queremos que el paso **zapatos** solo se muestre cuando antes pasamos por el **menú inicial**, agregamos el parámetro "pasoRequerido" a la regla "zapatos", de esta forma si alguien pone el número **1** sin estar en el menú principal, **no** los va a mandar a **zapatos**.
|
||||
- Un submenú es un paso que **sólo se dispara** cuando el paso anterior es el especificado, los submenus se definen agregando el parametro "```pasoRequerido```" en el **response.json**, entonces si queremos que el paso **zapatos** solo se muestre cuando antes pasamos por el **menú inicial**, agregamos el parámetro "pasoRequerido" a la regla "zapatos", de esta forma si alguien pone el número **1** sin estar en el menú principal, **no** los va a mandar a **zapatos**.
|
||||
|
||||
```json
|
||||
"menu":{
|
||||
@@ -33,7 +33,7 @@ Este proyecto es un clon de la **version 1** (legacy) de [Leifer Mendez](https:/
|
||||
"pasoRequerido":"menu"
|
||||
}
|
||||
```
|
||||
- Permite **expresiones regulares** en las palabras predefinidas en el ~~**initial.json**~~ **response.json**.
|
||||
- Permite **expresiones regulares** en las palabras predefinidas en el **initial.json**.
|
||||
- Si queremos usar RegExp, en los "keywords" de **inital.json**, en lugar de un arreglo, debemos usar un string ( quitamos los [] )
|
||||
y en él usamos "*" para significar cualquier texto y "|" para significar "OR", esto nos permite ser mas flexibles
|
||||
con los "keywords", por ejemplo, si queremos que el mensaje pueda decir:
|
||||
@@ -62,8 +62,6 @@ Este proyecto es un clon de la **version 1** (legacy) de [Leifer Mendez](https:/
|
||||
- Ponemos __%dia_semana%__ para que aparezca "lunes, martes, miercoles, etc" dependiendo del día de la semana.
|
||||
- Ponemos __%msjant_XX%__ para que aparezca el mensaje xx anterior, es decir, si quieres mostrar el texto de 2 mensajes anteriores se pone %msjant_2%.
|
||||
- etc, etc, se pueden agregar mas remplazos en la funcion "remplazos" en el archivo "adapter\index.js".
|
||||
|
||||
|
||||
- Permite el envío de **multiples mensajes** (burbujas o globos) definidos en la **misma respuesta** del **response.json**. (Esta modificación se la robe por completo a [KJoaquin](https://github.com/KJoaquin), el lo solucionó [aquí](https://github.com/codigoencasa/bot-whatsapp/issues/111#issuecomment-1353504575) 🙌🏽 y yo solo lo adapté a mi repositorio!.)
|
||||
|
||||
Antes:
|
||||
@@ -95,7 +93,7 @@ Este proyecto es un clon de la **version 1** (legacy) de [Leifer Mendez](https:/
|
||||
}
|
||||
}
|
||||
```
|
||||
- Permite ejecutar **funciones** y conectarse a **APIs**, por ejemplo: Google Sheets, Excel y cualquier otra API que se pueda llamar desde una función, esto se hace agregando el parámetro "```funcion```" al **response.json**, la funcion especificada recibe automaticamente una variable con toda la información del *mensaje recibido*, Nota: Si se especifica una funcion, esa regla ya no usa los parámetros de ```replyMessage```, ```media``` o ```goto```, solo toma en cuenta el parámetro ```keywords``` y ```pasoRequerido``` y ejecuta la función.
|
||||
- Permite conectarse a **APIs**, por ejemplo: Google Sheets, Excel y cualquier otra API que se pueda llamar desde una función, esto se hace agregando el parámetro "```funcion```" al **response.json**, la funcion especificada recibe automaticamente una variable con toda la información del *mensaje recibido*.
|
||||
|
||||
```response.json```
|
||||
```
|
||||
@@ -145,10 +143,7 @@ Este proyecto es un clon de la **version 1** (legacy) de [Leifer Mendez](https:/
|
||||
"goto":"paso1"
|
||||
},
|
||||
```
|
||||
- **Función** ```vamosA(from, 'regla')``` (goto), esta función nos permite decirle al bot que el ```pasoAnterior``` es el que estamos especificando en ```vamosA```, de esta forma solo se van a disparar reglas que tengan como ```pasoRequerido``` la que estamos indicando.
|
||||
- Se agregó la posibilidad de usar **Baileys** como proveedor, para esto solo hay que cambiar la variable ```PROVIDER``` en el archivo ```.env```, usamos "```wwebjs```" para *whatsapp-web.js* y "```baileys```" para *Baileys*.
|
||||
|
||||
- Las modificaciones están enfocadas al uso de los archivos ~~__initial.json__ y~~ __response.json__, yo no uso MySQL o DialogFlow, así que no sé si las modificaciones funcionen con esos modulos, en particular el __remplazo %msjant_XX%__ depende de los archivos __JSON__ que se crean en el directorio "chats".
|
||||
- Las modificaciones están enfocadas al uso de los archivos __initial.json__ y __response.json__, yo no uso MySQL o DialogFlow, así que no sé si las modificaciones funcionen con esos modulos, en particular el __remplazo %msjant_XX%__ depende de los archivos __JSON__ que se crean en el directorio "chats".
|
||||
- Tiene agregado el parche de **botones y listas**, así que funcionan sin problema (las listas no funcionan si el bot esta **ligado** a un número que use **Whatsapp Business**).
|
||||
- Tiene los ultimos parches de **DialogFlow** (27-dic-2022) (When Dialogflow asks for an Image, then **Upload it to Google Drive** and then generate Shared Link)
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ const fs = require('fs');
|
||||
//const clientEmail = require(`${__dirname}/../chatbot-account.json`);
|
||||
|
||||
/**
|
||||
* La funcion 'generatePublicUrl' genera un error muy pequeño al enviar el 'requestBody'
|
||||
* La funcion 'generatePublicUrl' genera un error muy menor al enviar el 'requestBody'
|
||||
* siempre y cuando necesites que el acceso sea restringido y solo ciertos usuarios puedan acceder.
|
||||
* Esto se logra con la combinacion requerida: 'reader', 'user' y 'emailAddress':
|
||||
* requestBody: {
|
||||
@@ -51,7 +51,6 @@ if (process.env.DATABASE === 'dialogflow') {
|
||||
},
|
||||
fields: 'id,name',
|
||||
});
|
||||
|
||||
generatePublicUrl(id).then(() => {
|
||||
console.log(`Se generó enlace https://drive.google.com/open?id=${id} para el archivo ${name}`);
|
||||
});
|
||||
|
||||
187
adapter/index.js
187
adapter/index.js
@@ -3,7 +3,7 @@ const { saveMessageJson } = require('./jsonDb')
|
||||
const { getDataIa } = require('./diaglogflow')
|
||||
// const stepsInitial = require('../flow/initial.json')
|
||||
const stepsReponse = require('../flow/response.json')
|
||||
// const { isUndefined } = require('util');
|
||||
const { isUndefined } = require('util');
|
||||
var ultimoStep; //MOD by CHV -
|
||||
var pasoRequerido; //MOD by CHV -
|
||||
var _vamosA = ""; //MOD by CHV -
|
||||
@@ -11,9 +11,7 @@ var VA = ""; //MOD by CHV -
|
||||
var elNum; //MOD by CHV -
|
||||
var cumplePasoPrevio = []; //MOD by CHV -
|
||||
const resps = require('../flow/response.json'); //MOD by CHV - Agregamos para traer las respuestas.
|
||||
// const { appendFile, existsSync } = require('fs')
|
||||
// const { traeVariables } = require(`../provider/${provider}.js`)
|
||||
|
||||
const { appendFile } = require('fs')
|
||||
/**
|
||||
* Regresa un arreglo de objetos como el stepsInitial original, que se generaba desde "initial.json".
|
||||
* Contiene el nombre del paso (key) y las palabras clave correspondientes (keywords).
|
||||
@@ -32,12 +30,6 @@ const getStepsInitial = () => {
|
||||
}
|
||||
const stepsInitial = getStepsInitial()
|
||||
|
||||
/**
|
||||
* Revisa si el texto del mensaje dispara alguna regla (body == keyword)
|
||||
* @param {*} message
|
||||
* @param {*} num
|
||||
* @returns
|
||||
*/
|
||||
const get = (message, num) => new Promise((resolve, reject) => { //MOD by CHV - Agregamos parametro "num" para recibir el número de "app.js"
|
||||
// console.log(num)
|
||||
elNum = num //MOD by CHV -
|
||||
@@ -153,6 +145,7 @@ const get = (message, num) => new Promise((resolve, reject) => { //MOD by CHV -
|
||||
// ultimoStep = key;
|
||||
}
|
||||
const response = key || null
|
||||
// if(key != null){remplazos(resps[key].replyMessage.join(''));}
|
||||
if(resps[key]!=undefined){VA = resps[key].goto}else{VA=null}
|
||||
cumplePasoRequerido(key);
|
||||
_vamosA = VA;
|
||||
@@ -219,17 +212,18 @@ const getIA = (message) => new Promise((resolve, reject) => {
|
||||
*
|
||||
* @param {*} message
|
||||
* @param {*} date
|
||||
* @param {*} trigger
|
||||
* @param {*} number
|
||||
* @returns
|
||||
*/
|
||||
const saveMessage = ( message, number, regla ) => new Promise( async (resolve, reject) => { //MOD by CHV - Agregamos el partametro "regla" para poder guardarlo en "chats/numero.json"
|
||||
const saveMessage = ( message, trigger, number, regla ) => new Promise( async (resolve, reject) => { //MOD by CHV - Agregamos el partametro "regla" para poder guardarlo en "chats/numero.json"
|
||||
switch ( process.env.DATABASE ) {
|
||||
case 'mysql':
|
||||
resolve( await saveMessageMysql( message, number ) )
|
||||
resolve( await saveMessageMysql( message, trigger, number ) )
|
||||
break;
|
||||
case 'none':
|
||||
resolve( await saveMessageJson( message, number, regla) ) //MOD by CHV - Agregamos el parametro "regla"
|
||||
// console.log("Guardamos mensaje JSON =", message)
|
||||
resolve( await saveMessageJson( message, trigger, number, regla) ) //MOD by CHV - Agregamos el parametro "regla"
|
||||
// console.log("REGLA DESDE APP.JS="+regla)
|
||||
break;
|
||||
default:
|
||||
resolve(true)
|
||||
@@ -237,6 +231,7 @@ const saveMessage = ( message, number, regla ) => new Promise( async (resolve, r
|
||||
}
|
||||
})
|
||||
|
||||
module.exports = { get, reply, getIA, saveMessage, remplazos, stepsInitial, vamosA, traeUltimaVisita } //MOD by CHV - Agregamos "remplazos" y "stepsInitial" para usarlos en "apps.js"
|
||||
|
||||
/**
|
||||
* Asigna el valor especificado a la variable pasoAnterior.
|
||||
@@ -244,16 +239,156 @@ const saveMessage = ( message, number, regla ) => new Promise( async (resolve, r
|
||||
* NO EJECUTA EL PASO DADO, solo espfecifica cual es el paso anterior para cuando una regla tiene el parametro "pasoRequerido".
|
||||
* @param {elNum} string - El numero del remitente.
|
||||
* @param {elPaso} string - El paso al que se va redirigir el flujo.
|
||||
*/
|
||||
*/
|
||||
function vamosA (elNum, elPaso){
|
||||
pasoAnterior[elNum] = elPaso;
|
||||
console.log("Asignamos pasoAnterior con " + elPaso, elNum)
|
||||
}
|
||||
|
||||
/**
|
||||
* Reemplaza texto en la respuesta con variables predefinidas.
|
||||
*/
|
||||
function remplazos(elTexto, extraInfo){
|
||||
if(elTexto == null){elTexto = '';}
|
||||
const fs = require('fs');
|
||||
laLista = elTexto.toString().split(' ');
|
||||
// console.log(laLista);
|
||||
// console.log('============= remplazos ============');
|
||||
for (var i = 0; i < laLista.length; i++) {
|
||||
// console.log('Revisamos: '+laLista[i]);
|
||||
if (laLista[i].search('%dia_semana%')>-1){//Remplaza con el dia de hoy.
|
||||
var dia = new Date().getDay();
|
||||
if(dia==0){diaSemana='domingo';}
|
||||
else if(dia==1){diaSemana='lunes';}
|
||||
else if(dia==2){diaSemana='martes';}
|
||||
else if(dia==3){diaSemana='miercoles';}
|
||||
else if(dia==4){diaSemana='jueves';}
|
||||
else if(dia==5){diaSemana='viernes';}
|
||||
else {diaSemana='sábado';}
|
||||
elTexto = elTexto.replace('%dia_semana%', diaSemana);
|
||||
}
|
||||
if (laLista[i].search('%saludo%')>-1){//Remplaza con "Buenos dias, tardes o noches" dependiendo de la hora.
|
||||
var hora = new Date().getHours()
|
||||
if(hora>0 && hora < 12){saludo='Buenos días';}
|
||||
else if(hora>11 && hora < 19){saludo='Buenas tardes';}
|
||||
else {saludo='Buenas noches';}
|
||||
elTexto = elTexto.toString().replace('%saludo%', saludo);
|
||||
}
|
||||
if (laLista[i].search('%hora24%')>-1){//Remplaza con la hora a 24 hrs.
|
||||
var hora = new Date().getHours();
|
||||
if (hora.toString().length < 2){hora = "0" + hora;}
|
||||
elTexto = elTexto.toString().replace('%hora24%', hora);
|
||||
}
|
||||
if (laLista[i].search('%hora12%')>-1){//Remplaza con la hora a 12 hrs.
|
||||
var hora = new Date().getHours();
|
||||
var ampm = hora >= 12 ? 'pm' : 'am';
|
||||
hora = hora % 12;
|
||||
hora = hora ? hora : 12; // the hour '0' should be '12'
|
||||
if (hora.toString().length < 2){hora = "0" + hora;}
|
||||
elTexto = elTexto.toString().replace('%hora12%', hora);
|
||||
}
|
||||
if (laLista[i].search('%minutos%')>-1){//Remplaza con los minutos de la hora actual.
|
||||
var mins = new Date().getMinutes();
|
||||
if (mins.toString().length < 2){mins = "0" + mins;}
|
||||
elTexto = elTexto.toString().replace('%minutos%', mins);
|
||||
}
|
||||
if (laLista[i].search('%ampm%')>-1){//Remplaza con am o pm.
|
||||
var hours = new Date().getHours();
|
||||
var ampm = hours >= 12 ? 'pm' : 'am';
|
||||
elTexto = elTexto.toString().replace('%ampm%', ampm);
|
||||
}
|
||||
if (laLista[i].search('%rnd_')>-1){//Remplaza con opción al azar dentro de las especificadas.
|
||||
var inicio = laLista[i].search('%rnd_');
|
||||
var final = laLista[i].indexOf("%", inicio+1);
|
||||
// console.log(inicio, final);
|
||||
var subStr = laLista[i].substring(inicio, final+1);
|
||||
// console.log("El substring="+subStr);
|
||||
var partes = subStr.toString().split('_');
|
||||
if(partes.length > 1){
|
||||
var opciones = partes[1].toString().substring(0,partes[1].toString().length-1).split(",");
|
||||
var elRand = Math.floor(Math.random() * (opciones.length));
|
||||
if(elRand == opciones.length){elRand = elRand - 1;}
|
||||
// console.log(opciones.length, elRand, opciones[elRand]);
|
||||
elTexto = elTexto.toString().replace(subStr, opciones[elRand]);
|
||||
}
|
||||
else{
|
||||
elTexto = elTexto.toString().replace(subStr, "");
|
||||
}
|
||||
}
|
||||
if(laLista[i].search('%msjant_')>-1){//Remplaza con el mensaje anterior especificado.
|
||||
var histlMsjs = {};
|
||||
// console.log("entramos a msjant")
|
||||
// var hayHistorial = (chkFile(`${__dirname}/chats/`+from+".json"));
|
||||
if(chkFile(`${__dirname}/../chats/`+elNum+".json")){
|
||||
let rawdata = fs.readFileSync(`./chats/${elNum}.json`);
|
||||
let elHistorial0 = JSON.parse(rawdata);
|
||||
elHistorial = elHistorial0["messages"];
|
||||
elHistorial = elHistorial.filter(x => x.message != "") //Quitamos mensajes en blanco.
|
||||
var inicio = laLista[i].search('%msjant_');
|
||||
var final = laLista[i].indexOf("%", inicio+1);
|
||||
var subStr = laLista[i].substring(inicio, final+1);
|
||||
// console.log("Substr = |" + subStr + "|");
|
||||
var partes = subStr.toString().split('_');
|
||||
if(partes.length > 1){
|
||||
// console.log("Partes[1] = |" + partes[1] + "|");
|
||||
let posicion0 = partes[1].substring(0, partes[1].length-1)
|
||||
// console.log("Posicion0 = |" + posicion0 + "|");
|
||||
posicion = ((posicion0*1) + 1);
|
||||
// console.log("Posicion = " + posicion);
|
||||
// console.log( elHistorial.length );
|
||||
// console.log((elHistorial.length*1)-posicion);
|
||||
// console.log("Mensaje="+elHistorial[elHistorial.length - posicion]["message"])
|
||||
elTexto = elTexto.toString().replace(subStr, elHistorial[elHistorial.length - posicion]["message"].trim());
|
||||
}
|
||||
// histlMsjs = elHistorial["messages"];
|
||||
// totalMsjs = histlMsjs.length-1;
|
||||
// ultimoMensaje = histlMsjs[histlMsjs.length-1];
|
||||
// let mensajeAnterior = elHistorial["messages"][totalMsjs-1];
|
||||
// console.log("Mensajes:"+totalMsjs+", Ultimo:"+JSON.stringify(ultimoMensaje));
|
||||
// console.log("Anterior:"+JSON.stringify(mensajeAnterior));
|
||||
}
|
||||
// return histlMsjs;
|
||||
}
|
||||
if (laLista[i].search('%body%')>-1){//Remplaza con el body del ctx.
|
||||
const {theMsg} = extraInfo;
|
||||
const { body } = theMsg
|
||||
elTexto = elTexto.toString().replace('%body%', body);
|
||||
}
|
||||
if (laLista[i].search('%from%')>-1){//Remplaza con el from del ctx.
|
||||
const {theMsg} = extraInfo;
|
||||
const { from } = theMsg
|
||||
elTexto = elTexto.toString().replace('%from%', from);
|
||||
}
|
||||
if (laLista[i].search('%solonumero%')>-1){//Remplaza con el from del ctx.
|
||||
const {theMsg} = extraInfo;
|
||||
const { from } = theMsg
|
||||
elTexto = elTexto.toString().replace('%solonumero%', from.replace('@c.us', ''));
|
||||
}
|
||||
if (laLista[i].search('%nombre%')>-1){//Remplaza con el nombre del remitente.
|
||||
if(typeof extraInfo !== undefined){
|
||||
const {theMsg} = extraInfo;
|
||||
if(theMsg['_data']['notifyName'] !== undefined){
|
||||
elTexto = elTexto.toString().replace('%nombre%', theMsg['_data']['notifyName']);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (laLista[i].search('%primer_nombre%')>-1){//Remplaza con el nombre del remitente.
|
||||
if(typeof extraInfo !== undefined){
|
||||
const {theMsg} = extraInfo;
|
||||
if(theMsg['_data']['notifyName'] !== undefined){
|
||||
elTexto = elTexto.toString().replace('%primer_nombre%', theMsg['_data']['notifyName'].split(' ')[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// console.log("EL TEXTO="+elTexto);
|
||||
return elTexto.trim()
|
||||
}
|
||||
|
||||
/**
|
||||
* Revisa si la regla especificada depende (es submenu) de otra regla, y cambia la variable "cumplePasoPrevio" a verdadero o falso.
|
||||
*/
|
||||
function cumplePasoRequerido(step){
|
||||
*/
|
||||
function cumplePasoRequerido(step){
|
||||
//Traemos las respuestas para obtener el "pasoRequerido".
|
||||
if(resps[step]!=undefined){pasoRequerido=resps[step].pasoRequerido}else{pasoRequerido=null}
|
||||
if((pasoRequerido != null && pasoRequerido == ultimoStep)){
|
||||
@@ -276,7 +411,7 @@ function cumplePasoRequerido(step){
|
||||
* Revisa que exista el archivo "chats/numero.json"
|
||||
* @param {*} theFile
|
||||
* @returns
|
||||
*/
|
||||
*/
|
||||
function chkFile(theFile){ //MOD by CHV - Agregamos para revisar que exista el archivo "chats/numero.json"
|
||||
const fs = require('fs');
|
||||
if (fs.existsSync(theFile)) {
|
||||
@@ -295,7 +430,7 @@ function chkFile(theFile){ //MOD by CHV - Agregamos para revisar que exista el a
|
||||
* datepart: 'y', 'm', 'w', 'd', 'h', 'n', 's' (default = n)
|
||||
* @param {*} file
|
||||
* @param {*} datepart
|
||||
*/
|
||||
*/
|
||||
function traeUltimaVisita(file, datepart = 'n'){
|
||||
// Node.js program to demonstrate the
|
||||
// fs.futimes() method
|
||||
@@ -325,7 +460,7 @@ function traeUltimaVisita(file, datepart = 'n'){
|
||||
}
|
||||
else { return 0 }
|
||||
}
|
||||
/**
|
||||
/**
|
||||
* Regresa el tiempo transcurrido en (datepart) entre las fechas dadas.
|
||||
* datepart: 'y', 'm', 'w', 'd', 'h', 'n', 's'
|
||||
* @param {*} datepart
|
||||
@@ -337,12 +472,10 @@ function dateDiff(datepart, fromdate, todate){
|
||||
datepart = datepart.toLowerCase();
|
||||
var diff = todate - fromdate;
|
||||
var divideBy = { w:604800000,
|
||||
d:86400000,
|
||||
h:3600000,
|
||||
n:60000,
|
||||
s:1000
|
||||
};
|
||||
d:86400000,
|
||||
h:3600000,
|
||||
n:60000,
|
||||
s:1000 };
|
||||
|
||||
return Math.floor( diff/divideBy[datepart]);
|
||||
}
|
||||
|
||||
module.exports = { get, reply, getIA, saveMessage, stepsInitial, vamosA, traeUltimaVisita } //MOD by CHV - Agregamos "stepsInitial" para usarlos en "apps.js"
|
||||
@@ -1,14 +1,14 @@
|
||||
const Path = require('path')
|
||||
const StormDB = require("stormdb");
|
||||
const date = new Date().toISOString();
|
||||
const saveMessageJson = (message, number, regla) => new Promise( async(resolve,reject) =>{
|
||||
const saveMessageJson = (message, trigger, number, regla) => new Promise( async(resolve,reject) =>{
|
||||
try {
|
||||
const engine = new StormDB.localFileEngine( Path.join(__dirname, `/../chats/${number}.json`) );
|
||||
const db = new StormDB(engine);
|
||||
// set default db value if db is empty
|
||||
db.default({ messages: [] });
|
||||
// add new users entry
|
||||
db.get("messages").push({ message, date, regla});
|
||||
db.get("messages").push({ message, date, trigger, regla});
|
||||
db.save();
|
||||
resolve('Saved')
|
||||
} catch (error) {
|
||||
|
||||
@@ -47,10 +47,10 @@ getMessages = ( number ) => new Promise((resolve,reejct) => {
|
||||
}
|
||||
})
|
||||
|
||||
saveMessageMysql = ( message, date, number ) => new Promise((resolve,reejct) => {
|
||||
saveMessageMysql = ( message, date, trigger, number ) => new Promise((resolve,reejct) => {
|
||||
try {
|
||||
connection.query(
|
||||
`INSERT INTO ${DATABASE_NAME}.messages `+"( `message`, `date`, `number`)"+` VALUES ('${message}','${date}', '${number}')` , (error, results) => {
|
||||
`INSERT INTO ${DATABASE_NAME}.messages `+"( `message`, `date`, `trigger`, `number`)"+` VALUES ('${message}','${date}','${trigger}', '${number}')` , (error, results) => {
|
||||
if(error) {
|
||||
//TODO esta parte es mejor incluirla directamente en el archivo .sql template
|
||||
console.log('DEBES DE CREAR LA TABLA DE MESSAGE')
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
/**
|
||||
* ⚡⚡⚡ DECLARAMOS LAS LIBRERIAS y CONSTANTES A USAR! ⚡⚡⚡
|
||||
*/
|
||||
require('dotenv').config()
|
||||
global.provider = process.env.PROVIDER || 'wwebjs';
|
||||
const { Client } = require('whatsapp-web.js');
|
||||
const { generateImage, cleanNumber, checkEnvFile, createClient, isValidNumber } = require('./controllers/handle')
|
||||
const { initBot, traeVariables } = require('./provider/baileys')
|
||||
const { sendMedia, sendMessage, lastTrigger, sendMessageButton, sendMessageList, readChat } = require('./controllers/send_baileys');
|
||||
let enviado = false
|
||||
|
||||
function listenMessage(client){
|
||||
client.ev.on('messages.upsert', async msg => {
|
||||
let {from, body, nombre} = traeVariables(msg)
|
||||
if (from === 'status@broadcast' || msg.type !== 'notify') { return }
|
||||
client.theMsg = msg;
|
||||
console.log("######################### INICIO ############################")
|
||||
console.log("from, Body y Nombre = ", "|", from, "|", body, "|", nombre, "|", msg?.type)
|
||||
console.log("CLIENT:", client)
|
||||
// console.log('KEY=', msg.messages.key)
|
||||
// console.log('MESSAGES=', msg.messages)
|
||||
console.log('MESSAGE__=', msg.messages[0])
|
||||
// await sock.sendMessage(m.messages[0].key.remoteJid, { text: 'hola como estas' })
|
||||
if(!enviado) {
|
||||
console.log("########## Enviamos mensaje")
|
||||
sendMessage(client, "5215554192439@s.whatsapp.net", "hola")
|
||||
|
||||
const buttonMessage = [
|
||||
{"body":"boton 1"},
|
||||
{"body":"boton 2"}
|
||||
]
|
||||
|
||||
console.log("Enviamos botones = ", from, buttonMessage)
|
||||
sendMessageButton(client, "5215554192439@s.whatsapp.net", "texto", buttonMessage)
|
||||
|
||||
|
||||
enviado = true
|
||||
}
|
||||
|
||||
})
|
||||
enviado = false
|
||||
}
|
||||
|
||||
async function inicializaBot(){
|
||||
const ib = await initBot()
|
||||
listenMessage(ib)
|
||||
}
|
||||
inicializaBot()
|
||||
@@ -1,12 +1,6 @@
|
||||
const { get, reply, getIA } = require('../adapter')
|
||||
const { saveExternalFile, checkIsUrl } = require('./handle')
|
||||
|
||||
/**
|
||||
* Regresa la regla que se cumple con el texto el mensaje.
|
||||
* @param {*} message
|
||||
* @param {*} num
|
||||
* @returns
|
||||
*/
|
||||
const getMessages = async (message, num) => { //MOD by CHV - Agregamos el parametro "num" para recibir el numero desde "app.js"
|
||||
// console.log("GETMESSAGES (flow.js)")
|
||||
const data = await get(message, num) //MOD by CHV - Agregamos "num"
|
||||
|
||||
@@ -6,18 +6,12 @@ const qr = require('qr-image')
|
||||
|
||||
const MULTI_DEVICE = process.env.MULTI_DEVICE || 'true';
|
||||
|
||||
const cleanNumber_wwebjs = (number) => {
|
||||
const cleanNumber = (number) => {
|
||||
number = number.replace('@c.us', '');
|
||||
number = `${number}@c.us`;
|
||||
return number
|
||||
}
|
||||
|
||||
const cleanNumber_baileys = (number) => {
|
||||
number = number.replace('@s.whatsapp.net', '');
|
||||
number = `${number}@s.whatsapp.net`;
|
||||
return number
|
||||
}
|
||||
|
||||
const saveExternalFile = (url) => new Promise((resolve, reject) => {
|
||||
const ext = url.split('.').pop()
|
||||
const checkProtocol = url.split('/').includes('https:');
|
||||
@@ -50,8 +44,8 @@ const checkIsUrl = (path) => {
|
||||
}
|
||||
|
||||
const generateImage = (base64, cb = () => {}) => {
|
||||
let qr_svg = qr.image(base64, { type: 'png', margin: 4 });
|
||||
qr_svg.pipe(require('fs').createWriteStream('./public/bot.qr.png'));
|
||||
let qr_svg = qr.image(base64, { type: 'svg', margin: 4 });
|
||||
qr_svg.pipe(require('fs').createWriteStream('./mediaSend/qr-code.svg'));
|
||||
console.log(`⚡ Recuerda que el QR se actualiza cada minuto ⚡'`);
|
||||
console.log(`⚡ Actualiza F5 el navegador para ver el QR mas reciente⚡`);
|
||||
cb()
|
||||
@@ -83,11 +77,7 @@ const createClient = () => {
|
||||
const isValidNumber = (rawNumber) => {
|
||||
const regexGroup = /\@g.us\b/gm;
|
||||
const exist = rawNumber.match(regexGroup);
|
||||
// console.log("IsValidWawebJS", rawNumber, exist, !exist)
|
||||
return !exist
|
||||
}
|
||||
|
||||
// const isValidNumber = eval(`isValidNumber_${provider}`)
|
||||
const cleanNumber = eval(`cleanNumber_${provider}`)
|
||||
|
||||
module.exports = {cleanNumber, saveExternalFile, generateImage, checkIsUrl, checkEnvFile, createClient, isValidNumber }
|
||||
module.exports = {cleanNumber, saveExternalFile, generateImage, checkIsUrl, checkEnvFile, createClient, isValidNumber}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
const mimeDb = require('mime-db')
|
||||
const GDRIVE_FOLDER_ID = process.env.GDRIVE_FOLDER_ID || 'false'
|
||||
if(GDRIVE_FOLDER_ID == true) { const { uploadSingleFile } = require('../adapter/gdrive') }
|
||||
const mimeDb = require('mime-db');
|
||||
const { uploadSingleFile } = require('../adapter/gdrive');
|
||||
const fs = require('fs');
|
||||
|
||||
var fileName;
|
||||
|
||||
/**
|
||||
@@ -9,6 +9,7 @@ var fileName;
|
||||
* @param {*} media
|
||||
*/
|
||||
|
||||
|
||||
const saveMedia = (media) => {
|
||||
const extensionProcess = mimeDb[media.mimetype];
|
||||
let ext;
|
||||
@@ -26,8 +27,10 @@ const saveMedia = (media) => {
|
||||
}
|
||||
|
||||
const saveMediaToGoogleDrive = async (media) => {
|
||||
|
||||
fileName = saveMedia(media);
|
||||
filePath = `${__dirname}/../media/${fileName}`
|
||||
|
||||
const googleDriveUrl = await uploadSingleFile(fileName, filePath);
|
||||
return googleDriveUrl
|
||||
}
|
||||
|
||||
@@ -2,9 +2,7 @@
|
||||
const ExcelJS = require('exceljs');
|
||||
const moment = require('moment');
|
||||
const fs = require('fs');
|
||||
const { MessageMedia, Buttons, List } = require('whatsapp-web.js')
|
||||
const baileys = require('./send_baileys')
|
||||
const wwebjs = require('./send_wwebjs')
|
||||
const { MessageMedia, Buttons, List } = require('whatsapp-web.js');
|
||||
const { cleanNumber } = require('./handle')
|
||||
const { remplazos } = require('../adapter/index'); //MOD by CHV - Agregamos remplazos
|
||||
const DELAY_TIME = 170; //ms
|
||||
@@ -14,26 +12,22 @@ const DIR_MEDIA = `${__dirname}/../mediaSend`;
|
||||
const { saveMessage } = require('../adapter')
|
||||
/**
|
||||
* Enviamos archivos multimedia a nuestro cliente
|
||||
* @param {*} client
|
||||
* @param {*} number
|
||||
* @param {*} fileName
|
||||
* @param {*} caption
|
||||
*/
|
||||
|
||||
const sendMedia = (client, number = null, fileName = null, caption = null) => {
|
||||
const sendMedia = (client, number = null, fileName = null, trigger = null) => {
|
||||
if(!client) return console.error("El objeto cliente no está definido.");
|
||||
// console.log("MEDIA:"+fileName);
|
||||
console.log("MEDIA:"+fileName);
|
||||
try {
|
||||
// number = cleanNumber(number || 0)
|
||||
// const file = `${DIR_MEDIA}/${fileName}`;
|
||||
// console.log("FILE="+file);
|
||||
// if (fs.existsSync(file)) {
|
||||
// console.log("ARCHIVO EXISTE");
|
||||
// const media = MessageMedia.fromFilePath(file);
|
||||
if(provider === 'baileys'){baileys.sendMedia(client, number, fileName, caption)}
|
||||
else{wwebjs.sendMedia(client, number, fileName, caption)}
|
||||
// client.sendMessage(number, media, { sendAudioAsVoice: true });
|
||||
// }
|
||||
number = cleanNumber(number || 0)
|
||||
const file = `${DIR_MEDIA}/${fileName}`;
|
||||
console.log("FILE="+file);
|
||||
if (fs.existsSync(file)) {
|
||||
console.log("ARCHIVO EXISTE");
|
||||
const media = MessageMedia.fromFilePath(file);
|
||||
client.sendMessage(number, media, { sendAudioAsVoice: true });
|
||||
}
|
||||
} catch(e) {
|
||||
throw e;
|
||||
}
|
||||
@@ -48,14 +42,13 @@ const sendMedia = (client, number = null, fileName = null, caption = null) => {
|
||||
const sendMediaVoiceNote = (client, number = null, fileName = null) => {
|
||||
if(!client) return console.error("El objeto cliente no está definido.");
|
||||
try {
|
||||
// number = cleanNumber(number || 0)
|
||||
// const file = `${DIR_MEDIA}/${fileName}`;
|
||||
// if (fs.existsSync(file)) {
|
||||
// const media = MessageMedia.fromFilePath(file)
|
||||
if(provider === 'baileys'){baileys.sendMediaVoiceNote(client, number, fileName)}
|
||||
else{wwebjs.sendMediaVoiceNote(client, number, fileName)}
|
||||
// client.sendMessage(number, media ,{ sendAudioAsVoice: true });
|
||||
// }
|
||||
number = cleanNumber(number || 0)
|
||||
const file = `${DIR_MEDIA}/${fileName}`;
|
||||
if (fs.existsSync(file)) {
|
||||
const media = MessageMedia.fromFilePath(file);
|
||||
client.sendMessage(number, media ,{ sendAudioAsVoice: true });
|
||||
|
||||
}
|
||||
}catch(e) {
|
||||
throw e;
|
||||
}
|
||||
@@ -65,15 +58,13 @@ const sendMedia = (client, number = null, fileName = null, caption = null) => {
|
||||
* Enviamos un mensaje simple (texto) a nuestro cliente
|
||||
* @param {*} number
|
||||
*/
|
||||
const sendMessage = async (client, number = null, text = null, regla) => { //MOD by CHV - Agregamos el parametro "regla" para guardarlo en "chats/numero.json"
|
||||
const sendMessage = async (client, number = null, text = null, trigger = null, regla) => { //MOD by CHV - Agregamos el parametro "regla" para guardarlo en "chats/numero.json"
|
||||
setTimeout(async () => {
|
||||
// number = cleanNumber(number)
|
||||
// const message = text
|
||||
if(provider === 'baileys'){baileys.sendMessage(client, number, text, regla)}
|
||||
else{wwebjs.sendMessage(client, number, text, regla)}
|
||||
// client.sendMessage(number, message);
|
||||
number = cleanNumber(number)
|
||||
const message = text
|
||||
client.sendMessage(number, message);
|
||||
// console.log(number, message, regla)
|
||||
await readChat(number, text, regla) //MOD by CHV - Agregamos el parametro "regla"
|
||||
await readChat(number, message, trigger, regla) //MOD by CHV - Agregamos el parametro "regla"
|
||||
console.log(`⚡⚡⚡ Enviando mensajes....`);
|
||||
// console.log("********************* SEND MESSAGE **************************************");
|
||||
},DELAY_TIME)
|
||||
@@ -85,14 +76,13 @@ const sendMessage = async (client, number = null, text = null, regla) => { //MOD
|
||||
*/
|
||||
const sendMessageButton = async (client, number = null, text = null, actionButtons) => {
|
||||
setTimeout(async () => {
|
||||
if(provider === 'baileys'){baileys.sendMessageButton(client, number, text, actionButtons)}
|
||||
else{wwebjs.sendMessageButton(client, number, text, actionButtons)}
|
||||
// number = cleanNumber(number)
|
||||
number = cleanNumber(number)
|
||||
const { title = null, message = null, footer = null, buttons = [] } = actionButtons;
|
||||
// let button = new Buttons(remplazos(message, client),[...buttons], remplazos(title, client), remplazos(footer, client));
|
||||
await readChat(number, message)
|
||||
// client.sendMessage(number, button);
|
||||
let button = new Buttons(remplazos(message, client),[...buttons], remplazos(title, client), remplazos(footer, client));
|
||||
await readChat(number, message, actionButtons)
|
||||
client.sendMessage(number, button);
|
||||
console.log(`⚡⚡⚡ Enviando mensajes (botones)....`);
|
||||
// console.log("sendMessageButton.");
|
||||
}, DELAY_TIME)
|
||||
// console.log("************************ SEND MESSAGE BUTTON ***********************************");
|
||||
}
|
||||
@@ -105,14 +95,12 @@ const sendMessageList = async (client, number = null, text = null, actionList) =
|
||||
setTimeout(async () => {
|
||||
// console.log("********************** client **************************")
|
||||
// console.log(client)
|
||||
// number = cleanNumber(number)
|
||||
// const { body = null, buttonText = null, sections = [], title = null, footer = null } = actionList;
|
||||
// let aList = new List( remplazos(body, client),remplazos(buttonText, client),[...sections],remplazos(title, client),remplazos(footer, client));
|
||||
if(provider === 'baileys'){baileys.sendMessageList(client, number, text, actionList)}
|
||||
else{wwebjs.sendMessageList(client, number, text, actionList)}
|
||||
// client.sendMessage(number, aList);
|
||||
await readChat(number, text)
|
||||
// console.log('⚡⚡⚡ Enviando lista a '+number+' ....');
|
||||
number = cleanNumber(number)
|
||||
const { body = null, buttonText = null, sections = [], title = null, footer = null } = actionList;
|
||||
let aList = new List( remplazos(body, client),remplazos(buttonText, client),[...sections],remplazos(title, client),remplazos(footer, client));
|
||||
client.sendMessage(number, aList);
|
||||
await readChat(number, message, actionList)
|
||||
console.log('⚡⚡⚡ Enviando lista a '+number+' ....');
|
||||
}, DELAY_TIME)
|
||||
}
|
||||
|
||||
@@ -142,9 +130,9 @@ const lastTrigger = (number) => new Promise((resolve, reject) => {
|
||||
* @param {*} number
|
||||
* @param {*} message
|
||||
*/
|
||||
const readChat = async (number, message, regla) => { //MOD by CHV - Agregamos el parametro "regla" para guardarlo en "chats/numero.json"
|
||||
const readChat = async (number, message, trigger = null, regla) => { //MOD by CHV - Agregamos el parametro "regla" para guardarlo en "chats/numero.json"
|
||||
number = cleanNumber(number)
|
||||
await saveMessage( message, number, regla ) //MOD by CHV - Agregamos "regla"
|
||||
await saveMessage( message, trigger, number, regla ) //MOD by CHV - Agregamos "regla"
|
||||
// console.log('Saved')
|
||||
}
|
||||
|
||||
|
||||
@@ -1,216 +0,0 @@
|
||||
const ExcelJS = require('exceljs');
|
||||
const moment = require('moment');
|
||||
const fs = require('fs');
|
||||
const { MessageMedia, Buttons, List } = require('whatsapp-web.js');
|
||||
const { cleanNumber } = require('./handle')
|
||||
const { remplazos } = require('../implementaciones/extraFuncs'); //MOD by CHV - Agregamos remplazos
|
||||
const DELAY_TIME = 170; //ms
|
||||
const DIR_MEDIA = `${__dirname}/../mediaSend`;
|
||||
// import { Low, JSONFile } from 'lowdb'
|
||||
// import { join } from 'path'
|
||||
const { saveMessage } = require('../adapter')
|
||||
// const { ingresarDatos, leerDatos } = require('../implementaciones/sheets')
|
||||
const mime = require('mime-types')
|
||||
|
||||
/**
|
||||
* Enviar imagen o multimedia
|
||||
* @param {*} number
|
||||
* @param {*} mediaInput
|
||||
* @param {*} message
|
||||
* @param {*} caption
|
||||
* @example await sendMessage(client, '+XXXXXXXXXXX', 'https://dominio.com/imagen.jpg' | 'img/imagen.jpg', 'caption')
|
||||
*/
|
||||
const sendMedia = async (client, number, fileName, caption = null) => {
|
||||
console.log("SendMedia Baileys = ", number, fileName, caption)
|
||||
// const fileDownloaded = await generalDownload(imageUrl)
|
||||
|
||||
const file = `${DIR_MEDIA}/${fileName}`;
|
||||
console.log("FILE="+file);
|
||||
if (fs.existsSync(file)) {
|
||||
console.log("ARCHIVO EXISTE");
|
||||
const mimeType = mime.lookup(file)
|
||||
if (mimeType.includes('image')) return sendImage(client, number, file, caption)
|
||||
if (mimeType.includes('video')) return sendVideo(client, number, file, caption)
|
||||
if (mimeType.includes('audio')) return sendAudio(client, number, file, caption)
|
||||
return sendFile(client, number, file)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enviar imagen
|
||||
* @param {*} number
|
||||
* @param {*} imageUrl
|
||||
* @param {*} text
|
||||
* @returns
|
||||
*/
|
||||
const sendImage = async (client, number, filePath, text) => {
|
||||
client.sendMessage(number, {
|
||||
image: fs.readFileSync(filePath),
|
||||
caption: text,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Enviamos archivos como notas de voz
|
||||
* @param {*} number
|
||||
* @param {*} fileName
|
||||
*/
|
||||
|
||||
const sendMediaVoiceNote = (client, number = null, fileName = null) => {
|
||||
if(!client) return console.error("El objeto cliente no está definido.");
|
||||
try {
|
||||
number = cleanNumber(number || 0)
|
||||
const file = `${DIR_MEDIA}/${fileName}`;
|
||||
if (fs.existsSync(file)) {
|
||||
const media = MessageMedia.fromFilePath(file);
|
||||
client.sendMessage(number, media ,{ sendAudioAsVoice: true });
|
||||
}
|
||||
}catch(e) {
|
||||
throw e;
|
||||
}
|
||||
|
||||
}
|
||||
/**
|
||||
* Enviamos un mensaje simple (texto) a nuestro cliente
|
||||
* @param {*} number
|
||||
*/
|
||||
const sendMessage = async (client, number = null, text = null, regla = null) => { //MOD by CHV - Agregamos el parametro "regla" para guardarlo en "chats/numero.json"
|
||||
if(text !== undefined && text != null){
|
||||
setTimeout(async () => {
|
||||
number = cleanNumber(number)
|
||||
client.sendMessage(number, { text: text })
|
||||
// console.log(number, message, regla)
|
||||
await readChat(number, text, regla) //MOD by CHV - Agregamos el parametro "regla"
|
||||
console.log(`⚡⚡⚡ Enviando mensajes....`);
|
||||
// ingresarDatos(number, text, 'Salida', 'Bot Pruebas')
|
||||
// console.log("********************* SEND MESSAGE **************************************");
|
||||
},DELAY_TIME)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enviamos un mensaje con buttons a nuestro cliente
|
||||
* @param {*} number
|
||||
*/
|
||||
const sendMessageButton2 = async (client, number = null, text = null, actionButtons) => {
|
||||
setTimeout(async () => {
|
||||
number = cleanNumber(number)
|
||||
const { title = null, message = null, footer = null, buttons = [] } = actionButtons;
|
||||
let button = new Buttons(remplazos(message, client),[...buttons], remplazos(title, client), remplazos(footer, client));
|
||||
await readChat(number, message)
|
||||
client.sendMessage(number, button);
|
||||
console.log(`⚡⚡⚡ Enviando mensajes (botones)....`);
|
||||
// console.log("sendMessageButton.");
|
||||
}, DELAY_TIME)
|
||||
// console.log("************************ SEND MESSAGE BUTTON ***********************************");
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {string} number
|
||||
* @param {string} text
|
||||
* @param {string} footer
|
||||
* @param {Array} buttons
|
||||
* @example await sendMessage("+XXXXXXXXXXX", "Your Text", "Your Footer", [{"buttonId": "id", "buttonText": {"displayText": "Button"}, "type": 1}])
|
||||
*/
|
||||
const sendMessageButton = async (client, number, text = null, actionButtons) => {
|
||||
number = cleanNumber(number)
|
||||
const { title = null, message = null, footer = null, buttons = [] } = actionButtons;
|
||||
const templateButtons = buttons.map((btn, i) => ({
|
||||
buttonId: `id-btn-${i}`,
|
||||
buttonText: { displayText: btn.body },
|
||||
type: 1,
|
||||
}))
|
||||
let mensaje2 = ""
|
||||
if (title != null) { mensaje2 = "*" + title + "*\n\n" + message }
|
||||
else { mensaje2 = message }
|
||||
text = remplazos(mensaje2, client)
|
||||
const buttonMessage = { text, footer, buttons: templateButtons, headerType: 1 }
|
||||
console.log("sendMessageButton:", buttonMessage)
|
||||
console.log(templateButtons)
|
||||
return client.sendMessage(number, buttonMessage)
|
||||
await readChat(number, message)
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {string} number
|
||||
* @param {string} text
|
||||
* @param {string} footer
|
||||
* @param {Array} buttons
|
||||
* @example await sendMessage("+XXXXXXXXXXX", "Your Text", "Your Footer", [{"buttonId": "id", "buttonText": {"displayText": "Button"}, "type": 1}])
|
||||
*/
|
||||
const sendMessageButtonTemplate = async (client, number, text = null, actionButtons) => {
|
||||
number = cleanNumber(number)
|
||||
const { title = null, message = null, footer = null, buttons = [] } = actionButtons;
|
||||
const templateButtons = buttons.map((btn, i) => ({
|
||||
buttonId: `id-btn-${i}`,
|
||||
buttonText: { displayText: btn.body },
|
||||
type: 1,
|
||||
}))
|
||||
text = remplazos(`*${title}*\n${message}`, client)
|
||||
const buttonMessage = { text, footer, buttons: templateButtons, headerType: 1 }
|
||||
console.log("sendMessageButton:", buttonMessage)
|
||||
console.log(templateButtons)
|
||||
return client.sendMessage(number, buttonMessage)
|
||||
await readChat(number, message)
|
||||
}
|
||||
|
||||
/**
|
||||
* Enviamos listas (con el formato de response.json)
|
||||
* @param {*} number
|
||||
*/
|
||||
const sendMessageList = async (client, number = null, text = null, actionList) => {
|
||||
// console.log("**************** baileys send ", number, text, actionList)
|
||||
setTimeout(async () => {
|
||||
// console.log("********************** client **************************")
|
||||
number = cleanNumber(number)
|
||||
const { body = null, buttonText = null, sections = [], title = null, footer = null } = actionList;
|
||||
const theList = {
|
||||
text: remplazos(body, client),
|
||||
footer: remplazos(footer, client),
|
||||
title: remplazos(title, client),
|
||||
buttonText: remplazos(buttonText, client),
|
||||
sections
|
||||
}
|
||||
// console.log(theList)
|
||||
// console.log(sections[0])
|
||||
client.sendMessage(number, theList);
|
||||
await readChat(number, body)
|
||||
console.log('⚡⚡⚡ Enviando lista a '+number+' ....');
|
||||
}, DELAY_TIME)
|
||||
}
|
||||
|
||||
/**
|
||||
* Opte
|
||||
*/
|
||||
const lastTrigger = (number) => new Promise((resolve, reject) => {
|
||||
number = cleanNumber(number)
|
||||
const pathExcel = `${__dirname}/../chats/${number}.xlsx`;
|
||||
const workbook = new ExcelJS.Workbook();
|
||||
if (fs.existsSync(pathExcel)) {
|
||||
workbook.xlsx.readFile(pathExcel)
|
||||
.then(() => {
|
||||
const worksheet = workbook.getWorksheet(1);
|
||||
const lastRow = worksheet.lastRow;
|
||||
const getRowPrevStep = worksheet.getRow(lastRow.number);
|
||||
const lastStep = getRowPrevStep.getCell('C').value;
|
||||
resolve(lastStep)
|
||||
});
|
||||
} else {
|
||||
resolve(null)
|
||||
}
|
||||
})
|
||||
|
||||
/**
|
||||
* Guardar historial de conversacion
|
||||
* @param {*} number
|
||||
* @param {*} message
|
||||
*/
|
||||
const readChat = async (number, message, regla = null) => { //MOD by CHV - Agregamos el parametro "regla" para guardarlo en "chats/numero.json"
|
||||
number = cleanNumber(number)
|
||||
await saveMessage( message, number, regla ) //MOD by CHV - Agregamos "regla"
|
||||
// console.log('Saved')
|
||||
}
|
||||
|
||||
module.exports = { sendMessage, sendMedia, lastTrigger, sendMessageButton, sendMessageList, readChat, sendMediaVoiceNote }
|
||||
@@ -1,166 +0,0 @@
|
||||
const ExcelJS = require('exceljs');
|
||||
const moment = require('moment');
|
||||
const fs = require('fs');
|
||||
const { MessageMedia, Buttons, List } = require('whatsapp-web.js');
|
||||
const { cleanNumber } = require('./handle')
|
||||
const { remplazos } = require('../implementaciones/extraFuncs') //MOD by CHV - Agregamos remplazos
|
||||
const DELAY_TIME = 170; //ms
|
||||
const DIR_MEDIA = `${__dirname}/../mediaSend`;
|
||||
// import { Low, JSONFile } from 'lowdb'
|
||||
// import { join } from 'path'
|
||||
const { saveMessage } = require('../adapter')
|
||||
// const { ingresarDatos, leerDatos } = require('../implementaciones/sheets')
|
||||
const mime = require('mime-types')
|
||||
|
||||
/**
|
||||
* Enviar imagen o multimedia
|
||||
* @param {*} number
|
||||
* @param {*} mediaInput
|
||||
* @param {*} message
|
||||
* @param {*} caption
|
||||
* @returns
|
||||
*/
|
||||
const sendMedia = async (client, number, fileName, caption = null) => {
|
||||
console.log("SendMedia WWebJS = ", number, fileName, caption)
|
||||
// const fileDownloaded = await generalDownload(imageUrl)
|
||||
const file = `${DIR_MEDIA}/${fileName}`;
|
||||
console.log("FILE="+file);
|
||||
if (fs.existsSync(file)) {
|
||||
console.log("ARCHIVO EXISTE");
|
||||
const mimeType = mime.lookup(file)
|
||||
if (mimeType.includes('image')) return sendImage(client, number, file, caption)
|
||||
if (mimeType.includes('video')) return sendVideo(client, number, file, caption)
|
||||
if (mimeType.includes('audio')) return sendAudio(client, number, file, caption)
|
||||
return sendFile(client, number, file)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enviar imagen
|
||||
* @param {*} number
|
||||
* @param {*} imageUrl
|
||||
* @param {*} text
|
||||
* @returns
|
||||
*/
|
||||
const sendImage = async (client, number, fileName, caption) => {
|
||||
const file = `${DIR_MEDIA}/${fileName}`;
|
||||
console.log("FILE="+file);
|
||||
if (fs.existsSync(file)) {
|
||||
console.log("ARCHIVO EXISTE");
|
||||
const media = MessageMedia.fromFilePath(file);
|
||||
}
|
||||
const base64 = fs.readFileSync(fileName, { encoding: 'base64' })
|
||||
const mimeType = mime.lookup(fileName)
|
||||
const media = new MessageMedia(mimeType, base64)
|
||||
client.sendMessage(number, media, { caption })
|
||||
}
|
||||
|
||||
/**
|
||||
* Enviamos archivos como notas de voz
|
||||
* @param {*} number
|
||||
* @param {*} fileName
|
||||
*/
|
||||
|
||||
const sendMediaVoiceNote = (client, number = null, fileName = null) => {
|
||||
if(!client) return console.error("El objeto cliente no está definido.");
|
||||
try {
|
||||
number = cleanNumber(number || 0)
|
||||
const file = `${DIR_MEDIA}/${fileName}`;
|
||||
if (fs.existsSync(file)) {
|
||||
const media = MessageMedia.fromFilePath(file);
|
||||
client.sendMessage(number, media ,{ sendAudioAsVoice: true });
|
||||
}
|
||||
}catch(e) {
|
||||
throw e;
|
||||
}
|
||||
|
||||
}
|
||||
/**
|
||||
* Enviamos un mensaje simple (texto) a nuestro cliente
|
||||
* @param {*} number
|
||||
*/
|
||||
const sendMessage = async (client, number = null, text = null, regla = null) => { //MOD by CHV - Agregamos el parametro "regla" para guardarlo en "chats/numero.json"
|
||||
setTimeout(async () => {
|
||||
number = cleanNumber(number)
|
||||
const message = text
|
||||
client.sendMessage(number, message);
|
||||
// console.log(number, message, regla)
|
||||
await readChat(number, message, regla) //MOD by CHV - Agregamos el parametro "regla"
|
||||
console.log(`⚡⚡⚡ Enviando mensajes....`);
|
||||
// ingresarDatos(number, message, 'Salida', 'Bot Pruebas')
|
||||
// console.log("********************* SEND MESSAGE **************************************");
|
||||
},DELAY_TIME)
|
||||
}
|
||||
|
||||
/**
|
||||
* Enviamos un mensaje con buttons a nuestro cliente
|
||||
* @param {*} number
|
||||
*/
|
||||
const sendMessageButton = async (client, number, text = null, actionButtons) => {
|
||||
setTimeout(async () => {
|
||||
number = cleanNumber(number)
|
||||
const { title = null, message = null, footer = null, buttons = [] } = actionButtons;
|
||||
let button = new Buttons(
|
||||
remplazos(message, client),
|
||||
[...buttons],
|
||||
remplazos(title, client),
|
||||
remplazos(footer, client));
|
||||
console.log("sendMessageButton wwebjs:", button)
|
||||
console.log(button.buttons)
|
||||
client.sendMessage(number, button);
|
||||
await readChat(number, message)
|
||||
}, DELAY_TIME)
|
||||
// console.log("************************ SEND MESSAGE BUTTON ***********************************");
|
||||
}
|
||||
|
||||
/**
|
||||
* Enviamos listas (con el formato de response.json)
|
||||
* @param {*} number
|
||||
*/
|
||||
const sendMessageList = async (client, number = null, text = null, actionList) => {
|
||||
// console.log("*************** wwebjs send")
|
||||
setTimeout(async () => {
|
||||
// console.log("********************** client **************************")
|
||||
console.log(actionList)
|
||||
number = cleanNumber(number)
|
||||
const { body = null, buttonText = null, sections = [], title = null, footer = null } = actionList;
|
||||
let aList = new List( remplazos(body, client),remplazos(buttonText, client),[...sections],remplazos(title, client),remplazos(footer, client));
|
||||
client.sendMessage(number, aList);
|
||||
await readChat(number, message)
|
||||
console.log('⚡⚡⚡ Enviando lista a '+number+' ....');
|
||||
}, DELAY_TIME)
|
||||
}
|
||||
|
||||
/**
|
||||
* Opte
|
||||
*/
|
||||
const lastTrigger = (number) => new Promise((resolve, reject) => {
|
||||
number = cleanNumber(number)
|
||||
const pathExcel = `${__dirname}/../chats/${number}.xlsx`;
|
||||
const workbook = new ExcelJS.Workbook();
|
||||
if (fs.existsSync(pathExcel)) {
|
||||
workbook.xlsx.readFile(pathExcel)
|
||||
.then(() => {
|
||||
const worksheet = workbook.getWorksheet(1);
|
||||
const lastRow = worksheet.lastRow;
|
||||
const getRowPrevStep = worksheet.getRow(lastRow.number);
|
||||
const lastStep = getRowPrevStep.getCell('C').value;
|
||||
resolve(lastStep)
|
||||
});
|
||||
} else {
|
||||
resolve(null)
|
||||
}
|
||||
})
|
||||
|
||||
/**
|
||||
* Guardar historial de conversacion
|
||||
* @param {*} number
|
||||
* @param {*} message
|
||||
*/
|
||||
const readChat = async (number, message, regla = null) => { //MOD by CHV - Agregamos el parametro "regla" para guardarlo en "chats/numero.json"
|
||||
number = cleanNumber(number)
|
||||
await saveMessage( message, number, regla ) //MOD by CHV - Agregamos "regla"
|
||||
// console.log('Saved')
|
||||
}
|
||||
|
||||
module.exports = { sendMessage, sendMedia, sendImage, lastTrigger, sendMessageButton, sendMessageList, readChat, sendMediaVoiceNote }
|
||||
@@ -1,5 +1,5 @@
|
||||
const fs = require('fs')
|
||||
const { sendMessage } = require(`./send_${provider}`)
|
||||
const { sendMessage } = require('../controllers/send')
|
||||
|
||||
const sendMessagePost = (req, res) => {
|
||||
console.log('asdasdasdasdasd')
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
"%saludo% %primer_nombre%, este es el *menú*, selecciona una opción:",
|
||||
"Pon *1* para ver mensajes anteriores.",
|
||||
"Pon *2* para ver remplazos.",
|
||||
"Pon *3* para capturar cualquier texto (RegExp).",
|
||||
"Pon *3* para pedir nombre (RegExp).",
|
||||
"Pon *4* para un ejemplo de listas y expresiones regulares.",
|
||||
"Pon *5* para un ejemplo de botones.",
|
||||
"Pon *6* para un ejemplo de botones y regExp.",
|
||||
@@ -92,7 +92,7 @@
|
||||
"mensaje":[
|
||||
"Seleccionaste la *opción 3*\n",
|
||||
"*Por favor dame tu nombre.*\n",
|
||||
"Aquí vamos a aceptar *cualquier* texto, porque en *keyword* tenemos : \"*\" (un asterisco en expresiones regulares quiere decir *\"cualquier cosa\"*)",
|
||||
"Aquí vamos a aceptar *cualquier* texto, porque en el *initial.json* tenemos keywords : \"*\" (un asterisco en expresiones regulares quiere decir *\"cualquier cosa\"*)",
|
||||
"Y en *response.json* en la opción correspondiente tenemos \"pasoRequerido\" : \"menu\", que quiere decir que SOLO se va a disparar cuando el paso anterior sea \"menu\"."
|
||||
]
|
||||
}
|
||||
@@ -189,15 +189,15 @@
|
||||
"media":null,
|
||||
"trigger":null,
|
||||
"actions":{
|
||||
"body":"Hola *%primer_nombre%*, este es un ejemplo de lista con expresiones regulares, *todas* las opciones de la *lista* disparan la misma regla:\n\n'*pak*3*|*pak*angular*|*paquete*3*|*paquete*angular*'\n\nAutomáticamente el flujo se regresa al *menú*, asi que puedes poner nuevamente un número del 1 al 5 sin necesidad de volver a iniciar con */menu*.",
|
||||
"body":"Hola *%primer_nombre%*, estos son ejemplos del uso de expresiones regulares, *todas* las opciones de la *lista* disparan la misma regla:\n\n'*pak*3*|*pak*angular*|*paquete*3*|*paquete*angular*'\n\nAutomáticamente el flujo se regresa al *menú*, asi que puedes poner nuevamente un número del 1 al 5 sin necesidad de volver a iniciar con */menu*.",
|
||||
"buttonText":"Ver los ejemplos de RegEx",
|
||||
"sections": [
|
||||
{"title":"Selecciona un mensaje:",
|
||||
"rows":[
|
||||
{"rowId": "paq3", "title": "Me gusta el paquete 3"},
|
||||
{"rowId": "paqA", "title": "Por favor mas info del paquete de Angular"},
|
||||
{"rowId": "pakA", "title": "Me gustó el pak de Angular"},
|
||||
{"rowId": "pak3", "title": "Estoy interesado en el pak 3"}
|
||||
{"id": "paq3", "title": "Me gusta el paquete 3"},
|
||||
{"id": "paqA", "title": "Por favor mas info del paquete de Angular"},
|
||||
{"id": "pakA", "title": "Me gustó el pak de Angular"},
|
||||
{"id": "pak3", "title": "Estoy interesado en el pak 3"}
|
||||
]
|
||||
}
|
||||
],
|
||||
|
||||
@@ -1,332 +0,0 @@
|
||||
const axios = require('axios').default;
|
||||
const { removeDiacritics, getRandomInt, remplazos, soloNumero, traeVariablesFromClient } = require('./extraFuncs')
|
||||
const { sendMedia, sendMessage, sendMessageButton, sendMessageList, readChat } = require(`../controllers/send`)
|
||||
const { vamosA, traeUltimaVisita } = require('../adapter/index')
|
||||
|
||||
/**
|
||||
* LAS FUNCIONES SE DECLARAN COMO UN OBJETO DENTRO DE MODULE.EXPORTS, DE LA SIGUIENTE MANERA:
|
||||
*
|
||||
* nombreFuncion1 : function nombreFuncion1(ctx) { // Aqui va el código de la funcion },
|
||||
* nombreFuncion2 : function nombreFuncion2(ctx) { // Aqui va el código de la funcion }
|
||||
*
|
||||
* SE PUEDE USAR LA FUNCION traeVariablesFromClient(ctx) PARA OBTENER LAS VARIABLES from, body, name, hasMedia y step:
|
||||
*
|
||||
* const { from, body, name, hasMedia, step } = traeVariablesFromClient(ctx)
|
||||
*
|
||||
* O SE PUEDEN OBTENER DIRECTAMENTE DEL OBJETO ctx QUE RECIBE LA FUNCION:
|
||||
*
|
||||
* const from = ctx.theMsg.from
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
/**
|
||||
* Llama el API para traer categorias de Guna.
|
||||
* @param {*} ctx El objeto del mensaje.
|
||||
*/
|
||||
getGunaCats : async function getGunaCats(ctx) {
|
||||
const { from, body, name, hasMedia, step } = traeVariablesFromClient(ctx)
|
||||
let lasOpciones = []
|
||||
let lasOpciones2 = []
|
||||
let theUrl = `http://localhost:8888/dbrquery?j={"query":"selectTipoFerreroMty","exec":"ExecuteQuery","params":{"par1":"xxx"}}`
|
||||
const RES = await axios.get(theUrl).then(function (response) {
|
||||
for(reg=0;reg<response.data.respuesta.length;reg++) {
|
||||
let tempItem = {}
|
||||
tempItem['id']=response.data.respuesta[reg].CAT_PT_DESC
|
||||
tempItem['title']=response.data.respuesta[reg].CAT_PT_DESC
|
||||
lasOpciones.push(tempItem)
|
||||
console.log(lasOpciones.length, lasOpciones)
|
||||
}
|
||||
console.log(lasOpciones2)
|
||||
const productList = {
|
||||
body: remplazos("%saludo%, selecciona una categoría 👇🏽", ctx),
|
||||
title: "Ver las categorías",
|
||||
sections:[
|
||||
{ title: "Categorías",
|
||||
rows: lasOpciones,
|
||||
}
|
||||
],
|
||||
footer:"Categorías",
|
||||
buttonText:"Selecciona"
|
||||
}
|
||||
sendMessageList(ctx, from, null, productList)
|
||||
|
||||
|
||||
console.log(ctx)
|
||||
sendMessagList(ctx, from, null, productList);
|
||||
return
|
||||
}).catch(function (error) {
|
||||
console.log(error);
|
||||
return error
|
||||
});
|
||||
// for(o=0;o<lasOpciones.length;o++){
|
||||
// let theUrlSubsT = `http://localhost:8888/dbrquery?j={"query":"selectSubtipoFerreroMty","exec":"ExecuteQuery","params":{"par1":"${lasOpciones[o].id}"}}`
|
||||
// const RES2 = await axios.get(theUrlSubsT).then(function (response2) {
|
||||
// console.log("LO= ", lasOpciones.length, o)
|
||||
// console.log("R2= ", response2.data.respuesta.length)
|
||||
// lasOpciones2 = {}
|
||||
// lasOpciones[o].rows = []
|
||||
// delete lasOpciones[o].id
|
||||
// for(st=0;st<response2.data.respuesta.length;st++) {
|
||||
// let tempItem = {}
|
||||
// tempItem['rowId']=response2.data.respuesta[st].CAT_PS_DESC
|
||||
// tempItem['title']=response2.data.respuesta[st].CAT_PS_DESC
|
||||
// lasOpciones[o].rows.push(tempItem)
|
||||
// console.log("LO2= ", lasOpciones2.length, st, tempItem)
|
||||
// // lasOpciones[st].rows = lasOpciones2
|
||||
// }
|
||||
// }).catch(function (error) {
|
||||
// console.log(error);
|
||||
// return error
|
||||
// })
|
||||
// }
|
||||
// console.log(lasOpciones)
|
||||
// console.log(lasOpciones[0].rows)
|
||||
// const productList = {
|
||||
// body: remplazos("Selecciona una categoria 👇🏽", ctx),
|
||||
// title: "Ver las categorías",
|
||||
// sections:lasOpciones,
|
||||
// footer:"",
|
||||
// buttonText:`CATEGORÍAS`
|
||||
// }
|
||||
// sendMessageList(ctx, from, null, productList)
|
||||
},
|
||||
/**
|
||||
* Llama el API para traer subcategorias de Guna.
|
||||
* @param {*} ctx El objeto del mensaje.
|
||||
*/
|
||||
getGunaSubtipo : async function getGunaSubtipo(ctx) {
|
||||
const { from, body, name, hasMedia, step } = traeVariablesFromClient(ctx);
|
||||
let par1 = ctx.theMsg.body
|
||||
vars[from]['tipo'] = ctx.theMsg.body
|
||||
// console.log("V_TIPO=", from, vars[from]['tipo'])
|
||||
let theUrl = `http://localhost:8888/dbrquery?j={"query":"selectSubtipoFerreroMty","exec":"ExecuteQuery","params":{"par1":"${vars[from]['tipo']}"}}`
|
||||
const RES = await axios.get(theUrl).then(function (response) {
|
||||
if( response.data.respuesta.length == 0 ) {
|
||||
console.log("No hay resultados",from)
|
||||
vamosA(from, "gunaCats")
|
||||
sendMessage(ctx, from, "Esa categoría *no existe*, por favor revisa y vuelve a intentar.", null, step)
|
||||
}
|
||||
let elMensaje = "Gracias,\nAhora una subcategoría:\n\n"
|
||||
let lasOpciones = []
|
||||
for(reg=0;reg<response.data.respuesta.length;reg++) {
|
||||
let tempItem = {}
|
||||
tempItem['id']=response.data.respuesta[reg].CAT_PS_DESC
|
||||
tempItem['title']=response.data.respuesta[reg].CAT_PS_DESC
|
||||
lasOpciones.push(tempItem)
|
||||
// console.log(lasOpciones.length, tempItem)
|
||||
}
|
||||
const productList = {
|
||||
body: remplazos("Selecciona una subcategoría 👇🏽", ctx),
|
||||
title: "Ver las subcategorías",
|
||||
sections:[
|
||||
{ title: "Subcategorías",
|
||||
rows: lasOpciones,
|
||||
}
|
||||
],
|
||||
footer:"",
|
||||
buttonText:`CATEGORÍA ${body}`
|
||||
}
|
||||
sendMessageList(ctx, from, null, productList)
|
||||
return "1"
|
||||
}).catch(function (error) {
|
||||
console.log(error);
|
||||
return error
|
||||
});
|
||||
},
|
||||
/**
|
||||
* Llama el API para traer productos de Guna.
|
||||
* @param {*} ctx El objeto del mensaje.
|
||||
*/
|
||||
getGunaProds : async function getGunaProds(ctx) {
|
||||
const { from, body, name, hasMedia, step } = traeVariablesFromClient(ctx);
|
||||
if(vars[from]['recompra'] === undefined) vars[from]['subtipo'] = ctx.theMsg.body
|
||||
console.log(vars[from]['tipo'], vars[from]['subtipo'], "RECOMPRA=", vars[from]['recompra'])
|
||||
let theUrl = `http://localhost:8888/dbrquery?j={"query":"selectProdsFerreroMty","exec":"ExecuteQuery","params":{"par1":"${vars[from]['tipo']}", "par2":"${vars[from]['subtipo']}"}}`
|
||||
const RES = await axios.get(theUrl).then(function (response) {
|
||||
let elMensaje = "Gracias,\nAhora un producto:\n\n"
|
||||
let lasOpciones = []
|
||||
console.log("resultados selectProds",response.data.respuesta.length)
|
||||
for(reg=0;reg<response.data.respuesta.length;reg++) {
|
||||
let tempItem = {}
|
||||
tempItem['id']=response.data.respuesta[reg].CAT_GP_ID
|
||||
tempItem['title']=`${response.data.respuesta[reg].CAT_GP_NOMBRE} $${response.data.respuesta[reg].CAT_GP_PRECIO}, INV:${response.data.respuesta[reg].CAT_GP_ALMACEN} `
|
||||
lasOpciones.push(tempItem)
|
||||
}
|
||||
const productList = {
|
||||
body: remplazos("Selecciona un producto 👇🏽", ctx),
|
||||
title: "Ver los productos",
|
||||
sections:[
|
||||
{ title: "Productos",
|
||||
rows: lasOpciones,
|
||||
}
|
||||
],
|
||||
buttonText:`SUBCATEGORÍA ${vars[from]['subtipo']}`
|
||||
}
|
||||
sendMessageList(ctx, from, null, productList)
|
||||
return "1"
|
||||
}).catch(function (error) {
|
||||
console.log(error);
|
||||
return error
|
||||
});
|
||||
},
|
||||
/**
|
||||
* Llama el API para traer productos de Guna.
|
||||
* @param {*} ctx El objeto del mensaje.
|
||||
*/
|
||||
agregaProds : async function agregaProds(ctx) {
|
||||
const { from, body, name, hasMedia, step } = traeVariablesFromClient(ctx);
|
||||
// vars[from]['subtipo'] = ctx.theMsg.body
|
||||
if(vars[from]['prods'] === undefined) { vars[from]['prods'] = [] }
|
||||
let elProd = ctx.theMsg.body
|
||||
let elMensaje = ""
|
||||
if(elProd.indexOf(' $') > -1){ // Producto con formato correcto.
|
||||
vars[from]['ultimoProd'] = elProd
|
||||
elProd = elProd.substring(0, elProd.indexOf(' $')).trim().toLowerCase()
|
||||
var precio = ctx.theMsg.body.substring(ctx.theMsg.body.indexOf(' $')+2)
|
||||
// console.log("precio",precio)
|
||||
precio = precio.substring(0, precio.indexOf(','))
|
||||
// console.log("precio",precio)
|
||||
vars[from]['prods'][elProd] = {"cant":0, "precio":precio}
|
||||
// console.log("EL_PROD=", elProd)
|
||||
// console.log(vars[from]['prods'])
|
||||
elMensaje = ctx.theMsg.replyMessage
|
||||
let re = ctx.theMsg.body.trim().toLowerCase()
|
||||
elMensaje = elMensaje.replace(re, elProd.toLowerCase())
|
||||
}
|
||||
else{ // Producto SIN precio.
|
||||
elMensaje = "El producto que seleccionaste es *incorrecto*, por favor intenta de nuevo."
|
||||
sendMessage(ctx, from, elMensaje, null, step);
|
||||
await delay(500)
|
||||
vars[from]['recompra'] = true
|
||||
getGunaProds(ctx)
|
||||
vamosA(from, "gunaProds")
|
||||
return
|
||||
}
|
||||
sendMessage(ctx, from, elMensaje, null, step);
|
||||
return
|
||||
},
|
||||
/**
|
||||
* Tomamos la cantidad del producto seleccionado.
|
||||
* @param {*} ctx El objeto del mensaje.
|
||||
*/
|
||||
prodCantidad : async function prodCantidad(ctx) {
|
||||
const { from, body, name, hasMedia, step } = traeVariablesFromClient(ctx);
|
||||
// console.log("Entramos a prodCantidad")
|
||||
let laCant = ctx.theMsg.body.trim()
|
||||
const reg = new RegExp(/^\d+$/)
|
||||
let elProd = vars[from]['ultimoProd'].toLowerCase()
|
||||
elProd = elProd.substring(0, elProd.indexOf(' $')).trim()
|
||||
console.log("SOLO NUMS |" + laCant + "|", reg.test(laCant))
|
||||
if(reg.test(laCant)){
|
||||
// console.log(vars)
|
||||
// console.log("Recibimos cant = " + laCant)
|
||||
// console.log("EL_PROD=", vars[from]['prods'][elProd])
|
||||
// console.log("precio=", vars[from]['prods'][elProd].precio)
|
||||
vars[from]['prods'][elProd] = {"cant":laCant, "precio":vars[from]['prods'][elProd]['precio']}
|
||||
var elMensaje = ""
|
||||
const prods = Object.keys(vars[from]['prods']);
|
||||
var total = 0
|
||||
prods.forEach((prod, index) => {
|
||||
if( vars[from]['prods'][prod] !== undefined && prod[0] !== undefined ){
|
||||
elMensaje = elMensaje + `${vars[from]['prods'][prod].cant} - ${prod[0].toUpperCase() + prod.substring(1)}\n`
|
||||
console.log("cant y precio=", vars[from]['prods'][prod].cant, vars[from]['prods'][prod].precio)
|
||||
if(reg.test(vars[from]['prods'][prod].cant) && vars[from]['prods'][prod].precio != ""){
|
||||
total = total + (vars[from]['prods'][prod].cant * vars[from]['prods'][prod].precio)
|
||||
}
|
||||
}
|
||||
console.log(prod, vars[from]['prods'][prod]);
|
||||
});
|
||||
let pesos = Intl.NumberFormat('en-US')
|
||||
elMensaje = elMensaje + "\n*Total*: $" + pesos.format(total)
|
||||
elMensaje = elMensaje + "\n¿Quieres agregar mas productos a tu orden?"
|
||||
var bts = {
|
||||
"title":"Tu orden",
|
||||
"message":elMensaje,
|
||||
"buttons":[
|
||||
{"body":"➕ Agregar productos"},
|
||||
{"body":"⬅️ Cambiar categoría"},
|
||||
{"body":"✖️ Terminar"}
|
||||
]
|
||||
}
|
||||
sendMessageButton(ctx, from, null, bts)
|
||||
}
|
||||
else{
|
||||
console.log("NO SOLO NUMS")
|
||||
vamosA(from, "gunaProdsAgrega")
|
||||
sendMessage(ctx, from, "Por favor escribe 👉🏽 *solo* 👈🏽 el número.", null, step);
|
||||
}
|
||||
return "1"
|
||||
},
|
||||
/**
|
||||
* Mandamos nuevamente la lista de productos.
|
||||
* @param {*} ctx El objeto del mensaje.
|
||||
*/
|
||||
comprarMas : async function comprarMas(ctx) {
|
||||
const { from, body, name, hasMedia, step } = traeVariablesFromClient(ctx);
|
||||
console.log("Entramos a comprarMas")
|
||||
vars[from]['recompra'] = true
|
||||
vamosA(from, "gunaProds")
|
||||
await getGunaProds(ctx)
|
||||
vars[from]['recompra'] = undefined
|
||||
return "1"
|
||||
},
|
||||
/**
|
||||
* Mandamos nuevamente la lista de categorías.
|
||||
* @param {*} ctx El objeto del mensaje.
|
||||
*/
|
||||
terminaCompra : async function terminaCompra(ctx) {
|
||||
const { from, body, name, hasMedia, step } = traeVariablesFromClient(ctx);
|
||||
console.log("Entramos a terminaCompra")
|
||||
vars[from] = []
|
||||
sendMessage(ctx, from, "!Gracias por tu compra, regresa pronto!", null, step);
|
||||
return
|
||||
},
|
||||
/**
|
||||
* Llama el API para desbloquear un usuario.
|
||||
* @param {*} ctx El objeto del mensaje.
|
||||
*/
|
||||
desbloqueaUsuario : async function desbloqueaUsuario(ctx) {
|
||||
const { from, body, name, hasMedia, step } = traeVariablesFromClient(ctx);
|
||||
let par1 = ctx.theMsg.body
|
||||
let theUrl = `http://localhost:8888/dbrquery?j={"query":"update_usuario_guna_nobajas","exec":"ExecuteCommand","params":{"par1":"${par1}", "par2":"XXPARAM2XX", "par3":"XXPARAM3XX"}}`
|
||||
const RES = await axios.get(theUrl).then(function (response) {
|
||||
const { AffectedRows } = response.data['respuesta'][0]
|
||||
console.log('AFFECTED_ROWS = ', AffectedRows)
|
||||
if(response.data['respuesta'][0]['AffectedRows']=="1"){
|
||||
sendMessage(ctx, from, "Listo, usuario *"+response.data['params']['par1']+"* desbloqueado, por favor *cerrar navegadores* y reingresar.", null, step);
|
||||
}
|
||||
else{
|
||||
sendMessage(ctx, from, "El usuario *"+response.data['params']['par1']+"* no *existe* o esta dado de *baja*, por favor revisarlo y volver a intentar.", null, step);
|
||||
}
|
||||
return response
|
||||
}).catch(function (error) {
|
||||
console.log(error);
|
||||
return error
|
||||
});
|
||||
},
|
||||
/**
|
||||
* Llama el API para desbloquear el usuario.
|
||||
*
|
||||
* @param {*} theURL El URL para llamar al API
|
||||
* @param {*} step
|
||||
*/
|
||||
desbloqueaUsuario2 : async function desbloqueaUsuario2(theUrl, step) {
|
||||
// const { from, body, name, hasMedia, step } = traeVariablesFromClient(ctx);
|
||||
// const RES = await axios.get(theUrl).then(function (response) {
|
||||
// const { AffectedRows } = response.data['respuesta'][0]
|
||||
// console.log('AFFECTED_ROWS = ', AffectedRows)
|
||||
// if(response.data['respuesta'][0]['AffectedRows']=="1"){
|
||||
// sendMessage(ctx, from, "Listo, usuario *"+response.data['params']['par1']+"* desbloqueado, por favor *cerrar navegadores* y reingresar.", null, step);
|
||||
// }
|
||||
// else{
|
||||
// sendMessage(ctx, from, "El usuario *"+response.data['params']['par1']+"* no *existe* o esta dado de *baja*, por favor revisarlo y volver a intentar.", null, step);
|
||||
// }
|
||||
// return response
|
||||
// }).catch(function (error) {
|
||||
// console.log(error);
|
||||
// return error
|
||||
// });
|
||||
}
|
||||
|
||||
}
|
||||
// module.exports = new funcsClass()
|
||||
12
implementaciones/credenciales.json
Normal file
12
implementaciones/credenciales.json
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"type": "service_account",
|
||||
"project_id": "strong-maker-107118",
|
||||
"private_key_id": "419c2f761213d11f2f30edab66832a9c475e1d33",
|
||||
"private_key": "-----BEGIN PRIVATE KEY-----\nMIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDXlNkR2C9L7mXp\niMfPC4GwOKZcLIAa2XzrigJg3ettAHnWbxFSX4mS9AsmDKjBvkxpRVo+6gBzdtPa\nCZUQVZI6cWE+lCD2fMabwRQMosHxpRTUCruAnb/sku9y1o/KpdDemmqPaAHYxZXV\nex88svqcCPNhivqiPE/cRb1HoVu08IDG31Kgy3+iTpKQux05ngrYwem7wQl2k8dX\nS2SPp7YQID3gZeqWHyC2GVazn3Rz0PuKdp3wMnGB6MMI0yk3vLPHNpsEGyuyNeLG\nya68XBY86y9+LHZ8EwxUdVUmt8hUm0h5bDQftosRhgJakTUHZg9qNTM4iEJ7WYwP\nSao143C/AgMBAAECggEAI6kWxSm5HSWDdyot6cpR+sKhhjgYPW4XiLuCDDWkFsT6\n4nqUkhyFRylBBNttjkA6fI7BJbdojrEBIfKZf/kKYMorggICd94zrkULL3yRegr1\nfePZQ1EU6SnJxnnGkbN0cGDOWrLOMhDxFD4IcJknSmin9c0wYLt69wlpjNqcrw/B\ny6K63hi7M0iXGEHp8nz8Vf1l7VA82hCwUi7D73pkORH98xVY4+MYOTqrCvU0/O2m\nVqP5+mLMG/fPFlMnk8FgL3Q4dqiZ/ds7a6qXND5htSX0sFroINrTYiyXJ73OCgre\nlIbUuAD/92fuHKBdcIaaZvkEEAVTYlainm6LGroeSQKBgQDtq3mUTYO3998GiWO4\nVKnw7yC12WbwOaIDvlccWuTRWByJrRIJmsA1EXg18i9kf9AwxesbRT7xRBCwRMhs\nKUDbKaqvdf4BRARFWe0DSKQZIJpjCQsOtmOaV3yZP5uKLehQKPGgsIVT1A3XmIZW\nNzDAufVM5mjW8KbTNeBmMKRCJwKBgQDoNUMzDTLFl147jOaBJbq99Gd2pB7Aa8dY\n7SI3mXMMX0xCPU06Ym+wI485ybFllm+Bg018/+fJzli3Ko3nNuGcJplYzV8Z/eru\nMWGFCAXq3iWUiwXR9snmTAyO8uYXm7DnnhPxHNr8B3g3v55cTIqEjRn6YF5p7qBD\ntFQrV0ozqQKBgAvqqx/qew5AWWhkfyGA7TxtYQB9NBIbcaoqYwfC7vIoLtYgXWUp\n4zVF+PcLe6DYX8HySoWFhVBnj0anTD1QHDZg8nP1wJSjqmsnxSCDBedUoSkSDQHh\n10Cn3lF4xP26q4lJZEQgVa8MVN1YgnPUNJeVO11tuBf+3P5+FxBIpBPFAoGARxcH\nW7nOsW+GCfU5HJDQexc4FbppL7/PaAoxT5RLBJ6oWh8qZZV9XA+G6co15UQJHz1z\nm7E85SunPWxpxT+oEoY+rFEzrGFwazvy/ydVqHIaTz/AqGdFqJvfvGPgzZl8r2xV\n7ptG76HZzDd95AQK5EnOiji2rve/WPr8SciPjwECgYBf2SejOtRDWo6TOAQtEgvL\ngxU852DwuIW79U/+G2zrJ7qbbRzYCiHtsuaGOgzR5AfqN1+i4PWaJxdIKxymlv4w\nMs+swdsTZCn2/Rj4TndvEXr3OvfMtp0uN68rBNG+pNe1cwi+/+wx/E5ZC3QWxePt\nOwijAJ+obR377HMJOTTOTg==\n-----END PRIVATE KEY-----\n",
|
||||
"client_email": "strong-maker-107118@appspot.gserviceaccount.com",
|
||||
"client_id": "",
|
||||
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
|
||||
"token_uri": "https://oauth2.googleapis.com/token",
|
||||
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
|
||||
"client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/strong-maker-107118%40appspot.gserviceaccount.com"
|
||||
}
|
||||
@@ -1,515 +0,0 @@
|
||||
const fs = require('fs')
|
||||
|
||||
function alertas(ctx){
|
||||
console.log("LISTO - ALERTAS")
|
||||
console.log(ctx)
|
||||
}
|
||||
|
||||
/**
|
||||
* Regresa un número random entre los parametros min y max dados.
|
||||
* @param {*} min
|
||||
* @param {*} max
|
||||
* @returns
|
||||
*/
|
||||
function getRandomInt(min, max) {
|
||||
min = Math.ceil(min);
|
||||
max = Math.floor(max);
|
||||
return Math.floor(Math.random() * (max - min) + min); // The maximum is exclusive and the minimum is inclusive
|
||||
}
|
||||
|
||||
/**
|
||||
* Revisa que exista el archivo "chats/numero.json"
|
||||
* @param {*} theFile
|
||||
* @returns
|
||||
*/
|
||||
function chkFile(theFile){ //MOD by CHV - Agregamos para revisar que exista el archivo "chats/numero.json"
|
||||
const fs = require('fs');
|
||||
if (fs.existsSync(theFile)) {
|
||||
// console.log("Si existe el archivo "+ theFile);
|
||||
var h = true;
|
||||
}
|
||||
else{
|
||||
// console.log("No existe el archivo "+ theFile);
|
||||
var h = false;
|
||||
}
|
||||
return h;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reemplaza texto en la respuesta con variables predefinidas.
|
||||
*/
|
||||
function remplazos(elTexto, extraInfo){
|
||||
if(elTexto == null){elTexto = '';}
|
||||
// console.log("EXTRAINFO_THEMSG", extraInfo.theMsg)
|
||||
// console.log(extraInfo.theMsg.messages)
|
||||
const { from, body, name } = extraInfo.theMsg
|
||||
laLista = elTexto.toString().split(' ');
|
||||
// console.log(laLista);
|
||||
// console.log('============= remplazos ============');
|
||||
for (var i = 0; i < laLista.length; i++) {
|
||||
// console.log('Revisamos: '+laLista[i]);
|
||||
if (laLista[i].search('%dia_semana%')>-1){//Remplaza con el dia de hoy.
|
||||
var dia = new Date().getDay();
|
||||
if(dia==0){diaSemana='domingo';}
|
||||
else if(dia==1){diaSemana='lunes';}
|
||||
else if(dia==2){diaSemana='martes';}
|
||||
else if(dia==3){diaSemana='miercoles';}
|
||||
else if(dia==4){diaSemana='jueves';}
|
||||
else if(dia==5){diaSemana='viernes';}
|
||||
else {diaSemana='sábado';}
|
||||
elTexto = elTexto.replace('%dia_semana%', diaSemana);
|
||||
}
|
||||
if (laLista[i].search('%saludo%')>-1){//Remplaza con "Buenos dias, tardes o noches" dependiendo de la hora.
|
||||
var hora = new Date().getHours()
|
||||
if(hora>0 && hora < 12){saludo='Buenos días';}
|
||||
else if(hora>11 && hora < 19){saludo='Buenas tardes';}
|
||||
else {saludo='Buenas noches';}
|
||||
elTexto = elTexto.toString().replace('%saludo%', saludo);
|
||||
}
|
||||
if (laLista[i].search('%hora24%')>-1){//Remplaza con la hora a 24 hrs.
|
||||
var hora = new Date().getHours();
|
||||
if (hora.toString().length < 2){hora = "0" + hora;}
|
||||
elTexto = elTexto.toString().replace('%hora24%', hora);
|
||||
}
|
||||
if (laLista[i].search('%hora12%')>-1){//Remplaza con la hora a 12 hrs.
|
||||
var hora = new Date().getHours();
|
||||
var ampm = hora >= 12 ? 'pm' : 'am';
|
||||
hora = hora % 12;
|
||||
hora = hora ? hora : 12; // the hour '0' should be '12'
|
||||
if (hora.toString().length < 2){hora = "0" + hora;}
|
||||
elTexto = elTexto.toString().replace('%hora12%', hora);
|
||||
}
|
||||
if (laLista[i].search('%minutos%')>-1){//Remplaza con los minutos de la hora actual.
|
||||
var mins = new Date().getMinutes();
|
||||
if (mins.toString().length < 2){mins = "0" + mins;}
|
||||
elTexto = elTexto.toString().replace('%minutos%', mins);
|
||||
}
|
||||
if (laLista[i].search('%ampm%')>-1){//Remplaza con am o pm.
|
||||
var hours = new Date().getHours();
|
||||
var ampm = hours >= 12 ? 'pm' : 'am';
|
||||
elTexto = elTexto.toString().replace('%ampm%', ampm);
|
||||
}
|
||||
if (laLista[i].search('%rnd_')>-1){//Remplaza con opción al azar dentro de las especificadas.
|
||||
var inicio = laLista[i].search('%rnd_');
|
||||
var final = laLista[i].indexOf("%", inicio+1);
|
||||
// console.log(inicio, final);
|
||||
var subStr = laLista[i].substring(inicio, final+1);
|
||||
// console.log("El substring="+subStr);
|
||||
var partes = subStr.toString().split('_');
|
||||
if(partes.length > 1){
|
||||
var opciones = partes[1].toString().substring(0,partes[1].toString().length-1).split(",");
|
||||
var elRand = Math.floor(Math.random() * (opciones.length));
|
||||
if(elRand == opciones.length){elRand = elRand - 1;}
|
||||
// console.log(opciones.length, elRand, opciones[elRand]);
|
||||
elTexto = elTexto.toString().replace(subStr, opciones[elRand]);
|
||||
}
|
||||
else{
|
||||
elTexto = elTexto.toString().replace(subStr, "");
|
||||
}
|
||||
}
|
||||
if(laLista[i].search('%msjant_')>-1){//Remplaza con el mensaje anterior especificado.
|
||||
var histlMsjs = {};
|
||||
console.log("entramos a msjant", from)
|
||||
var hayHistorial = (chkFile(`${__dirname}/chats/`+from+".json"));
|
||||
if(chkFile(`${__dirname}/../chats/`+from+".json")){
|
||||
let rawdata = fs.readFileSync(`./chats/${from}.json`);
|
||||
let elHistorial0 = JSON.parse(rawdata);
|
||||
elHistorial = elHistorial0["messages"];
|
||||
elHistorial = elHistorial.filter(x => x.message != "") //Quitamos mensajes en blanco.
|
||||
var inicio = laLista[i].search('%msjant_');
|
||||
var final = laLista[i].indexOf("%", inicio+1);
|
||||
var subStr = laLista[i].substring(inicio, final+1);
|
||||
// console.log("Substr = |" + subStr + "|");
|
||||
var partes = subStr.toString().split('_');
|
||||
if(partes.length > 1){
|
||||
// console.log("Partes[1] = |" + partes[1] + "|");
|
||||
let posicion0 = partes[1].substring(0, partes[1].length-1)
|
||||
// console.log("Posicion0 = |" + posicion0 + "|");
|
||||
posicion = ((posicion0*1) + 1);
|
||||
// console.log("Posicion = " + posicion);
|
||||
// console.log( elHistorial.length );
|
||||
// console.log((elHistorial.length*1)-posicion);
|
||||
// console.log("Mensaje="+elHistorial[elHistorial.length - posicion]["message"])
|
||||
elTexto = elTexto.toString().replace(subStr, elHistorial[elHistorial.length - posicion]["message"].trim());
|
||||
}
|
||||
// histlMsjs = elHistorial["messages"];
|
||||
// totalMsjs = histlMsjs.length-1;
|
||||
// ultimoMensaje = histlMsjs[histlMsjs.length-1];
|
||||
// let mensajeAnterior = elHistorial["messages"][totalMsjs-1];
|
||||
// console.log("Mensajes:"+totalMsjs+", Ultimo:"+JSON.stringify(ultimoMensaje));
|
||||
// console.log("Anterior:"+JSON.stringify(mensajeAnterior));
|
||||
}
|
||||
// return histlMsjs;
|
||||
}
|
||||
if (laLista[i].search('%body%')>-1){//Remplaza con el body del ctx.
|
||||
elTexto = elTexto.toString().replace('%body%', body);
|
||||
}
|
||||
if (laLista[i].search('%from%')>-1){//Remplaza con el from del ctx.
|
||||
elTexto = elTexto.toString().replace('%from%', from);
|
||||
}
|
||||
if (laLista[i].search('%solonumero%')>-1){//Remplaza con el from del ctx.
|
||||
elTexto = elTexto.toString().replace('%solonumero%', from.replace('@c.us', ''));
|
||||
}
|
||||
if (laLista[i].search('%nombre%')>-1){//Remplaza con el nombre del remitente.
|
||||
if(typeof extraInfo !== undefined){
|
||||
if(name !== undefined){
|
||||
elTexto = elTexto.toString().replace('%nombre%', name);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (laLista[i].search('%primer_nombre%')>-1){//Remplaza con el nombre del remitente.
|
||||
if(typeof extraInfo !== undefined){
|
||||
// console.log("EXRAINFO:", extraInfo.theMsg)
|
||||
if(name !== undefined){
|
||||
elTexto = elTexto.toString().replace('%primer_nombre%', name.split(' ')[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// console.log("EL TEXTO="+elTexto);
|
||||
return elTexto.trim()
|
||||
}
|
||||
|
||||
/**
|
||||
* Regresa el historial de mensajes del número especificado del directorio "chats".
|
||||
*/
|
||||
function traeMensajes(from){ //MOD by CHV - Agregamos para traer el historial de mensajes
|
||||
var histlMsjs = {};
|
||||
var hayHistorial = (chkFile(`${__dirname}/chats/`+from+".json"));
|
||||
console.log(hayHistorial)
|
||||
// var hayHistorialNoBlanks = hayHistorial.find(k => k.messages.message != "")
|
||||
// console.log(hayHistorialNoBlanks)
|
||||
// var {keywords} = stepsInitial.find(k => k.key.includes(key))
|
||||
if(hayHistorial){
|
||||
let rawdata = fs.readFileSync(`./chats/${from}.json`);
|
||||
let elHistorial = JSON.parse(rawdata);
|
||||
histlMsjs = elHistorial["messages"];
|
||||
// totalMsjs = histlMsjs.length-1;
|
||||
ultimoMensaje = histlMsjs[histlMsjs.length-1];
|
||||
// let mensajeAnterior = elHistorial["messages"][totalMsjs-1];
|
||||
// console.log("Mensajes:"+totalMsjs+", Ultimo:"+JSON.stringify(ultimoMensaje));
|
||||
// console.log("Anterior:"+JSON.stringify(mensajeAnterior));
|
||||
}
|
||||
console.log(histlMsjs)
|
||||
// var histlMsjsNoBlanks = histlMsjs.find(k => k.message != "")
|
||||
var histlMsjsNoBlanks = histlMsjs.filter(x => x.message != "")
|
||||
console.log(histlMsjsNoBlanks)
|
||||
return histlMsjs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Regresa las variables from, body, name y hasMedia del objeto del mensaje.
|
||||
* @param {*} msg
|
||||
* @returns from, body, name, hasMedia
|
||||
*/
|
||||
function traeVariablesFromMsg(msg){
|
||||
if(provider == 'baileys'){return traeVariablesFromMsgBaileys(msg)}
|
||||
else{return traeVariablesFromMsgWWebJS(msg)}
|
||||
}
|
||||
|
||||
function traeVariablesFromMsgBaileys(msg){
|
||||
const { remoteJid } = msg.messages[0].key
|
||||
const { pushName } = msg.messages[0]
|
||||
let theBody = msg.messages[0].message?.conversation || msg.messages[0].message?.templateButtonReplyMessage?.selectedDisplayText || msg.messages[0].message?.buttonsResponseMessage?.selectedDisplayText || msg.messages[0].message?.listResponseMessage?.title
|
||||
let from = remoteJid
|
||||
let body = theBody
|
||||
let name = pushName
|
||||
let hasMedia = false
|
||||
let timestamp = msg.messages[0].messageTimestamp
|
||||
// console.log("fromBody=", from, body, name)
|
||||
return {"from":from, "body":body, "name":name, "hasMedia":hasMedia, "timestamp":timestamp}
|
||||
}
|
||||
|
||||
function traeVariablesFromMsgWWebJS(msg){
|
||||
const { from, body, hasMedia, timestamp } = msg;
|
||||
let name = msg?._data?.notifyName
|
||||
// console.log("fromBody=", msg?._data)
|
||||
return {"from":from, "body":body, "name":name, "hasMedia":hasMedia, "timestamp":timestamp}
|
||||
}
|
||||
|
||||
/**
|
||||
* Regresa las variables from, body, name, hasMedia, step y number del objeto del cliente.
|
||||
* @param {*} client
|
||||
* @returns from, body, name, hasMedia, step y number
|
||||
*/
|
||||
function traeVariablesFromClient(client){
|
||||
// console.log(client)
|
||||
const { body, from, name, hasMedia, step, number } = client.theMsg
|
||||
// const { pushName } = client.theMsg
|
||||
return {"from":from, "body":body, "name":name, "hasMedia":hasMedia, "step":step, "number":number}
|
||||
}
|
||||
|
||||
/**
|
||||
* Regresa el número limpio, sin @x.xxx
|
||||
* @param {*} from
|
||||
* @returns
|
||||
*/
|
||||
function soloNumero(from){
|
||||
let soloNum
|
||||
if(provider == 'baileys'){soloNum = from.replace('@s.whatsapp.net', '')}
|
||||
else if(provider == 'wwebjs'){soloNum = from.replace('@c.us', '')}
|
||||
return soloNum
|
||||
}
|
||||
|
||||
/**
|
||||
* Agrega las variables msg, body, from, hasMedia, name y numero al objeto del cliente.
|
||||
* @param {*} client
|
||||
* @param {*} msg
|
||||
* @param {*} vars
|
||||
* @returns
|
||||
*/
|
||||
function agregaVars(client, msg, vars){
|
||||
const { from, body, name, hasMedia } = vars
|
||||
client.theMsg = msg;
|
||||
client.theMsg['body'] = body
|
||||
client.theMsg['from'] = from
|
||||
client.theMsg['hasMedia'] = hasMedia
|
||||
client.theMsg['name'] = name
|
||||
client.theMsg['number'] = soloNumero(from)
|
||||
return client
|
||||
}
|
||||
|
||||
async function variousFuncs(){
|
||||
/**
|
||||
* Trae información desde un archivo de excel y le manda a cada número un mensaje. (Envío masivo)
|
||||
*/
|
||||
if(body=='traeXLS'){
|
||||
const rows = await leeXLSDatos('x')
|
||||
console.log("RESULTADOS:")
|
||||
function sleep(ms) { return new Promise(resolve => setTimeout(resolve, ms)) }
|
||||
async function retardo() {
|
||||
for (sp=1;sp<rows.length;sp++) {
|
||||
// console.log(masivo[sp].numero+"@c.us");
|
||||
var rnd = getRandomInt(1,7); // Random entre 1 y 6 segundos.
|
||||
if(sp % 15 === 0){console.log("******** VAN 15, HACEMOS PAUSA DE 10 SEGUNDOS ********"); await sleep(10000);} //
|
||||
console.log(`============= Mandamos el mensaje ${sp} ==============`);
|
||||
var elTextoDelMensaje = `%saludo% ${rows[sp].prefijo} *${rows[sp].nombre}* con CARNET *${rows[sp].carnet}*, le saludamos de _CORPORACION AZUL_ le escribimos para recordarle que tiene un pago *pendiente* que se vence el *02/02/2023*`;
|
||||
await sleep(500);
|
||||
// let elNumero = '51968016860@c.us'
|
||||
let elNumero = '5215554192439@c.us'
|
||||
client.sendMessage(elNumero, remplazos(elTextoDelMensaje, client));
|
||||
console.log(`Esperamos ${rnd} segundos...`);
|
||||
await sleep(rnd*1000);
|
||||
}
|
||||
console.log('Terminamos');
|
||||
}
|
||||
retardo();
|
||||
}
|
||||
|
||||
/*
|
||||
============================================================================
|
||||
========================== ENVIO MASIVO (JSON)) =========================
|
||||
============================================================================
|
||||
*/
|
||||
if(message=='/spam'){
|
||||
const masivo = require('./spam.json')
|
||||
var saludo;
|
||||
var caritas;
|
||||
function sleep(ms) {
|
||||
return new Promise(resolve => setTimeout(resolve, ms));
|
||||
}
|
||||
async function retardo() {
|
||||
for (sp=0;sp<masivo.length;sp++) {
|
||||
console.log(masivo[sp].numero+"@c.us");
|
||||
var rnd = getRandomInt(1,7); // Random entre 1 y 6 segundos.
|
||||
if(rnd==1||rnd==4){saludo = "Hola ";}
|
||||
else if(rnd==2||rnd==5){saludo = "Saludos ";}
|
||||
else {saludo = "%saludo% ";}
|
||||
if(rnd==1){caritas = "👨🏻🦰👩🏻🦰";}
|
||||
else if(rnd==2){caritas = "👩🏻🦰👨🏻🦰";}
|
||||
else if(rnd==3){caritas = "🧔🏽👧🏽";}
|
||||
else if(rnd==4){caritas = "👧🏽🧔🏽";}
|
||||
else if(rnd==5){caritas = "👩🏻🦰🧔🏽";}
|
||||
else if(rnd==6){caritas = "🧔🏽👩🏻🦰";}s
|
||||
if(sp % 15 === 0){console.log("******** VAN 15, HACEMOS PAUSA DE 10 SEGUNDOS ********"); await sleep(10000);} //
|
||||
console.log(`============= Mandamos el mensaje ${sp} ==============`);
|
||||
var elTextoDelMensaje = caritas + " *" + saludo + "amigo tendero* ❗❗👋🏻\n🕊️ *GUNA* trae para ti dinámicas digitales, con las que podrás participar para ganar increíbles premios. 🏆💸💰\nSigue los siguientes pasos: 😃\n*1.* 📲Sigue la página de Yo Soy Guna en Facebook en la siguiente liga ➡️ https://www.facebook.com/yosoyguna\n*2.* 👉🏻Es importante des click en el botón Me Gusta 👍\n*3.* 🧐Sigue la dinámica que publicaremos , subiendo tu foto 📸 con los siguientes #yosoyguna #gunatenderos #gunachampions\n*4.* 🥳🎉En esta misma página , podrás ver publicados los ganadores🏅 y el tiempo en que serán elegidos. 💲 Además de tener acceso a increíbles promociones 🤑";
|
||||
sendMedia(client, masivo[sp].numero+"@c.us", "envioMasivoGuna.jpg");
|
||||
await sleep(500);
|
||||
client.sendMessage(masivo[sp].numero+"@c.us", remplazos(elTextoDelMensaje, client));
|
||||
// client.sendMessage(masivo[i].numero+"@c.us", "Este es un mensaje de prueba para *"+masivo[i].numero+"*, HORA:*"+new Date().toLocaleTimeString()+"*");
|
||||
console.log(`Esperamos ${rnd} segundos...`);
|
||||
await sleep(rnd*1000);
|
||||
}
|
||||
console.log('Done');
|
||||
}
|
||||
retardo();
|
||||
}
|
||||
|
||||
if(body == "/botones"){
|
||||
// Asi se mandan botones **directamente** con el cliente de whatsapp-web.js "client.sendMessage(from, productList)"
|
||||
const buttonMessage = [
|
||||
{"body":"boton 1"},
|
||||
{"body":"boton 2"}
|
||||
]
|
||||
const ab = {
|
||||
"title":"¿Que te interesa ver?",
|
||||
"message":"%saludo%\nHoy es %dia_semana%.\nSon las %hora24%:%minutos% hrs.\nSon las %hora12%:%minutos% %ampm%\n*Palabra random:* %rnd_arbol,burro,cabra,dinosaurio,elefante,fuego,gorila%\n*Emoji random:* %rnd_👍🏽,😁,🤣,🤔,🤦🏽♂️,🙄,😎%\n*Número random:* %rnd_1,2,3,4,5,6,7%\n",
|
||||
"footer":"Gracias",
|
||||
"buttons":[
|
||||
{"body":"Cursos"},
|
||||
{"body":"Youtube"},
|
||||
{"body":"Telegram"}
|
||||
]
|
||||
}
|
||||
console.log("Enviamos botones = ", from, ab)
|
||||
sendMessageButton(client, from, "texto", ab)
|
||||
}
|
||||
|
||||
if(body=='/listas'){
|
||||
// Asi se mandan **listas** directamente con el ciente de whatsapp-web.js "client.sendMessage(from, productList)"
|
||||
const productList = new List(
|
||||
"Here's our list of products at 50% off",
|
||||
"View all products",
|
||||
[
|
||||
{
|
||||
title: "Products list",
|
||||
rows: [
|
||||
{ id: "apple", title: "Apple" },
|
||||
{ id: "mango", title: "Mango" },
|
||||
{ id: "banana", title: "Banana" },
|
||||
],
|
||||
},
|
||||
],
|
||||
"Please select a product"
|
||||
);
|
||||
console.log('##################################################################################################')
|
||||
console.log("****************** productList ******************")
|
||||
console.log(productList)
|
||||
client.sendMessage(from, productList);
|
||||
// Asi se manda directamente con la funcion del bot. "sendMessageList(client, from, null, lista)"
|
||||
// let sections = [
|
||||
// { title:'sectionTitle',
|
||||
// rows:[
|
||||
// {id:'ListItem1', title: 'title1'},
|
||||
// {id:'ListItem2', title:'title2'}
|
||||
// ]
|
||||
// }
|
||||
// ];
|
||||
// let lista = new List('List body','btnText',sections,'Title','footer');
|
||||
await sendMessageList(client, from, null, productList); //sendMessageList recibe el arreglo CON nombres, tal cual se usa en "response.json"
|
||||
}
|
||||
}
|
||||
/*
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
var defaultDiacriticsRemovalMap = [ //MOD by CHV - Agregamos para eliminar acentos
|
||||
{'base':'A', 'letters':'\u0041\u24B6\uFF21\u00C0\u00C1\u00C2\u1EA6\u1EA4\u1EAA\u1EA8\u00C3\u0100\u0102\u1EB0\u1EAE\u1EB4\u1EB2\u0226\u01E0\u00C4\u01DE\u1EA2\u00C5\u01FA\u01CD\u0200\u0202\u1EA0\u1EAC\u1EB6\u1E00\u0104\u023A\u2C6F'},
|
||||
{'base':'AA','letters':'\uA732'},
|
||||
{'base':'AE','letters':'\u00C6\u01FC\u01E2'},
|
||||
{'base':'AO','letters':'\uA734'},
|
||||
{'base':'AU','letters':'\uA736'},
|
||||
{'base':'AV','letters':'\uA738\uA73A'},
|
||||
{'base':'AY','letters':'\uA73C'},
|
||||
{'base':'B', 'letters':'\u0042\u24B7\uFF22\u1E02\u1E04\u1E06\u0243\u0182\u0181'},
|
||||
{'base':'C', 'letters':'\u0043\u24B8\uFF23\u0106\u0108\u010A\u010C\u00C7\u1E08\u0187\u023B\uA73E'},
|
||||
{'base':'D', 'letters':'\u0044\u24B9\uFF24\u1E0A\u010E\u1E0C\u1E10\u1E12\u1E0E\u0110\u018B\u018A\u0189\uA779\u00D0'},
|
||||
{'base':'DZ','letters':'\u01F1\u01C4'},
|
||||
{'base':'Dz','letters':'\u01F2\u01C5'},
|
||||
{'base':'E', 'letters':'\u0045\u24BA\uFF25\u00C8\u00C9\u00CA\u1EC0\u1EBE\u1EC4\u1EC2\u1EBC\u0112\u1E14\u1E16\u0114\u0116\u00CB\u1EBA\u011A\u0204\u0206\u1EB8\u1EC6\u0228\u1E1C\u0118\u1E18\u1E1A\u0190\u018E'},
|
||||
{'base':'F', 'letters':'\u0046\u24BB\uFF26\u1E1E\u0191\uA77B'},
|
||||
{'base':'G', 'letters':'\u0047\u24BC\uFF27\u01F4\u011C\u1E20\u011E\u0120\u01E6\u0122\u01E4\u0193\uA7A0\uA77D\uA77E'},
|
||||
{'base':'H', 'letters':'\u0048\u24BD\uFF28\u0124\u1E22\u1E26\u021E\u1E24\u1E28\u1E2A\u0126\u2C67\u2C75\uA78D'},
|
||||
{'base':'I', 'letters':'\u0049\u24BE\uFF29\u00CC\u00CD\u00CE\u0128\u012A\u012C\u0130\u00CF\u1E2E\u1EC8\u01CF\u0208\u020A\u1ECA\u012E\u1E2C\u0197'},
|
||||
{'base':'J', 'letters':'\u004A\u24BF\uFF2A\u0134\u0248'},
|
||||
{'base':'K', 'letters':'\u004B\u24C0\uFF2B\u1E30\u01E8\u1E32\u0136\u1E34\u0198\u2C69\uA740\uA742\uA744\uA7A2'},
|
||||
{'base':'L', 'letters':'\u004C\u24C1\uFF2C\u013F\u0139\u013D\u1E36\u1E38\u013B\u1E3C\u1E3A\u0141\u023D\u2C62\u2C60\uA748\uA746\uA780'},
|
||||
{'base':'LJ','letters':'\u01C7'},
|
||||
{'base':'Lj','letters':'\u01C8'},
|
||||
{'base':'M', 'letters':'\u004D\u24C2\uFF2D\u1E3E\u1E40\u1E42\u2C6E\u019C'},
|
||||
{'base':'N', 'letters':'\u004E\u24C3\uFF2E\u01F8\u0143\u00D1\u1E44\u0147\u1E46\u0145\u1E4A\u1E48\u0220\u019D\uA790\uA7A4'},
|
||||
{'base':'NJ','letters':'\u01CA'},
|
||||
{'base':'Nj','letters':'\u01CB'},
|
||||
{'base':'O', 'letters':'\u004F\u24C4\uFF2F\u00D2\u00D3\u00D4\u1ED2\u1ED0\u1ED6\u1ED4\u00D5\u1E4C\u022C\u1E4E\u014C\u1E50\u1E52\u014E\u022E\u0230\u00D6\u022A\u1ECE\u0150\u01D1\u020C\u020E\u01A0\u1EDC\u1EDA\u1EE0\u1EDE\u1EE2\u1ECC\u1ED8\u01EA\u01EC\u00D8\u01FE\u0186\u019F\uA74A\uA74C'},
|
||||
{'base':'OI','letters':'\u01A2'},
|
||||
{'base':'OO','letters':'\uA74E'},
|
||||
{'base':'OU','letters':'\u0222'},
|
||||
{'base':'OE','letters':'\u008C\u0152'},
|
||||
{'base':'oe','letters':'\u009C\u0153'},
|
||||
{'base':'P', 'letters':'\u0050\u24C5\uFF30\u1E54\u1E56\u01A4\u2C63\uA750\uA752\uA754'},
|
||||
{'base':'Q', 'letters':'\u0051\u24C6\uFF31\uA756\uA758\u024A'},
|
||||
{'base':'R', 'letters':'\u0052\u24C7\uFF32\u0154\u1E58\u0158\u0210\u0212\u1E5A\u1E5C\u0156\u1E5E\u024C\u2C64\uA75A\uA7A6\uA782'},
|
||||
{'base':'S', 'letters':'\u0053\u24C8\uFF33\u1E9E\u015A\u1E64\u015C\u1E60\u0160\u1E66\u1E62\u1E68\u0218\u015E\u2C7E\uA7A8\uA784'},
|
||||
{'base':'T', 'letters':'\u0054\u24C9\uFF34\u1E6A\u0164\u1E6C\u021A\u0162\u1E70\u1E6E\u0166\u01AC\u01AE\u023E\uA786'},
|
||||
{'base':'TZ','letters':'\uA728'},
|
||||
{'base':'U', 'letters':'\u0055\u24CA\uFF35\u00D9\u00DA\u00DB\u0168\u1E78\u016A\u1E7A\u016C\u00DC\u01DB\u01D7\u01D5\u01D9\u1EE6\u016E\u0170\u01D3\u0214\u0216\u01AF\u1EEA\u1EE8\u1EEE\u1EEC\u1EF0\u1EE4\u1E72\u0172\u1E76\u1E74\u0244'},
|
||||
{'base':'V', 'letters':'\u0056\u24CB\uFF36\u1E7C\u1E7E\u01B2\uA75E\u0245'},
|
||||
{'base':'VY','letters':'\uA760'},
|
||||
{'base':'W', 'letters':'\u0057\u24CC\uFF37\u1E80\u1E82\u0174\u1E86\u1E84\u1E88\u2C72'},
|
||||
{'base':'X', 'letters':'\u0058\u24CD\uFF38\u1E8A\u1E8C'},
|
||||
{'base':'Y', 'letters':'\u0059\u24CE\uFF39\u1EF2\u00DD\u0176\u1EF8\u0232\u1E8E\u0178\u1EF6\u1EF4\u01B3\u024E\u1EFE'},
|
||||
{'base':'Z', 'letters':'\u005A\u24CF\uFF3A\u0179\u1E90\u017B\u017D\u1E92\u1E94\u01B5\u0224\u2C7F\u2C6B\uA762'},
|
||||
{'base':'a', 'letters':'\u0061\u24D0\uFF41\u1E9A\u00E0\u00E1\u00E2\u1EA7\u1EA5\u1EAB\u1EA9\u00E3\u0101\u0103\u1EB1\u1EAF\u1EB5\u1EB3\u0227\u01E1\u00E4\u01DF\u1EA3\u00E5\u01FB\u01CE\u0201\u0203\u1EA1\u1EAD\u1EB7\u1E01\u0105\u2C65\u0250'},
|
||||
{'base':'aa','letters':'\uA733'},
|
||||
{'base':'ae','letters':'\u00E6\u01FD\u01E3'},
|
||||
{'base':'ao','letters':'\uA735'},
|
||||
{'base':'au','letters':'\uA737'},
|
||||
{'base':'av','letters':'\uA739\uA73B'},
|
||||
{'base':'ay','letters':'\uA73D'},
|
||||
{'base':'b', 'letters':'\u0062\u24D1\uFF42\u1E03\u1E05\u1E07\u0180\u0183\u0253'},
|
||||
{'base':'c', 'letters':'\u0063\u24D2\uFF43\u0107\u0109\u010B\u010D\u00E7\u1E09\u0188\u023C\uA73F\u2184'},
|
||||
{'base':'d', 'letters':'\u0064\u24D3\uFF44\u1E0B\u010F\u1E0D\u1E11\u1E13\u1E0F\u0111\u018C\u0256\u0257\uA77A'},
|
||||
{'base':'dz','letters':'\u01F3\u01C6'},
|
||||
{'base':'e', 'letters':'\u0065\u24D4\uFF45\u00E8\u00E9\u00EA\u1EC1\u1EBF\u1EC5\u1EC3\u1EBD\u0113\u1E15\u1E17\u0115\u0117\u00EB\u1EBB\u011B\u0205\u0207\u1EB9\u1EC7\u0229\u1E1D\u0119\u1E19\u1E1B\u0247\u025B\u01DD'},
|
||||
{'base':'f', 'letters':'\u0066\u24D5\uFF46\u1E1F\u0192\uA77C'},
|
||||
{'base':'g', 'letters':'\u0067\u24D6\uFF47\u01F5\u011D\u1E21\u011F\u0121\u01E7\u0123\u01E5\u0260\uA7A1\u1D79\uA77F'},
|
||||
{'base':'h', 'letters':'\u0068\u24D7\uFF48\u0125\u1E23\u1E27\u021F\u1E25\u1E29\u1E2B\u1E96\u0127\u2C68\u2C76\u0265'},
|
||||
{'base':'hv','letters':'\u0195'},
|
||||
{'base':'i', 'letters':'\u0069\u24D8\uFF49\u00EC\u00ED\u00EE\u0129\u012B\u012D\u00EF\u1E2F\u1EC9\u01D0\u0209\u020B\u1ECB\u012F\u1E2D\u0268\u0131'},
|
||||
{'base':'j', 'letters':'\u006A\u24D9\uFF4A\u0135\u01F0\u0249'},
|
||||
{'base':'k', 'letters':'\u006B\u24DA\uFF4B\u1E31\u01E9\u1E33\u0137\u1E35\u0199\u2C6A\uA741\uA743\uA745\uA7A3'},
|
||||
{'base':'l', 'letters':'\u006C\u24DB\uFF4C\u0140\u013A\u013E\u1E37\u1E39\u013C\u1E3D\u1E3B\u017F\u0142\u019A\u026B\u2C61\uA749\uA781\uA747'},
|
||||
{'base':'lj','letters':'\u01C9'},
|
||||
{'base':'m', 'letters':'\u006D\u24DC\uFF4D\u1E3F\u1E41\u1E43\u0271\u026F'},
|
||||
{'base':'n', 'letters':'\u006E\u24DD\uFF4E\u01F9\u0144\u00F1\u1E45\u0148\u1E47\u0146\u1E4B\u1E49\u019E\u0272\u0149\uA791\uA7A5'},
|
||||
{'base':'nj','letters':'\u01CC'},
|
||||
{'base':'o', 'letters':'\u006F\u24DE\uFF4F\u00F2\u00F3\u00F4\u1ED3\u1ED1\u1ED7\u1ED5\u00F5\u1E4D\u022D\u1E4F\u014D\u1E51\u1E53\u014F\u022F\u0231\u00F6\u022B\u1ECF\u0151\u01D2\u020D\u020F\u01A1\u1EDD\u1EDB\u1EE1\u1EDF\u1EE3\u1ECD\u1ED9\u01EB\u01ED\u00F8\u01FF\u0254\uA74B\uA74D\u0275'},
|
||||
{'base':'oi','letters':'\u01A3'},
|
||||
{'base':'ou','letters':'\u0223'},
|
||||
{'base':'oo','letters':'\uA74F'},
|
||||
{'base':'p','letters':'\u0070\u24DF\uFF50\u1E55\u1E57\u01A5\u1D7D\uA751\uA753\uA755'},
|
||||
{'base':'q','letters':'\u0071\u24E0\uFF51\u024B\uA757\uA759'},
|
||||
{'base':'r','letters':'\u0072\u24E1\uFF52\u0155\u1E59\u0159\u0211\u0213\u1E5B\u1E5D\u0157\u1E5F\u024D\u027D\uA75B\uA7A7\uA783'},
|
||||
{'base':'s','letters':'\u0073\u24E2\uFF53\u00DF\u015B\u1E65\u015D\u1E61\u0161\u1E67\u1E63\u1E69\u0219\u015F\u023F\uA7A9\uA785\u1E9B'},
|
||||
{'base':'t','letters':'\u0074\u24E3\uFF54\u1E6B\u1E97\u0165\u1E6D\u021B\u0163\u1E71\u1E6F\u0167\u01AD\u0288\u2C66\uA787'},
|
||||
{'base':'tz','letters':'\uA729'},
|
||||
{'base':'u','letters': '\u0075\u24E4\uFF55\u00F9\u00FA\u00FB\u0169\u1E79\u016B\u1E7B\u016D\u00FC\u01DC\u01D8\u01D6\u01DA\u1EE7\u016F\u0171\u01D4\u0215\u0217\u01B0\u1EEB\u1EE9\u1EEF\u1EED\u1EF1\u1EE5\u1E73\u0173\u1E77\u1E75\u0289'},
|
||||
{'base':'v','letters':'\u0076\u24E5\uFF56\u1E7D\u1E7F\u028B\uA75F\u028C'},
|
||||
{'base':'vy','letters':'\uA761'},
|
||||
{'base':'w','letters':'\u0077\u24E6\uFF57\u1E81\u1E83\u0175\u1E87\u1E85\u1E98\u1E89\u2C73'},
|
||||
{'base':'x','letters':'\u0078\u24E7\uFF58\u1E8B\u1E8D'},
|
||||
{'base':'y','letters':'\u0079\u24E8\uFF59\u1EF3\u00FD\u0177\u1EF9\u0233\u1E8F\u00FF\u1EF7\u1E99\u1EF5\u01B4\u024F\u1EFF'},
|
||||
{'base':'z','letters':'\u007A\u24E9\uFF5A\u017A\u1E91\u017C\u017E\u1E93\u1E95\u01B6\u0225\u0240\u2C6C\uA763'}
|
||||
];
|
||||
|
||||
var diacriticsMap = {};
|
||||
for (var i=0; i < defaultDiacriticsRemovalMap .length; i++){
|
||||
var letters = defaultDiacriticsRemovalMap [i].letters;
|
||||
for (var j=0; j < letters.length ; j++){
|
||||
diacriticsMap[letters[j]] = defaultDiacriticsRemovalMap [i].base;
|
||||
}
|
||||
}
|
||||
|
||||
// "what?" version ... http://jsperf.com/diacritics/12
|
||||
function removeDiacritics(str) {
|
||||
if (str !== undefined) {
|
||||
return str.replace(/[^\u0000-\u007E]/g, function (a) {
|
||||
return diacriticsMap[a] || a;
|
||||
});
|
||||
}
|
||||
else { return "" }
|
||||
}
|
||||
// var paragraph = "L'avantage d'utiliser le lorem ipsum est bien évidemment de pouvoir créer des maquettes ou de remplir un site internet de contenus qui présentent un rendu s'approchant un maximum du rendu final. \n Par défaut lorem ipsum ne contient pas d'accent ni de caractères spéciaux contrairement à la langue française qui en contient beaucoup. C'est sur ce critère que nous proposons une solution avec cet outil qui générant du faux-texte lorem ipsum mais avec en plus, des caractères spéciaux tel que les accents ou certains symboles utiles pour la langue française. \n L'utilisation du lorem standard est facile d’utilisation mais lorsque le futur client utilisera votre logiciel il se peut que certains caractères spéciaux ou qu'un accent ne soient pas codés correctement. \n Cette page a pour but donc de pouvoir perdre le moins de temps possible et donc de tester directement si tous les encodages de base de donnée ou des sites sont les bons de plus il permet de récuperer un code css avec le texte formaté !";
|
||||
// alert(removeDiacritics(paragraph));
|
||||
|
||||
module.exports = { removeDiacritics, traeMensajes, chkFile, getRandomInt, remplazos, soloNumero, agregaVars, traeVariablesFromClient, traeVariablesFromMsg }
|
||||
@@ -5,7 +5,7 @@ const RESPONSES_SHEET_ID = '1tVRX1ojXJadsjRUJ-pNv8DZgziaIMcAdsMtPmWQRBcM'; //Ge
|
||||
const doc = new GoogleSpreadsheet(RESPONSES_SHEET_ID);
|
||||
const CREDENTIALS = JSON.parse(fs.readFileSync('./implementaciones/credenciales.json'));
|
||||
|
||||
async function ingresarDatos(numero, mensaje, sentido){
|
||||
async function ingresarDatos(numero, mensaje){
|
||||
let Fecha = getDate();
|
||||
let Hora = getTime(Date.now(), {local: 'es-MX', timeZone: 'America/Mexico_City', hour12:false});
|
||||
elNum = numero.replace('@c.us', '')
|
||||
@@ -13,27 +13,34 @@ async function ingresarDatos(numero, mensaje, sentido){
|
||||
let rows = [{
|
||||
Numero: elNum.trim(),
|
||||
Mensaje: mensaje,
|
||||
Sentido: sentido,
|
||||
Fecha: Fecha,
|
||||
Hora: Hora
|
||||
}];
|
||||
try{
|
||||
await doc.useServiceAccountAuth({
|
||||
client_email: CREDENTIALS.client_email,
|
||||
private_key: CREDENTIALS.private_key
|
||||
});
|
||||
await doc.loadInfo();
|
||||
let sheet = doc.sheetsByTitle['Mensajes'];
|
||||
// console.log("SHEET=", sheet)
|
||||
for (let index = 0; index < rows.length; index++) {
|
||||
const row = rows[index];
|
||||
await sheet.addRow(row);
|
||||
console.log(`Datos guardados - ${sentido} (sheets.js)`)
|
||||
}
|
||||
}
|
||||
catch{
|
||||
console.log("Error Sheets")
|
||||
await doc.useServiceAccountAuth({
|
||||
client_email: CREDENTIALS.client_email,
|
||||
private_key: CREDENTIALS.private_key
|
||||
});
|
||||
await doc.loadInfo();
|
||||
let sheet = doc.sheetsByTitle['Mensajes'];
|
||||
// console.log("SHEET=", sheet)
|
||||
for (let index = 0; index < rows.length; index++) {
|
||||
const row = rows[index];
|
||||
await sheet.addRow(row);
|
||||
console.log("Datos guardados (sheets.js)")
|
||||
}
|
||||
// console.log('Fecha:',Fecha,);
|
||||
// console.log('Hora:',Hora);
|
||||
// console.log('Nombre:',nombre);
|
||||
// console.log('Apellidos:',apellido);
|
||||
// console.log('Direccion:',direccion);
|
||||
// console.log('Planta:',planta);
|
||||
// console.log('Codigo Postal:',CP);
|
||||
// console.log('Descripcion:',descripcion);
|
||||
// console.log('Telefono:',telsim);
|
||||
// console.log('Horario deseado:',horario);
|
||||
// console.log('ID_Solicitud: ',ID_Solicitud);
|
||||
// console.log('Estado: ',Estado)
|
||||
// console.log('-----------------------------------');
|
||||
}
|
||||
|
||||
async function leerDatos(telsim){
|
||||
|
||||
125
initBailey.js
125
initBailey.js
@@ -1,125 +0,0 @@
|
||||
const baileysReq = require ('@adiwajshing/baileys')
|
||||
var pino = require('pino');
|
||||
const { createWriteStream } = require('fs')
|
||||
var combineImage = require('combine-image');
|
||||
const {
|
||||
default: makeWASocket,
|
||||
useMultiFileAuthState,
|
||||
Browsers,
|
||||
DisconnectReason,
|
||||
} = baileysReq
|
||||
const globalVendorArgs = { name: `bot` }
|
||||
var qr = require('qr-image');
|
||||
|
||||
/**
|
||||
* Hace promesa el write
|
||||
* @param {*} base64
|
||||
*/
|
||||
const baileyGenerateImage = async (base64, name = 'bot.qr.png') => {
|
||||
const PATH_QR = `${process.cwd()}/public/${name}`;
|
||||
let qr_svg = qr.image(base64, { type: 'png', margin: 4 });
|
||||
|
||||
const writeFilePromise = () =>
|
||||
new Promise((resolve, reject) => {
|
||||
const file = qr_svg.pipe(createWriteStream(PATH_QR));
|
||||
file.on('finish', () => resolve(true));
|
||||
file.on('error', reject);
|
||||
});
|
||||
|
||||
await writeFilePromise();
|
||||
|
||||
const cleanImage = await combineImage([PATH_QR], {
|
||||
margin: 15,
|
||||
color: 0xffffffff,
|
||||
});
|
||||
cleanImage.write(PATH_QR);
|
||||
};
|
||||
|
||||
|
||||
function listenMessage(client){
|
||||
client.ev.on('messages.upsert', async msg => {
|
||||
console.log('M=', msg)
|
||||
console.log('replying to', msg.messages[0])
|
||||
// await sock.sendMessage(m.messages[0].key.remoteJid, { text: 'hola como estas' })
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Iniciar todo Bailey
|
||||
*/
|
||||
initBailey = async () => {
|
||||
const NAME_DIR_SESSION = `baileys_sessions`;
|
||||
const { state, saveCreds } = await useMultiFileAuthState(
|
||||
NAME_DIR_SESSION
|
||||
);
|
||||
saveCredsGlobal = saveCreds;
|
||||
const sock = makeWASocket({
|
||||
// can provide additional config here
|
||||
printQRInTerminal: true,
|
||||
auth: state,
|
||||
browser: Browsers.macOS('Desktop'),
|
||||
syncFullHistory: false,
|
||||
logger: pino({ level: 'error' }),
|
||||
})
|
||||
try {
|
||||
sock.ev.on('connection.update', async (update) => {
|
||||
const { connection, lastDisconnect, qr } = update;
|
||||
const statusCode = lastDisconnect?.error?.output?.statusCode;
|
||||
if(connection === 'close') {
|
||||
if (statusCode !== DisconnectReason.loggedOut) {
|
||||
initBailey();
|
||||
}
|
||||
if (statusCode === DisconnectReason.loggedOut) {
|
||||
const PATH_BASE = join(process.cwd(), NAME_DIR_SESSION);
|
||||
rimraf(PATH_BASE, (err) => {
|
||||
if (err) return
|
||||
});
|
||||
initBailey();
|
||||
}
|
||||
}
|
||||
/** Conexion abierta correctamente */
|
||||
if (connection === 'open') {
|
||||
console.log('ready', true);
|
||||
// initBusEvents(sock);
|
||||
}
|
||||
/** QR Code */
|
||||
if (qr) {
|
||||
console.log('require_action', {
|
||||
instructions: [
|
||||
`Debes escanear el QR Code para iniciar bot.qr.png`,
|
||||
`Recuerda que el QR se actualiza cada minuto `,
|
||||
`Necesitas ayuda: https://link.codigoencasa.com/DISCORD`,
|
||||
],
|
||||
});
|
||||
await baileyGenerateImage(
|
||||
qr,
|
||||
`bot.qr.png`
|
||||
);
|
||||
}
|
||||
});
|
||||
sock.ev.on('creds.update', async () => {
|
||||
await saveCreds();
|
||||
});
|
||||
} catch (e) {
|
||||
// logger.log(e);
|
||||
console.log('auth_failure', [
|
||||
`Algo inesperado ha ocurrido NO entres en pánico`,
|
||||
`Reinicia el BOT`,
|
||||
`Tambien puedes mirar un log que se ha creado baileys.log`,
|
||||
`Necesitas ayuda: https://link.codigoencasa.com/DISCORD`,
|
||||
`(Puedes abrir un ISSUE) https://github.com/codigoencasa/bot-whatsapp/issues/new/choose`,
|
||||
]);
|
||||
}
|
||||
listenMessage(sock)
|
||||
// sock.ev.on('messages.upsert', async (m) => {
|
||||
// console.log('M=', m)
|
||||
// console.log('replying to', m.messages[0])
|
||||
// // await sock.sendMessage(m.messages[0].key.remoteJid, { text: 'hola como estas' })
|
||||
// })
|
||||
}
|
||||
// run in main file
|
||||
initBailey()
|
||||
|
||||
|
||||
module.exports = { initBailey, listenMessage, baileyGenerateImage }
|
||||
@@ -3,7 +3,7 @@ const middlewareClient = (client = null) => async (req, res, next) => {
|
||||
|
||||
if(!client){
|
||||
res.status(409)
|
||||
// console.log(client)
|
||||
console.log(client)
|
||||
res.send({ error: 'Error de client.' })
|
||||
}else{
|
||||
req.clientWs = client;
|
||||
|
||||
3393
package-lock.json
generated
3393
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -11,27 +11,21 @@
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@adiwajshing/baileys": "^4.4.0",
|
||||
"@google-cloud/dialogflow": "^5.2.0",
|
||||
"axios": "^0.27.2",
|
||||
"combine-image": "^1.0.3",
|
||||
"cors": "^2.8.5",
|
||||
"dotenv": "^16.0.1",
|
||||
"exceljs": "^4.3.0",
|
||||
"express": "^4.18.1",
|
||||
"express-fileupload": "^1.4.0",
|
||||
"express-validator": "^6.15.0",
|
||||
"file-type": "^17.1.6",
|
||||
"google-spreadsheet": "^3.3.0",
|
||||
"googleapis": "^109.0.1",
|
||||
"mime-db": "^1.52.0",
|
||||
"moment": "^2.29.4",
|
||||
"mysql": "^2.18.1",
|
||||
"open": "^8.4.2",
|
||||
"pb-util": "^1.0.3",
|
||||
"qr-image": "^3.2.0",
|
||||
"qrcode-terminal": "^0.12.0",
|
||||
"react-dev-utils": "^12.0.1",
|
||||
"socket.io": "^4.5.1",
|
||||
"stormdb": "^0.6.0",
|
||||
"util-tiempo": "^1.0.41",
|
||||
|
||||
@@ -1,116 +0,0 @@
|
||||
const { default: makeWASocket, useMultiFileAuthState, Browsers, DisconnectReason } = require ('@adiwajshing/baileys')
|
||||
// const { traeVariablesFromMsg, traeVariablesFromClient } = require('../implementaciones/extraFuncs')
|
||||
var pino = require('pino');
|
||||
const { createWriteStream } = require('fs')
|
||||
var combineImage = require('combine-image');
|
||||
const { path, join } = require('path');
|
||||
const rimraf = require('rimraf')
|
||||
// function listenMessage(client){
|
||||
// client.on('messages.upsert', async msg => {
|
||||
// console.log('MSG=', msg)
|
||||
// console.log('REPLY TO=', msg.messages[0])
|
||||
// // await sock.sendMessage(m.messages[0].key.remoteJid, { text: 'hola como estas' })
|
||||
// })
|
||||
// }
|
||||
|
||||
// const { default: makeWASocket, useMultiFileAuthState, Browsers, DisconnectReason } = baileysReq
|
||||
const globalVendorArgs = { name: `bot` }
|
||||
var qr = require('qr-image');
|
||||
|
||||
/**
|
||||
* Hace promesa el write
|
||||
* @param {*} base64
|
||||
*/
|
||||
const baileyGenerateImage = async (base64, name = 'bot.qr.png') => {
|
||||
const PATH_QR = `${process.cwd()}/public/${name}`;
|
||||
let qr_svg = qr.image(base64, { type: 'png', margin: 4 });
|
||||
|
||||
const writeFilePromise = () =>
|
||||
new Promise((resolve, reject) => {
|
||||
const file = qr_svg.pipe(createWriteStream(PATH_QR));
|
||||
file.on('finish', () => resolve(true));
|
||||
file.on('error', reject);
|
||||
});
|
||||
|
||||
await writeFilePromise();
|
||||
|
||||
const cleanImage = await combineImage([PATH_QR], {
|
||||
margin: 15,
|
||||
color: 0xffffffff,
|
||||
});
|
||||
cleanImage.write(PATH_QR);
|
||||
};
|
||||
|
||||
/**
|
||||
* Inicializa el Bot con Baileys
|
||||
*/
|
||||
initBot = async () => {
|
||||
console.log("Baileys Init")
|
||||
const NAME_DIR_SESSION = `baileys_sessions`;
|
||||
const { state, saveCreds } = await useMultiFileAuthState(
|
||||
NAME_DIR_SESSION
|
||||
);
|
||||
saveCredsGlobal = saveCreds;
|
||||
const sock = makeWASocket({
|
||||
// can provide additional config here
|
||||
printQRInTerminal: true,
|
||||
auth: state,
|
||||
browser: Browsers.macOS('Desktop'),
|
||||
syncFullHistory: false,
|
||||
logger: pino({ level: 'error' }),
|
||||
})
|
||||
try {
|
||||
sock.ev.on('connection.update', async (update) => {
|
||||
const { connection, lastDisconnect, qr } = update;
|
||||
const statusCode = lastDisconnect?.error?.output?.statusCode;
|
||||
if(connection === 'close') {
|
||||
if (statusCode !== DisconnectReason.loggedOut) {
|
||||
initBot();
|
||||
}
|
||||
if (statusCode === DisconnectReason.loggedOut) {
|
||||
const PATH_BASE = join(process.cwd(), NAME_DIR_SESSION);
|
||||
rimraf(PATH_BASE, (err) => {
|
||||
if (err) return
|
||||
});
|
||||
initBot();
|
||||
}
|
||||
}
|
||||
/** Conexion abierta correctamente */
|
||||
if (connection === 'open') {
|
||||
console.log('ready', true);
|
||||
// initBusEvents(sock);
|
||||
}
|
||||
/** QR Code */
|
||||
if (qr) {
|
||||
console.log('require_action', {
|
||||
instructions: [
|
||||
`Debes escanear el QR Code para iniciar ${globalVendorArgs.name}.qr.png`,
|
||||
`Recuerda que el QR se actualiza cada minuto `,
|
||||
`Necesitas ayuda: https://link.codigoencasa.com/DISCORD`,
|
||||
],
|
||||
});
|
||||
await baileyGenerateImage(qr, `bot.qr.png`);
|
||||
}
|
||||
});
|
||||
sock.ev.on('creds.update', async () => { await saveCreds() });
|
||||
}
|
||||
catch (e) {
|
||||
logger.log(e);
|
||||
console.log('auth_failure', [
|
||||
`Algo inesperado ha ocurrido NO entres en pánico`,
|
||||
`Reinicia el BOT`,
|
||||
`Tambien puedes mirar un log que se ha creado baileys.log`,
|
||||
`Necesitas ayuda: https://link.codigoencasa.com/DISCORD`,
|
||||
`(Puedes abrir un ISSUE) https://github.com/codigoencasa/bot-whatsapp/issues/new/choose`,
|
||||
]);
|
||||
}
|
||||
// listenMessage(sock.ev)
|
||||
return sock
|
||||
}
|
||||
// run in main file
|
||||
// initBot()
|
||||
|
||||
|
||||
|
||||
|
||||
module.exports = { initBot, baileyGenerateImage, makeWASocket }
|
||||
@@ -1,65 +0,0 @@
|
||||
const mimeDep = require('mime-types')
|
||||
const { tmpdir } = require('os')
|
||||
const http = require('http')
|
||||
const https = require('https')
|
||||
const { rename, createWriteStream } = require('fs')
|
||||
|
||||
/**
|
||||
* Extrar el mimetype from buffer
|
||||
* @param {string} response
|
||||
* @returns
|
||||
*/
|
||||
const fileTypeFromFile = async (response) => {
|
||||
const type = response.headers['content-type'] ?? null
|
||||
const ext = mimeDep.extension(type)
|
||||
return {
|
||||
type,
|
||||
ext,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Descargar archivo binay en tmp
|
||||
* @param {*} url
|
||||
* @returns
|
||||
*/
|
||||
const generalDownload = async (url) => {
|
||||
const handleDownload = () => {
|
||||
const checkProtocol = url.includes('https:')
|
||||
const handleHttp = checkProtocol ? https : http
|
||||
const name = `tmp-${Date.now()}-dat`
|
||||
const fullPath = `${tmpdir()}/${name}`
|
||||
const file = createWriteStream(fullPath)
|
||||
|
||||
return new Promise((res, rej) => {
|
||||
handleHttp.get(url, function (response) {
|
||||
response.pipe(file)
|
||||
file.on('finish', async function () {
|
||||
file.close()
|
||||
res({ response, fullPath })
|
||||
})
|
||||
file.on('error', function () {
|
||||
file.close()
|
||||
rej(null)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
const handleFile = (pathInput, ext) =>
|
||||
new Promise((resolve, reject) => {
|
||||
const fullPath = `${pathInput}.${ext}`
|
||||
rename(pathInput, fullPath, (err) => {
|
||||
if (err) reject(null)
|
||||
resolve(fullPath)
|
||||
})
|
||||
})
|
||||
|
||||
const httpResponse = await handleDownload()
|
||||
const { ext } = await fileTypeFromFile(httpResponse.response)
|
||||
const getPath = await handleFile(httpResponse.fullPath, ext)
|
||||
|
||||
return getPath
|
||||
}
|
||||
|
||||
module.exports = { generalDownload }
|
||||
@@ -1,295 +0,0 @@
|
||||
const { MessageMedia, Client, LocalAuth, Buttons, List } = require('whatsapp-web.js');
|
||||
const { sendMedia, sendMessage, sendMessageButton, sendMessageList, readChat } = require(`../controllers/send`);
|
||||
const mime = require('mime-types')
|
||||
// const mysqlConnection = require('./config/mysql')
|
||||
require('dotenv').config()
|
||||
const fs = require('fs');
|
||||
const express = require('express');
|
||||
const bodyParser = require("body-parser");
|
||||
const cors = require('cors')
|
||||
const qrcode = require('qrcode-terminal');
|
||||
const app = express();
|
||||
app.use(cors())
|
||||
app.use(express.json())
|
||||
// Use the express-fileupload middleware
|
||||
const server = require('http').Server(app)
|
||||
const port = process.env.PORT || 3000
|
||||
const { generateImage, checkEnvFile } = require('../controllers/handle')
|
||||
const { connectionReady } = require('../controllers/connection')
|
||||
const { body, validationResult } = require('express-validator');
|
||||
const fileUpload = require('express-fileupload');
|
||||
app.use(fileUpload());
|
||||
app.use('/', require('../routes/web'))
|
||||
|
||||
|
||||
const { Server } = require("socket.io");
|
||||
const io = new Server(server);
|
||||
|
||||
// app.use(bodyParser.json({ limit: "50mb" }));
|
||||
// app.use(cors());
|
||||
app.use(express.json());
|
||||
app.use(bodyParser.urlencoded({ extended: true }));
|
||||
|
||||
let socks
|
||||
let client
|
||||
|
||||
initBot = async () => {
|
||||
console.log("Iniciamos WaWebJS")
|
||||
client = new Client({
|
||||
authStrategy: new LocalAuth(),
|
||||
pup: { headless: true, args: ['--no-sandbox','--disable-setuid-sandbox'] }
|
||||
});
|
||||
client.on('ready', (a) => {
|
||||
connectionReady()
|
||||
// listenMessage(client)
|
||||
// listenMessageFromBot()
|
||||
// socketEvents.sendStatus(client)
|
||||
});
|
||||
client.on('auth_failure', (e) => {
|
||||
// console.log(e)
|
||||
// connectionLost()
|
||||
});
|
||||
client.on('authenticated', () => {
|
||||
console.log('AUTHENTICATED');
|
||||
});
|
||||
|
||||
client.on('qr', qr => generateImage(qr, async () => {
|
||||
qrcode.generate(qr, { small: true });
|
||||
console.log(`Ver QR http://localhost:${port}/bot.qr.png`)
|
||||
}))
|
||||
|
||||
|
||||
client.initialize();
|
||||
|
||||
/**
|
||||
* Verificamos si tienes un gesto de db
|
||||
*/
|
||||
if (process.env.DATABASE === 'mysql') {
|
||||
mysqlConnection.connect()
|
||||
}
|
||||
|
||||
let waReady = false
|
||||
// Socket IO
|
||||
io.on('connection', async function (socket) {
|
||||
// console.log("Conectando ...")
|
||||
socket.emit('ioStatus', socketioStatus);
|
||||
socks = socket
|
||||
await socket.emit('message', 'Conectando...');
|
||||
socket.on('checkConn', async function () { // Si recibe mensaje, regresa "connOk"
|
||||
// console.log("checking conn")
|
||||
await socket.emit('connOk', 'Connected');
|
||||
})
|
||||
|
||||
try {
|
||||
client.on('message', msg => {
|
||||
// console.log(msg)
|
||||
// console.log(waReady)
|
||||
socketioStatus = "wa_msg"; socket.emit('ioStatus', socketioStatus); socket.emit('wa_msg', msg.body);
|
||||
socket.emit('incomming', 'Message In')
|
||||
waReady = true
|
||||
})
|
||||
client.on('qr', qr => generateImage(qr, async () => {
|
||||
socketioStatus = "wa_qr"; socket.emit('ioStatus', socketioStatus);
|
||||
qrcode.generate(qr, { small: true });
|
||||
console.log(`Ver QR http://localhost:${port}/bot.qr.png`)
|
||||
await socket.emit('qr', `http://localhost:${port}/bot.qr.png`);
|
||||
await socket.emit('message', 'QR Code received, scan please!');
|
||||
}))
|
||||
|
||||
client.on('ready', async () => {
|
||||
socketioStatus = "wa_ready"
|
||||
await socket.emit('ready', 'Whatsapp esta listo!');
|
||||
await socket.emit('message', 'Whatsapp está listo!');
|
||||
waReady = true
|
||||
});
|
||||
|
||||
client.on('authenticated', async () => {
|
||||
socketioStatus = "wa_autenticated"; socket.emit('ioStatus', socketioStatus);
|
||||
await socket.emit('authenticated', 'Whatsapp is authenticated!');
|
||||
await socket.emit('message', 'Whatsapp is authenticated!');
|
||||
// console.log('AUTHENTICATED');
|
||||
});
|
||||
|
||||
client.on('auth_failure', async function (session) {
|
||||
await socket.emit('message', 'Auth failure, restarting...');
|
||||
waReady = false
|
||||
});
|
||||
|
||||
client.on('disconnected', async (reason) => {
|
||||
socketioStatus = "wa_disconnected"; socket.emit('ioStatus', socketioStatus);
|
||||
await socket.emit('message', 'Whatsapp is disconnected!');
|
||||
waReady = false
|
||||
// client.destroy();
|
||||
// client.initialize();
|
||||
})
|
||||
}
|
||||
catch (e) {waReady = false }
|
||||
|
||||
});
|
||||
server.listen(port, () => {
|
||||
console.log(`El servidor web esta listo en el puerto ${port} - http://localhost:${port}`);
|
||||
})
|
||||
const phoneNumberFormatter = function (number) {
|
||||
// 1. Eliminar caracteres que no sean números
|
||||
let formatted = number.replace(/\D/g, '');
|
||||
|
||||
// 2. Eliminar el número 0 del prefijo y reemplazarlo con 62
|
||||
// if (formatted.startsWith('0')) {
|
||||
// formatted = '62' + formatted.substr(1);
|
||||
// }
|
||||
|
||||
if (!formatted.endsWith('@c.us')) {
|
||||
formatted += '@c.us';
|
||||
}
|
||||
|
||||
return formatted;
|
||||
}
|
||||
const checkRegisteredNumber = async function (number) {
|
||||
const isRegistered = await client.isRegisteredUser(number);
|
||||
return isRegistered;
|
||||
}
|
||||
// Send message
|
||||
app.post('/send-message', [
|
||||
body('number').notEmpty(),
|
||||
body('message').notEmpty(),
|
||||
], async (req, res) => {
|
||||
// console.log("REQUEST=", req.body)
|
||||
socks.emit('incomming', 'Message In')
|
||||
const errors = validationResult(req).formatWith(({
|
||||
msg
|
||||
}) => {
|
||||
return msg;
|
||||
});
|
||||
if (!errors.isEmpty()) {
|
||||
return res.status(422).json({
|
||||
status: false,
|
||||
message: errors.mapped()
|
||||
});
|
||||
}
|
||||
const number = phoneNumberFormatter(req.body.number);
|
||||
const message = req.body.message;
|
||||
const isRegisteredNumber = await checkRegisteredNumber(number);
|
||||
if (!isRegisteredNumber) {
|
||||
return res.status(422).json({
|
||||
status: false,
|
||||
message: 'The number is not registered'
|
||||
});
|
||||
}
|
||||
client.sendMessage(number, message).then(response => {
|
||||
res.status(200).json({
|
||||
status: true,
|
||||
response: response
|
||||
});
|
||||
}).catch(err => {
|
||||
res.status(500).json({
|
||||
status: false,
|
||||
response: err
|
||||
});
|
||||
});
|
||||
});
|
||||
// Send buttons
|
||||
app.post('/send-buttons', async (req, res) => {
|
||||
// console.log("REQUEST=", req.body)
|
||||
socks.emit('incomming', 'Button In')
|
||||
|
||||
if (client.theMsg === undefined) {
|
||||
client.theMsg = {}
|
||||
client.theMsg.from = "WEB"
|
||||
client.theMsg.body = "WEB"
|
||||
client.theMsg.name = "WEB"
|
||||
}
|
||||
|
||||
const number = phoneNumberFormatter(req.body.number);
|
||||
const title = req.body.title || null;
|
||||
const btnmsg = req.body.btnmsg;
|
||||
const btn1 = req.body.btn1;
|
||||
const btn2 = req.body.btn2 || null;
|
||||
const btn3 = req.body.btn3 || null;
|
||||
const footer = req.body.footer || null;
|
||||
const isRegisteredNumber = await checkRegisteredNumber(number);
|
||||
if (!isRegisteredNumber) {
|
||||
return res.status(422).json({
|
||||
status: false,
|
||||
message: 'The number is not registered'
|
||||
});
|
||||
}
|
||||
let botones = []
|
||||
botones.push({ body: btn1 })
|
||||
if (btn2 != null) { botones.push({ body: btn2 }) }
|
||||
if (btn3 != null) { botones.push({body: btn3}) }
|
||||
let losBotones = new Buttons(btnmsg, botones, title, footer);
|
||||
client.sendMessage(number, losBotones).then(response => {
|
||||
res.status(200).json({
|
||||
status: true,
|
||||
response: response
|
||||
});
|
||||
}).catch(err => {
|
||||
res.status(500).json({
|
||||
status: false,
|
||||
response: err
|
||||
});
|
||||
});
|
||||
});
|
||||
// Send image
|
||||
app.post('/send-image', async (req, res) => {
|
||||
// console.log("REQUEST=", req.body)
|
||||
socks.emit('incomming', 'Image In')
|
||||
const number = phoneNumberFormatter(req.body.number);
|
||||
// const filename = req.body.image || null;
|
||||
const caption = req.body.caption || null;
|
||||
const { image } = req.files;
|
||||
// If no image submitted, exit
|
||||
if (!image) return res.sendStatus(400);
|
||||
// Move the uploaded image to our upload folder
|
||||
image.mv(__dirname + '/../mediaSend/' + image.name);
|
||||
res.sendStatus(200);
|
||||
const isRegisteredNumber = await checkRegisteredNumber(number);
|
||||
if (!isRegisteredNumber) {
|
||||
return res.status(422).json({
|
||||
status: false,
|
||||
message: 'The number is not registered'
|
||||
});
|
||||
}
|
||||
// sendMedia(client, number, image.name, caption)
|
||||
// `${__dirname}/../mediaSend`;
|
||||
const file = `${__dirname}/../mediaSend/${image.name}`;
|
||||
console.log("FILE="+file);
|
||||
if (fs.existsSync(file)) {
|
||||
console.log("ARCHIVO EXISTE");
|
||||
const media = MessageMedia.fromFilePath(file);
|
||||
}
|
||||
const base64 = fs.readFileSync(file, { encoding: 'base64' })
|
||||
const mimeType = mime.lookup(file)
|
||||
const media = new MessageMedia(mimeType, base64)
|
||||
client.sendMessage(number, media, { caption }).then(response => {
|
||||
socks.emit('imgOk', 'image sent')
|
||||
console.log("Imagen OK")
|
||||
// res.status(200).json({
|
||||
// status: true,
|
||||
// response: response
|
||||
// });
|
||||
|
||||
}).catch(err => {
|
||||
socks.emit('imgKo', 'image NOT sent')
|
||||
console.log("Imagen NOT OK")
|
||||
// res.status(500).json({
|
||||
// status: false,
|
||||
// response: err
|
||||
// });
|
||||
});
|
||||
});
|
||||
// app.post('/upload', async (req, res) => {
|
||||
// // Get the file that was set to our field named "image"
|
||||
// const { image } = req.files;
|
||||
// // If no image submitted, exit
|
||||
// if (!image) return res.sendStatus(400);
|
||||
// // Move the uploaded image to our upload folder
|
||||
// image.mv(__dirname + '/../mediaSend/' + image.name);
|
||||
// res.sendStatus(200);
|
||||
// });
|
||||
|
||||
checkEnvFile();
|
||||
return client
|
||||
}
|
||||
|
||||
module.exports = { initBot }
|
||||
@@ -1,344 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<title>Whatsapp API by Ngekoding</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<!-- This parts is optional, just for improve the styles -->
|
||||
<link href="https://fonts.googleapis.com/css2?family=Montserrat:wght@400;700&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: 'Montserrat', sans-serif;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
#app {
|
||||
max-width: 500px;
|
||||
margin: 20px auto;
|
||||
}
|
||||
|
||||
#qrcode {
|
||||
/* display: none; */
|
||||
/* Showed when qr code received */
|
||||
width: 100%;
|
||||
margin: 10px 0;
|
||||
border: 1px solid #efefef;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
ul.logs {
|
||||
max-height: 150px;
|
||||
padding: 15px 15px 15px 30px;
|
||||
margin-top: 5px;
|
||||
border-radius: 4px;
|
||||
overflow-y: auto;
|
||||
background: #efefef;
|
||||
color: #666;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
ul.logs li:first-child {
|
||||
color: green;
|
||||
font-weight: bold;
|
||||
}
|
||||
::placeholder {
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="app">
|
||||
<div style="text-align:center;">
|
||||
<h1>Whatsapp API</h1>
|
||||
<br><br>
|
||||
<div id="divQRPage" style="display:none;"></div>
|
||||
<div id="countdown" style="margin-top:-25px"></div>
|
||||
<div id="postman" style="display:flex;justify-content:center;">
|
||||
<div>
|
||||
<select id="tipoMensaje">
|
||||
<option>Mensaje</option>
|
||||
<option>Imagen</option>
|
||||
<option>Botones</option>
|
||||
</select>
|
||||
</div>
|
||||
<div id="postMsg">
|
||||
<table>
|
||||
<tr>
|
||||
<td>Número:</td>
|
||||
<td><input type="text" id="number" value="5215554192439"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Mensaje:</td>
|
||||
<td><input type="text" id="message" value="test1"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td> </td>
|
||||
<td align="center"><input type="button" id="btnMessage" value="Enviar Mensaje"></td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<div id="postBtn" style="display:none;">
|
||||
<table>
|
||||
<tr>
|
||||
<td>Número:</td>
|
||||
<td><input type="text" id="btnnumber" value="5215554192439"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Titulo:</td>
|
||||
<td><input type="text" id="btntitle" placeholder="El título"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Mensaje:</td>
|
||||
<td><input type="text" id="btnmsg" placeholder="El mensaje"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Boton 1:</td>
|
||||
<td><input type="text" id="btn1" placeholder="Texto del botón 1"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Boton 2:</td>
|
||||
<td><input type="text" id="btn2" placeholder="Texto del botón 1"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Boton 3:</td>
|
||||
<td><input type="text" id="btn3" placeholder="Texto del botón 1"></td>
|
||||
</tr> <tr>
|
||||
<td>Footer:</td>
|
||||
<td><input type="text" id="btnfooter" placeholder="Texto del footer"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td> </td>
|
||||
<td align="center"><input type="button" id="btnBtn" value="Enviar Botones"></td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<div id="postImg">
|
||||
<table>
|
||||
<form action="/send-image" method="POST" id="imgForm" enctype="multipart/form-data">
|
||||
<tr>
|
||||
<td>Número:</td>
|
||||
<td><input type="text" id="imgnumber" value="5215554192439" style="width:160px;"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Imagen:</td>
|
||||
<td><input type="file" id="imgimage" name="imgimage" style="width:160px;" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Texto:</td>
|
||||
<td><input type="text" id="imgcaption" placeholder="El texto aquí" style="width:160px;"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td> </td>
|
||||
<td align="center"><input type="button" id="btnImg" value="Enviar Mensaje"></td>
|
||||
</tr>
|
||||
</form>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- <input type="button" id="chkConn" value="QR"> -->
|
||||
<br>
|
||||
<h3>Logs:</h3>
|
||||
<ul class="logs"></ul>
|
||||
</div>
|
||||
<div id="div_wa_msg" style="display: none;"></div>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js" crossorigin="anonymous"></script>
|
||||
<script src="/socket.io/socket.io.js" crossorigin="anonymous"></script>
|
||||
<script>
|
||||
let downloadTimer;
|
||||
let IntervaloABorrar
|
||||
let waReady = false
|
||||
let IOSTATUS = "NONE"
|
||||
$(document).ready( function(){
|
||||
$("#postBtn").hide(); $("#postImg").hide();
|
||||
if (waReady == false && IOSTATUS == "wa_ready") { $("#btnMessage").attr("disabled", true); $("#btnBtn").attr("disabled", true); }
|
||||
var socket = io();
|
||||
socket.on('ioStatus', function ( msg ){
|
||||
IOSTATUS = msg;
|
||||
console.log("IOSTATUS="+msg);
|
||||
console.log("XXXXXXXXXXXXX " + IOSTATUS)
|
||||
if(msg == 'wa_msg') { IOSTATUS = "wa_ready" }
|
||||
if (IOSTATUS == 'wa_ready') { $("#postman").show(); $("#divQRPage").hide() }
|
||||
else if (IOSTATUS == 'wa_qr') { $("#divQRPage").show(); loadQR(); $("#postman").hide(); console.log("mostramos QRPage") }
|
||||
else { $("#divQRPage").hide(); $("#postman").hide(); }
|
||||
})
|
||||
socket.on('wa_msg', function( msg ){
|
||||
$("#div_wa_msg").fadeIn()
|
||||
$("#div_wa_msg").html(msg)
|
||||
setTimeout(() => {
|
||||
$("#div_wa_msg").fadeOut("slow")
|
||||
}, 1500);
|
||||
})
|
||||
socket.on('imgOk', function (msg) {
|
||||
alert("¡Imagen mandada con exito!")
|
||||
})
|
||||
socket.on('message', function (msg) {
|
||||
$('.logs').prepend($('<li>').text(msg));
|
||||
console.log("|" + msg + "|");
|
||||
console.log("MENSAJES = " + $(".logs li").length)
|
||||
if($(".logs li").length >= 15){ $('.logs li').last().remove(); }
|
||||
if (msg == 'Conectando...' && IOSTATUS == "wa_ready") { $('#divQRPage').hide(); $('#postman').show(); waReady = false, $("#btnMessage").attr("disabled", true); $("#btnBtn").attr("disabled", true); }
|
||||
// if (msg == 'Whatsapp esta listo!') { $("#btnMessage").attr("disabled", false); $("#btnBtn").attr("disabled", false); }
|
||||
})
|
||||
socket.on('qr', function (src) {
|
||||
var extra = Date.now();
|
||||
console.log(extra)
|
||||
loadQR()
|
||||
// $('#qrcode').attr('src', src + '?' + extra);
|
||||
$('#postman').hide();
|
||||
$('#divQRPage').show();
|
||||
waReady = false;
|
||||
$("#btnMessage").attr("disabled", true);
|
||||
$("#btnBtn").attr("disabled", true);
|
||||
startImer()
|
||||
})
|
||||
socket.on('ready', function (data) {
|
||||
$("#divQRPage").hide();
|
||||
$('#postman').show();
|
||||
$("#btnMessage").attr("disabled", false);
|
||||
$("#btnBtn").attr("disabled", false);
|
||||
clearInterval(IntervaloABorrar);
|
||||
})
|
||||
socket.on('authenticated', function (data) {
|
||||
$('#divQRPage').hide();
|
||||
$('#postman').show();
|
||||
})
|
||||
socket.on("connect_error", (err) => {
|
||||
$("#btnMessage").attr("disabled", true);
|
||||
$("#btnBtn").attr("disabled", true);
|
||||
$('.logs').prepend($('<li>').text("¡Error de conexión!"));
|
||||
if ($(".logs li").length >= 15) { $('.logs li').last().remove(); }
|
||||
console.log("MENSAJES = " + $(".logs li").length)
|
||||
waReady = false
|
||||
console.log(`connect_error due to ${err.message}`);
|
||||
})
|
||||
socket.on('incomming', function () {
|
||||
if (waReady == false) {
|
||||
$('.logs').prepend($('<li>').text('Whatsapp está listo!'));
|
||||
if ($(".logs li").length >= 15) { $('.logs li').last().remove(); }
|
||||
console.log("MENSAJES = " + $(".logs li").length)
|
||||
console.log("incomming")
|
||||
$("#btnMessage").attr("disabled", false);
|
||||
$("#btnBtn").attr("disabled", false);
|
||||
waReady = true
|
||||
}
|
||||
})
|
||||
socket.on('connOk', function () {
|
||||
console.log("connOk")
|
||||
if (waReady == false && IOSTATUS == "wa_ready") {
|
||||
$('.logs').prepend($('<li>').text('Whatsapp está listo!'));
|
||||
if ($(".logs li").length >= 15) { $('.logs li').last().remove(); }
|
||||
console.log("MENSAJES = " + $(".logs li").length)
|
||||
console.log("incomming")
|
||||
$("#btnMessage").attr("disabled", false);
|
||||
$("#btnBtn").attr("disabled", false);
|
||||
waReady = true
|
||||
}
|
||||
})
|
||||
$("#chkConn").on('click', async function () {
|
||||
loadQR()
|
||||
})
|
||||
function revisaConexion() {
|
||||
var checkConnection = setInterval(function () {
|
||||
if (waReady == false) {
|
||||
socket.emit('checkConn', 'check conn');
|
||||
console.log("chk conn")
|
||||
IntervaloABorrar = checkConnection
|
||||
clearInterval(IntervaloABorrar)
|
||||
console.log("borrado " + IntervaloABorrar)
|
||||
}
|
||||
}, 2000);
|
||||
}
|
||||
revisaConexion();
|
||||
function loadQR(){
|
||||
$('#divQRPage').load("qr.html");
|
||||
console.log("Load QR page!")
|
||||
}
|
||||
function startImer() {
|
||||
clearInterval(IntervaloABorrar);
|
||||
var timeleft = 60;
|
||||
console.log(typeof downloadTimer)
|
||||
var downloadTimer = setInterval(function () {
|
||||
if (timeleft <= 0) {
|
||||
IntervaloABorrar = downloadTimer
|
||||
clearInterval(IntervaloABorrar);
|
||||
document.getElementById("countdown").innerHTML = "Finished";
|
||||
// startImer();
|
||||
} else {
|
||||
document.getElementById("countdown").innerHTML = timeleft + " seconds remaining";
|
||||
}
|
||||
console.log(typeof downloadTimer + "|" + downloadTimer)
|
||||
IntervaloABorrar = downloadTimer
|
||||
timeleft -= 1;
|
||||
}, 1000);
|
||||
}
|
||||
$('#btnMessage').on('click', function () {
|
||||
console.log("msg clicked")
|
||||
$.post("http://localhost:3005/send-message/", { "number": $("#number").val(), "message": $("#message").val() })
|
||||
.done(function (data) {
|
||||
console.log(data.status);
|
||||
if (data.status == true) { alert("¡Mensaje enviado!") }
|
||||
});
|
||||
})
|
||||
$('#btnBtn').on('click', function () {
|
||||
console.log("btn clicked")
|
||||
if($("#btnnumber").val() != "" && $("#btnmsg").val() != "" && $("#btn1").val() != ""){
|
||||
let data = {}
|
||||
data.number = $("#btnnumber").val()
|
||||
data.title = $("#btntitle").val()
|
||||
data.btnmsg = $("#btnmsg").val()
|
||||
if($("#btn1").val() != "") {data.btn1 = $("#btn1").val()}
|
||||
if ($("#btn2").val() != "") {data.btn2 = $("#btn2").val()}
|
||||
if ($("#btn3").val() != "") {data.btn3 = $("#btn3").val()}
|
||||
if ($("#btnfooter").val() != "") {data.footer = $("#btnfooter").val()}
|
||||
$.post("http://localhost:3005/send-buttons/", data)
|
||||
.done(function (data) {
|
||||
console.log(data.status);
|
||||
if (data.status == true) { alert("¡Mensaje enviado!") }
|
||||
});
|
||||
}
|
||||
else{alert("Es necesario llenar por lo menos el número, mensaje y boton1.")}
|
||||
})
|
||||
$("#btnImg").click(function () {
|
||||
var fd = new FormData();
|
||||
console.log("IMAGEN=" + $('#imgimage')[0]?.files[0])
|
||||
var files = $('#imgimage')[0].files[0];
|
||||
fd.append('image', files);
|
||||
fd.append('number', $("#imgnumber").val())
|
||||
fd.append('caption', $("#imgcaption").val())
|
||||
$.ajax({
|
||||
url: 'http://localhost:3005/send-image/',
|
||||
type: 'POST',
|
||||
data: fd,
|
||||
contentType: false,
|
||||
processData: false,
|
||||
success: function (response) {
|
||||
if (response != 0) {
|
||||
// alert('file uploaded');
|
||||
}
|
||||
else {
|
||||
alert('file not uploaded');
|
||||
}
|
||||
},
|
||||
});
|
||||
});
|
||||
$("#tipoMensaje").change(function () {
|
||||
let sel = $("select option:selected").val()
|
||||
console.log(sel)
|
||||
if(sel == 'Mensaje'){ $("#postMsg").show(); $("#postBtn").hide(); $("#postImg").hide(); }
|
||||
else if(sel == 'Imagen') { $("#postMsg").hide(); $("#postBtn").hide(); $("#postImg").show(); }
|
||||
else if (sel == 'Botones') { $("#postMsg").hide(); $("#postBtn").show(); $("#postImg").hide(); }
|
||||
})
|
||||
});
|
||||
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -1 +0,0 @@
|
||||
<img src="bot.qr.png" alt="QR Code" id="qrcode" style="width:300px">
|
||||
@@ -1,15 +1,7 @@
|
||||
const express = require('express');
|
||||
const router = express.Router()
|
||||
const { getQr } = require('../controllers/web')
|
||||
var path = require('path');
|
||||
|
||||
// router.use('/qr', getQr)
|
||||
var staticFilesPath0 = path.resolve('./', 'public');
|
||||
var staticFilesPath = path.resolve('./', 'public/index.html');
|
||||
console.log(staticFilesPath)
|
||||
router.use(express.static(staticFilesPath0));
|
||||
router.get('/', (req, res) => {
|
||||
res.sendFile(staticFilesPath)
|
||||
});
|
||||
router.use('/qr', getQr)
|
||||
|
||||
module.exports = router
|
||||
Reference in New Issue
Block a user