integramos Baileys y varios cambios,

This commit is contained in:
2023-02-21 18:49:07 -06:00
parent 3518f516e0
commit fe8d0f7648
17 changed files with 935 additions and 1360 deletions

2
.env
View File

@@ -13,4 +13,4 @@ KEEP_DIALOG_FLOW=false
MULTI_DEVICE=true
DIALOGFLOW_MEDIA_FOR_SLOT_FILLING=false
GDRIVE_FOLDER_ID=
PROVIDER=baileys
PROVIDER=wwebjs

View File

@@ -1,5 +1,5 @@
## Chatbot Whatsapp (OpenSource)
#### Actualizado Diciembre 2022
#### Actualizado Febrero 2023
Este proyecto es un clon de la **version 1** (legacy) de [Leifer Mendez](https://github.com/leifermendez/bot-whatsapp) y tiene las siguientes modificaciones:
@@ -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.
- 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,23 +62,30 @@ 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** 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 repo!)
- 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:
```json
{
"ejemploViejo":{
"replyMessage":["¿Hola como estas?"],
"ejemploViejo":
{
"replyMessage":
[
"¿Hola como estas?"
],
"media":null,
"trigger":null
}
}
```
Ahora **replyMessage** debe de contener un arreglo con los mensajes que se van a enviar:
Ahora "```replyMessage```" debe de contener un arreglo con los mensajes que se van a enviar:
```json
{
"ejemploNuevo":{
"replyMessage":[
"replyMessage":
[
{ "mensaje":["¿Hola como estas?"]},
{ "mensaje":["Este es el *segundo* mensaje.","Contiene dos lineas 🤪"]},
{ "mensaje":["Este es el *tercer* mensaje"]}
@@ -88,9 +95,58 @@ Este proyecto es un clon de la **version 1** (legacy) de [Leifer Mendez](https:/
}
}
```
- 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```
```
"Desbloqueo":{
"keywords": "desbloqueo",
"replyMessage":[
"Mensaje de desbloqueo de usuarios."
],
"funcion":"getFakeHTTP", //esta linea ejecuta la funcion.
"media":null,
"trigger":null,
"pasoRequerido":"soporte"
}
```
```app.js```
```
function fakeHTTP(data){
let body = data.theMsg.body
let from= data.theMsg.from
}
```
- Los archivos **initial.json** y **response.json** se unificaron, y ya solo se usa el **response.json**, para esto solo se agrega el parametro "```keywords```" del **initial.json** al **response.json**.
```response.json```
```
"Desbloqueo":{
"keywords": "desbloqueo", //Esta linea se trae desde initial.json
"replyMessage":[
"Mensaje de desbloqueo de usuarios."
],
"media":null,
"trigger":null,
"pasoRequerido":"soporte"
}
```
- Se puede especificar que al terminar un paso, el flujo se **vaya automaticamente** a otro, por ejemplo, si tenemos un flujo de tres pasos, y queremos que al terminar el tercer paso se regrese automaticamente al primero, agregamos el parametro "```goto```" al **response.json** del tercer paso y ponemos el nombre del paso 1.
```
"paso3":{
"keywords": ["zapatos"],
"replyMessage":["Gracias por tu compra"],
"media":null,
"trigger":null,
"goto":"paso1"
},
```
- 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 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)
## INICIA DOCUMENTACION DEL PROYECTO ORIGINAL
@@ -106,7 +162,7 @@ El siguiente proyecto se realizó con fines educativos para el canal de [Youtube
> [VER](https://github.com/leifermendez/bot-whatsapp/commits/main)
### Busco colaboradores ⭐
Hola amigos me gusta mucho este proyecto pero por cuestiones de tiempo se me dificulta mantener las actualizaciones si alguno quieres participar en el proyecto escribeme a leifer.contacto@gmail.com
Hola amigos me gusta mucho este proyecto pero por cuestiones de tiempo se me dificulta mantener las actualizaciones si alguno quiere participar en el proyecto escribanme a leifer.contacto@gmail.com
#### Acceso rápido
> Si tienes una cuenta en __heroku__ puedes desplegar este proyecto con (1 click)
@@ -237,7 +293,7 @@ __Listo 😎__
![](https://i.imgur.com/OSUgljQ.png)
> Ahora deberías obtener un arespuesta por parte del BOT como la siguiente, ademas de esto tambien se crea un archivo excel
> Ahora deberías obtener una respuesta por parte del BOT como la siguiente, ademas de esto tambien se crea un archivo excel
con el historial de conversación con el número de tu cliente
![](https://i.imgur.com/lrMLgR8.png)

View File

@@ -5,7 +5,7 @@ const fs = require('fs');
//const clientEmail = require(`${__dirname}/../chatbot-account.json`);
/**
* La funcion 'generatePublicUrl' genera un error muy menor al enviar el 'requestBody'
* La funcion 'generatePublicUrl' genera un error muy pequeño 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,6 +51,7 @@ 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}`);
});

View File

@@ -218,19 +218,18 @@ const getIA = (message) => new Promise((resolve, reject) => {
/**
*
* @param {*} message
* @param {*} date
* @param {*} trigger
* @param {*} date
* @param {*} number
* @returns
*/
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"
const saveMessage = ( message, 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, trigger, number ) )
resolve( await saveMessageMysql( message, number ) )
break;
case 'none':
resolve( await saveMessageJson( message, trigger, number, regla) ) //MOD by CHV - Agregamos el parametro "regla"
console.log("Guardamos mensaje JSON=", message)
resolve( await saveMessageJson( message, number, regla) ) //MOD by CHV - Agregamos el parametro "regla"
// console.log("Guardamos mensaje JSON =", message)
break;
default:
resolve(true)

View File

@@ -1,14 +1,14 @@
const Path = require('path')
const StormDB = require("stormdb");
const date = new Date().toISOString();
const saveMessageJson = (message, trigger, number, regla) => new Promise( async(resolve,reject) =>{
const saveMessageJson = (message, 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, trigger, regla});
db.get("messages").push({ message, date, regla});
db.save();
resolve('Saved')
} catch (error) {

View File

@@ -47,10 +47,10 @@ getMessages = ( number ) => new Promise((resolve,reejct) => {
}
})
saveMessageMysql = ( message, date, trigger, number ) => new Promise((resolve,reejct) => {
saveMessageMysql = ( message, date, number ) => new Promise((resolve,reejct) => {
try {
connection.query(
`INSERT INTO ${DATABASE_NAME}.messages `+"( `message`, `date`, `trigger`, `number`)"+` VALUES ('${message}','${date}','${trigger}', '${number}')` , (error, results) => {
`INSERT INTO ${DATABASE_NAME}.messages `+"( `message`, `date`, `number`)"+` VALUES ('${message}','${date}', '${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')

318
app.js
View File

@@ -6,16 +6,18 @@ global.provider = process.env.PROVIDER || 'wwebjs';
const fs = require('fs');
global.siguientePaso = [{"numero":"1", "va":"XXX"}]; //MOD by CHV - Agregamos para pasar el VAMOSA a "index.js"
global.pasoAnterior = [];
const axios = require('axios').default;
const { List } = require('whatsapp-web.js');
global.vars = []
// const mysqlConnection = require('./config/mysql')
const { initBot, traeVariables } = require(`./provider/${provider}`)
if( provider == 'baileys' ){ const { initBot } = require(`./provider/baileys`) }
else { const { initBot } = require(`./provider/wwebjs`) }
const { isValidNumber } = require('./controllers/handle')
const { saveMedia, saveMediaToGoogleDrive } = require('./controllers/save')
const { getMessages, responseMessages, bothResponse, waitFor } = require('./controllers/flows')
const { sendMedia, sendMessage, sendMessageButton, sendMessageList, readChat } = require(`./controllers/send_${provider}`);
const { sendMedia, sendMessage, sendMessageButton, sendMessageList, readChat } = require(`./controllers/send`);
const { stepsInitial, vamosA, traeUltimaVisita } = require('./adapter/index');//MOD by CHV - Agregamos para utilizar remplazos y stepsInitial
const { removeDiacritics, getRandomInt, remplazos, soloNumero, agregaVars } = require('./implementaciones/extraFuncs')
const { removeDiacritics, getRandomInt, remplazos, soloNumero, agregaVars, traeVariablesFromMsg, traeVariablesFromClient } = require('./implementaciones/extraFuncs')
const appFuncs = require('./implementaciones/appFuncs')
// import * as appFuncs from './implementaciones/appFuncs'
// const { guardaXLSDatos, leeXLSDatos} = require('./Excel');
// const { ingresarDatos, leerDatos } = require('./implementaciones/sheets')
const MULTI_DEVICE = process.env.MULTI_DEVICE || 'true';
@@ -25,18 +27,32 @@ let client0
var dialogflowFilter = false;
var newBody; //MOD by CHV -
var nuevaRespuesta; //MOD by CHV - Se agrego para los remplazos
var vars = []
let blackList = ['34692936038', '34678310819', '34660962689', '34649145761','34630283553','34648827637','34630255646','14178973313']
// ############################################################################################################
// ########################## AQUI SE DECLARAN LAS FUNCIONES PERSONALIZADAS DESDE #########################
// ######################## EL ARCHIVO APPFUNCS.JS EN EL DIRECTORIO IMPLEMENTACIONES ######################
// ############################################################################################################
const arrayOfAppFuncs = Object.entries(appFuncs);
// console.log(arrayOfAppFuncs)
// console.log(arrayOfAppFuncs[0][0], arrayOfAppFuncs[0][1])
for(thisF = 0; thisF < arrayOfAppFuncs.length; thisF++){
// console.log(arrayOfAppFuncs[thisF][0], "|", arrayOfAppFuncs[thisF][1])
// console.log(eval(arrayOfAppFuncs[thisF][0]), "|", arrayOfAppFuncs[thisF][1])
global[arrayOfAppFuncs[thisF][0]] = arrayOfAppFuncs[thisF][1]
// eval(arrayOfAppFuncs[thisF][0]) = eval(arrayOfAppFuncs[thisF][1])
}
/**
* Escuchamos cuando entre un mensaje
* Escuchamos cuando entra un mensaje
*/
function listenMessage(client){
if(provider == 'wwebjs'){ client0 = client; messageEV = 'message' } // Usamos WWebJS.
else { client0 = client.ev; messageEV = 'messages.upsert' } // Usamos Baileys.
client0.on(messageEV, async msg => {
const { from, body, name, hasMedia } = traeVariables(msg);
if(provider == 'wwebjs'){ msg.type = 'notify' }
const { from, body, name, hasMedia } = traeVariablesFromMsg(msg);
if (vars[from] === undefined) vars[from] = []
// Este bug lo reporto Lucas Aldeco Brescia para evitar que se publiquen estados
if (from === 'status@broadcast' || msg.type !== 'notify') { console.log("++++++ status@broadcast o tipo mensaje = ", msg.type); return }
@@ -50,8 +66,8 @@ function listenMessage(client){
// * Blacklist, los telefonos incluidos en este arreglo son ignorados por el bot.
if (blackList.includes(number)){ console.log('BlackListed'); return }
var { key } = stepsInitial.find(k => k.keywords.includes(message)) || { key: null }//MOD by CHV - Se agrega para obtener KEY
await readChat(number, message, null , key) //MOD by CHV - Agregamos key/regla para guardarla en "chats/numero.json"
client = agregaVars(client, msg, traeVariables(msg))
await readChat(number, message, key) //MOD by CHV - Agregamos key/regla para guardarla en "chats/numero.json"
client = agregaVars(client, msg, traeVariablesFromMsg(msg))
client.theMsg['key'] = key
/**
@@ -105,276 +121,6 @@ function listenMessage(client){
nuevaRespuesta = remplazos(resps[step].replyMessage.join(''), client);
client.theMsg['replyMessage'] = nuevaRespuesta
// ############################################################################################################
// ############################## INICIAN FUNCIONES PERSONALIZADAS #####################################
// ############################################################################################################
/**
* Llama el API para traer categorias de Guna.
* @param {*} ctx El objeto del mensaje.
*/
async function getGunaCats(ctx) {
let theUrl = `http://localhost:8888/dbrquery?j={"query":"selectTipoFerreroMty","exec":"ExecuteQuery","params":{"par1":"xxx"}}`
const RES = await axios.get(theUrl).then(function (response) {
let lasOpciones = []
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, tempItem)
}
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(client, from, null, productList)
// console.log(ctx)
// sendMessagList(client, from, null, productList);
return
}).catch(function (error) {
console.log(error);
return error
});
}
/**
* Llama el API para traer subcategorias de Guna.
* @param {*} ctx El objeto del mensaje.
*/
async function getGunaSubtipo(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")
client.sendMessage(from, "Esa categoría *no existe*, por favor revisa y vuelve a intentar.")
}
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("Sselecciona una subcategoría 👇🏽", ctx),
title: "Ver las subcategorías",
sections:[
{ title: "Subcategorías",
rows: lasOpciones,
}
],
footer:"",
buttonText:`CATEGORÍA ${body}`
}
sendMessageList(client, 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.
*/
async function getGunaProds(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(client, 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.
*/
async function agregaProds(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(client, from, elMensaje, ctx.theMsg.trigger, ctx.theMsg.step);
await delay(500)
vars[from]['recompra'] = true
getGunaProds()
vamosA(from, "gunaProds")
return
}
sendMessage(client, from, elMensaje, ctx.theMsg.trigger, ctx.theMsg.step);
return
}
/**
* Tomamos la cantidad del producto seleccionado.
* @param {*} ctx El objeto del mensaje.
*/
async function prodCantidad(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(client, from, "xxx", bts)
}
else{
console.log("NO SOLO NUMS")
vamosA(from, "gunaProdsAgrega")
sendMessage(client, from, "Por favor escribe 👉🏽 *solo* 👈🏽 el número.", response.trigger, step);
}
return "1"
}
/**
* Mandamos nuevamente la lista de productos.
* @param {*} ctx El objeto del mensaje.
*/
async function comprarMas(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.
*/
async function terminaCompra(ctx) {
console.log("Entramos a terminaCompra")
vars[from] = []
sendMessage(client, from, "!Gracias por tu compra, regresa pronto!", response.trigger, step);
return
}
/**
* Llama el API para desbloquear un usuario.
* @param {*} ctx El objeto del mensaje.
*/
async function desbloqueaUsuario(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(client, from, "Listo, usuario *"+response.data['params']['par1']+"* desbloqueado, por favor *cerrar navegadores* y reingresar.", response.trigger, step);
}
else{
sendMessage(client, from, "El usuario *"+response.data['params']['par1']+"* no *existe* o esta dado de *baja*, por favor revisarlo y volver a intentar.", response.trigger, 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
*/
async function desbloqueaUsuario2(theUrl, step) {
// const {from} = client.theMsg
// 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(client, from, "Listo, usuario *"+response.data['params']['par1']+"* desbloqueado, por favor *cerrar navegadores* y reingresar.", response.trigger, step);
// }
// else{
// sendMessage(client, from, "El usuario *"+response.data['params']['par1']+"* no *existe* o esta dado de *baja*, por favor revisarlo y volver a intentar.", response.trigger, step);
// }
// return response
// }).catch(function (error) {
// console.log(error);
// return error
// });
}
// ####################################################################################################################
// ############################## INICIAN FUNCIONES PARA MANEJO DE PARAMETROS #####################################
// ############################## EN EL RESPONSE.JSON #####################################
@@ -392,7 +138,7 @@ function listenMessage(client){
*/
if (!response.delay && response.media) {
// console.log("++++++++++++++++++++++++++++ SEND MEDIA NO DELAY +++++++++++++++++++++++++++++++++++");
await sendMedia(client, from, response.media, response.trigger);
await sendMedia(client, from, response.media);
console.log("Enviamos imagen")
await delay(500)
}
@@ -402,7 +148,7 @@ function listenMessage(client){
if (response.delay && response.media) {
setTimeout(() => {
// console.log("++++++++++++++++++++++++++++ SEND MEDIA AND DELAY +++++++++++++++++++++++++++++++++++");
sendMedia(client, from, response.media, response.trigger);
sendMedia(client, from, response.media);
}, response.delay)
}
/**
@@ -414,7 +160,7 @@ function listenMessage(client){
response.replyMessage.forEach( async messages => {
var thisMsg = messages.mensaje
if(Array.isArray(messages.mensaje)){thisMsg = messages.mensaje.join('\n')}
await sendMessage(client, from, remplazos(thisMsg, client), response.trigger);
await sendMessage(client, from, remplazos(thisMsg, client), step);
})
}, response.delay)
await delay(500)
@@ -428,7 +174,7 @@ function listenMessage(client){
var thisMsg = messages.mensaje
if(Array.isArray(messages.mensaje)){thisMsg = messages.mensaje.join('\n')}
// console.log("Mensaje=", thisMsg)
if(thisMsg !== undefined) await sendMessage(client, from, remplazos(thisMsg, client), response.trigger);
if(thisMsg !== undefined) await sendMessage(client, from, remplazos(thisMsg, client), step);
})
await delay(500)
}
@@ -458,7 +204,7 @@ function listenMessage(client){
response.replyMessage.forEach( async messages => {
var thisMsg = messages.mensaje
if(Array.isArray(messages.mensaje)){thisMsg = messages.mensaje.join('\n')}
await sendMessage(client, from, remplazos(thisMsg, client), response.trigger);
await sendMessage(client, from, remplazos(thisMsg, client), step);
})
/**
@@ -511,6 +257,6 @@ function listenMessageFromBot(client0){
async function inicializaBot(){
const ib = await initBot()
listenMessage(ib)
listenMessageFromBot(ib)
// listenMessageFromBot(ib)
}
inicializaBot()

View File

@@ -1,5 +1,5 @@
const mimeDb = require('mime-db');
const { uploadSingleFile } = require('../adapter/gdrive');
// const { uploadSingleFile } = require('../adapter/gdrive') // Para Goole Drive y DialogFlow
const fs = require('fs');
var fileName;

View File

@@ -2,7 +2,9 @@
const ExcelJS = require('exceljs');
const moment = require('moment');
const fs = require('fs');
const { MessageMedia, Buttons, List } = require('whatsapp-web.js');
const { MessageMedia, Buttons, List } = require('whatsapp-web.js')
const baileys = require('./send_baileys')
const wwebjs = require('./send_wwebjs')
const { cleanNumber } = require('./handle')
const { remplazos } = require('../adapter/index'); //MOD by CHV - Agregamos remplazos
const DELAY_TIME = 170; //ms
@@ -12,22 +14,26 @@ const DIR_MEDIA = `${__dirname}/../mediaSend`;
const { saveMessage } = require('../adapter')
/**
* Enviamos archivos multimedia a nuestro cliente
* @param {*} number
* @param {*} client
* @param {*} number
* @param {*} fileName
* @param {*} caption
*/
const sendMedia = (client, number = null, fileName = null, trigger = null) => {
const sendMedia = (client, number = null, fileName = null, caption = 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);
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);
if(provider === 'baileys'){baileys.sendMedia(client, number, fileName, caption)}
else{wwebjs.sendMedia(client, number, fileName, caption)}
// client.sendMessage(number, media, { sendAudioAsVoice: true });
// }
} catch(e) {
throw e;
}
@@ -42,13 +48,14 @@ const sendMedia = (client, number = null, fileName = null, trigger = 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);
client.sendMessage(number, media ,{ sendAudioAsVoice: true });
}
// 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 });
// }
}catch(e) {
throw e;
}
@@ -58,13 +65,15 @@ const sendMedia = (client, number = null, fileName = null, trigger = null) => {
* Enviamos un mensaje simple (texto) a nuestro cliente
* @param {*} number
*/
const sendMessage = async (client, number = null, text = null, trigger = null, regla) => { //MOD by CHV - Agregamos el parametro "regla" para guardarlo en "chats/numero.json"
const sendMessage = async (client, number = null, text = null, regla) => { //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);
// 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);
// console.log(number, message, regla)
await readChat(number, message, trigger, regla) //MOD by CHV - Agregamos el parametro "regla"
await readChat(number, message, regla) //MOD by CHV - Agregamos el parametro "regla"
console.log(`⚡⚡⚡ Enviando mensajes....`);
// console.log("********************* SEND MESSAGE **************************************");
},DELAY_TIME)
@@ -76,13 +85,14 @@ const sendMessage = async (client, number = null, text = null, trigger = null, r
*/
const sendMessageButton = 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, actionButtons)
client.sendMessage(number, button);
if(provider === 'baileys'){baileys.sendMessageButton(client, number, text, actionButtons)}
else{wwebjs.sendMessageButton(client, number, text, actionButtons)}
// 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 ***********************************");
}
@@ -95,12 +105,14 @@ 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));
client.sendMessage(number, aList);
await readChat(number, message, actionList)
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));
if(provider === 'baileys'){baileys.sendMessageList(client, number, text, actionList)}
else{wwebjs.sendMessageList(client, number, text, actionList)}
// client.sendMessage(number, aList);
await readChat(number, message)
// console.log('⚡⚡⚡ Enviando lista a '+number+' ....');
}, DELAY_TIME)
}
@@ -130,9 +142,9 @@ const lastTrigger = (number) => new Promise((resolve, reject) => {
* @param {*} number
* @param {*} message
*/
const readChat = async (number, message, trigger = null, regla) => { //MOD by CHV - Agregamos el parametro "regla" para guardarlo en "chats/numero.json"
const readChat = async (number, message, regla) => { //MOD by CHV - Agregamos el parametro "regla" para guardarlo en "chats/numero.json"
number = cleanNumber(number)
await saveMessage( message, trigger, number, regla ) //MOD by CHV - Agregamos "regla"
await saveMessage( message, number, regla ) //MOD by CHV - Agregamos "regla"
// console.log('Saved')
}

View File

@@ -17,10 +17,11 @@ const mime = require('mime-types')
* @param {*} number
* @param {*} mediaInput
* @param {*} message
* @example await sendMessage('+XXXXXXXXXXX', 'https://dominio.com/imagen.jpg' | 'img/imagen.jpg')
* @param {*} caption
* @example await sendMessage(client, '+XXXXXXXXXXX', 'https://dominio.com/imagen.jpg' | 'img/imagen.jpg', 'caption')
*/
const sendMedia = async (client, number, fileName, text) => {
console.log("SendMedia = ", number, fileName, text)
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}`;
@@ -28,9 +29,9 @@ const sendMedia = async (client, number, fileName, text) => {
if (fs.existsSync(file)) {
console.log("ARCHIVO EXISTE");
const mimeType = mime.lookup(file)
if (mimeType.includes('image')) return sendImage(client, number, file, text)
if (mimeType.includes('video')) return sendVideo(client, number, file, text)
if (mimeType.includes('audio')) return sendAudio(client, number, file, text)
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)
}
}
@@ -63,7 +64,6 @@ const sendImage = async (client, number, filePath, text) => {
if (fs.existsSync(file)) {
const media = MessageMedia.fromFilePath(file);
client.sendMessage(number, media ,{ sendAudioAsVoice: true });
}
}catch(e) {
throw e;
@@ -74,13 +74,13 @@ const sendImage = async (client, number, filePath, text) => {
* Enviamos un mensaje simple (texto) a nuestro cliente
* @param {*} number
*/
const sendMessage = async (client, number = null, text = null, trigger = null, regla) => { //MOD by CHV - Agregamos el parametro "regla" para guardarlo en "chats/numero.json"
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)
await client.sendMessage(number, { text: text })
client.sendMessage(number, { text: text })
// console.log(number, message, regla)
await readChat(number, text, trigger, regla) //MOD by CHV - Agregamos el parametro "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 **************************************");
@@ -97,7 +97,7 @@ const sendMessageButton2 = async (client, number = null, text = null, actionButt
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, actionButtons)
await readChat(number, message)
client.sendMessage(number, button);
console.log(`⚡⚡⚡ Enviando mensajes (botones)....`);
// console.log("sendMessageButton.");
@@ -122,10 +122,11 @@ const sendMessageButton = async (client, number, text = null, actionButtons) =>
type: 1,
}))
text = remplazos(`*${title}*\n${message}`, client)
await readChat(number, message, actionButtons)
// console.log("sendMessageButton:", text, templateButtons)
const buttonMessage = { text, footer, buttons: templateButtons, headerType: 1 }
console.log("sendMessageButton:", buttonMessage)
console.log(templateButtons)
return client.sendMessage(number, buttonMessage)
await readChat(number, message)
}
/**
@@ -133,7 +134,7 @@ const sendMessageButton = async (client, number, text = null, actionButtons) =>
* @param {*} number
*/
const sendMessageList = async (client, number = null, text = null, actionList) => {
console.log("**************** baileys send")
// console.log("**************** baileys send ", number, text, actionList)
setTimeout(async () => {
// console.log("********************** client **************************")
number = cleanNumber(number)
@@ -145,10 +146,10 @@ const sendMessageList = async (client, number = null, text = null, actionList) =
buttonText: remplazos(buttonText, client),
sections
}
console.log(theList)
// console.log(theList)
// console.log(sections[0])
client.sendMessage(number, theList);
await readChat(number, body, actionList)
await readChat(number, body)
console.log('⚡⚡⚡ Enviando lista a '+number+' ....');
}, DELAY_TIME)
}
@@ -179,9 +180,9 @@ const lastTrigger = (number) => new Promise((resolve, reject) => {
* @param {*} number
* @param {*} message
*/
const readChat = async (number, message, trigger = null, regla) => { //MOD by CHV - Agregamos el parametro "regla" para guardarlo en "chats/numero.json"
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, trigger, number, regla ) //MOD by CHV - Agregamos "regla"
await saveMessage( message, number, regla ) //MOD by CHV - Agregamos "regla"
// console.log('Saved')
}

View File

@@ -17,19 +17,20 @@ const mime = require('mime-types')
* @param {*} number
* @param {*} mediaInput
* @param {*} message
* @param {*} caption
* @returns
*/
const sendMedia = async (client, number, fileName, text) => {
console.log("SendMedia = ", number, fileName, text)
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, text)
if (mimeType.includes('video')) return sendVideo(client, number, file, text)
if (mimeType.includes('audio')) return sendAudio(client, number, file, text)
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)
}
}
@@ -68,7 +69,6 @@ const sendImage = async (client, number, fileName, caption) => {
if (fs.existsSync(file)) {
const media = MessageMedia.fromFilePath(file);
client.sendMessage(number, media ,{ sendAudioAsVoice: true });
}
}catch(e) {
throw e;
@@ -79,13 +79,13 @@ const sendImage = async (client, number, fileName, caption) => {
* Enviamos un mensaje simple (texto) a nuestro cliente
* @param {*} number
*/
const sendMessage = async (client, number = null, text = null, trigger = null, regla) => { //MOD by CHV - Agregamos el parametro "regla" para guardarlo en "chats/numero.json"
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, trigger, regla) //MOD by CHV - Agregamos el parametro "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 **************************************");
@@ -96,15 +96,19 @@ const sendMessage = async (client, number = null, text = null, trigger = null, r
* Enviamos un mensaje con buttons a nuestro cliente
* @param {*} number
*/
const sendMessageButton = async (client, number = null, text = null, actionButtons) => {
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));
await readChat(number, message, actionButtons)
let button = new Buttons(
remplazos(message, client),
[...buttons],
remplazos(title, client),
remplazos(footer, client));
console.log("sendMessageButton:", button)
console.log(buttons)
client.sendMessage(number, button);
console.log(`⚡⚡⚡ Enviando mensajes (botones)....`);
// console.log("sendMessageButton.");
await readChat(number, message)
}, DELAY_TIME)
// console.log("************************ SEND MESSAGE BUTTON ***********************************");
}
@@ -117,12 +121,12 @@ const sendMessageList = async (client, number = null, text = null, actionList) =
// console.log("*************** wwebjs send")
setTimeout(async () => {
// console.log("********************** client **************************")
// 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, actionList)
await readChat(number, message)
console.log('⚡⚡⚡ Enviando lista a '+number+' ....');
}, DELAY_TIME)
}
@@ -153,9 +157,9 @@ const lastTrigger = (number) => new Promise((resolve, reject) => {
* @param {*} number
* @param {*} message
*/
const readChat = async (number, message, trigger = null, regla) => { //MOD by CHV - Agregamos el parametro "regla" para guardarlo en "chats/numero.json"
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, trigger, number, regla ) //MOD by CHV - Agregamos "regla"
await saveMessage( message, number, regla ) //MOD by CHV - Agregamos "regla"
// console.log('Saved')
}

View File

@@ -0,0 +1,331 @@
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()

View File

@@ -1,4 +1,10 @@
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
@@ -191,6 +197,47 @@ function traeMensajes(from){ //MOD by CHV - Agregamos para traer el historial de
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?.buttonsResponseMessage?.selectedDisplayText || msg.messages[0].message?.listResponseMessage?.title
let from = remoteJid
let body = theBody
let name = pushName
let hasMedia = false
// console.log("fromBody=", from, body, name)
return {"from":from, "body":body, "name":name, "hasMedia":hasMedia}
}
function traeVariablesFromMsgWWebJS(msg){
const { from, body, hasMedia } = msg;
let name = msg?._data?.notifyName
// console.log("fromBody=", msg?._data)
return {"from":from, "body":body, "name":name, "hasMedia":hasMedia}
}
/**
* Regresa las variables from, body, name, hasMedia y steps del objeto del cliente.
* @param {*} client
* @returns from, body, name, hasMedia y step
*/
function traeVariablesFromClient(client){
// console.log(client)
const { body, from, name, hasMedia, step } = client.theMsg
const { pushName } = client.theMsg
return {"from":from, "body":body, "name":name, "hasMedia":hasMedia, "step":step}
}
/**
* Regresa el número limpio, sin @x.xxx
* @param {*} from
@@ -203,6 +250,13 @@ function soloNumero(from){
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;
@@ -265,7 +319,7 @@ async function variousFuncs(){
else if(rnd==3){caritas = "🧔🏽👧🏽";}
else if(rnd==4){caritas = "👧🏽🧔🏽";}
else if(rnd==5){caritas = "👩🏻‍🦰🧔🏽";}
else if(rnd==6){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 🤑";
@@ -281,7 +335,6 @@ async function variousFuncs(){
retardo();
}
if(body == "/botones"){
// Asi se mandan botones **directamente** con el cliente de whatsapp-web.js "client.sendMessage(from, productList)"
const buttonMessage = [
@@ -455,4 +508,4 @@ function removeDiacritics (str) {
// 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 dutilisation 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 }
module.exports = { removeDiacritics, traeMensajes, chkFile, getRandomInt, remplazos, soloNumero, agregaVars, traeVariablesFromClient, traeVariablesFromMsg }

View File

@@ -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;

1271
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +1,5 @@
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');
@@ -39,8 +40,9 @@ const baileyGenerateImage = async (base64, name = 'qr.png') => {
});
cleanImage.write(PATH_QR);
};
/**
* Iniciar todo Bailey
* Inicializa el Bot con Baileys
*/
initBot = async () => {
console.log("Baileys Init")
@@ -104,30 +106,11 @@ initBot = async () => {
}
// listenMessage(sock.ev)
return sock
}
// run in main file
// initBot()
}
// run in main file
// initBot()
/**
* Regresa las variables from, body, name y hasMedia de el objeto del mensaje.
* @param {*} msg
* @returns from, body, name, hasMedia
*/
function traeVariables(msg){
const { remoteJid } = msg.messages[0].key
const { pushName } = msg.messages[0]
// console.log("THE_MSG = ", client.theMsg.messages[0])
// console.log("*** CONVERSATION=", client.theMsg.messages[0].message?.conversation)
// console.log("*** SELECTEDDISPLAYTEXT=", client.theMsg.messages[0].message?.buttonsResponseMessage?.selectedDisplayText)
// console.log("*** TITLE=", client.theMsg.messages[0].message?.listResponseMessage?.title)
let theBody = msg.messages[0].message?.conversation || msg.messages[0].message?.buttonsResponseMessage?.selectedDisplayText || msg.messages[0].message?.listResponseMessage?.title
let from = remoteJid
let body = theBody
let name = pushName
let hasMedia = false
// console.log("fromBody=", from, body)
return {"from":from, "body":body, "name":name, "hasMedia":hasMedia}
}
module.exports = { initBot, baileyGenerateImage, makeWASocket, traeVariables }
module.exports = { initBot, baileyGenerateImage, makeWASocket }

View File

@@ -14,7 +14,7 @@ app.use('/', require('../routes/web'))
initBot = async () => {
console.log("WaWebJS Init")
client = new Client({
const client = new Client({
authStrategy: new LocalAuth(),
puppeteer: { headless: true, args: ['--no-sandbox','--disable-setuid-sandbox'] }
});
@@ -59,16 +59,4 @@ initBot = async () => {
return client
}
/**
* Regresa las variables from, body, name y hasMedia de el objeto del mensaje.
* @param {*} msg
* @returns from, body, name, hasMedia
*/
function traeVariables(msg){
const { from, body, hasMedia } = msg;
let name = msg?._data?.notifyName
// console.log("fromBody=", msg?._data)
return {"from":from, "body":body, "name":name, "hasMedia":hasMedia}
}
module.exports = { initBot, traeVariables }
module.exports = { initBot }