mirror of
https://github.com/cheveguerra/bot-whatsapp.git
synced 2026-04-21 04:59:15 +00:00
Compare commits
35 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e9ed8e514e | ||
|
|
f36ddd3014 | ||
|
|
3fadaaaf13 | ||
|
|
dfa569f29d | ||
|
|
601508f379 | ||
|
|
e7ad205268 | ||
|
|
f62ba0a076 | ||
|
|
a9efa0aa58 | ||
|
|
3276c21bc3 | ||
|
|
1114f25a71 | ||
|
|
f13a34ff75 | ||
|
|
d45ea85e7d | ||
|
|
10e2b138d3 | ||
|
|
a1bf5ba5c2 | ||
|
|
19102b7b3a | ||
|
|
5efcc2a9a6 | ||
|
|
8279c07a88 | ||
|
|
02d7b3bd98 | ||
|
|
f8f6a3000d | ||
|
|
9a92b152a4 | ||
|
|
f86700deaf | ||
|
|
4ba259b46c | ||
|
|
cf459e94d2 | ||
|
|
4f8ed1361c | ||
|
|
bad8802241 | ||
|
|
f09ac862d5 | ||
|
|
fe7567e1a9 | ||
|
|
9b0b7f4d54 | ||
|
|
3ddbf462a8 | ||
|
|
e6043c99a7 | ||
|
|
b1daa0020e | ||
|
|
190d35c9a5 | ||
|
|
e4378fe848 | ||
|
|
981a6bd928 | ||
|
|
ba4f05ebb2 |
@@ -9,3 +9,5 @@ SQL_HOST=
|
|||||||
SQL_USER=
|
SQL_USER=
|
||||||
SQL_PASS=
|
SQL_PASS=
|
||||||
SQL_DATABASE=
|
SQL_DATABASE=
|
||||||
|
KEEP_DIALOG_FLOW=false
|
||||||
|
MULTI_DEVICE=true
|
||||||
@@ -12,3 +12,7 @@
|
|||||||
- add support for ubuntu/linux
|
- add support for ubuntu/linux
|
||||||
|
|
||||||
https://stackoverflow.com/questions/51855169/dialogflow-403-iam-permission-dialogflow-sessions-detectintent
|
https://stackoverflow.com/questions/51855169/dialogflow-403-iam-permission-dialogflow-sessions-detectintent
|
||||||
|
|
||||||
|
#### Actualización 20 Oct 2022
|
||||||
|
- npm update
|
||||||
|
- use node crypto instead of nanoid
|
||||||
|
|||||||
@@ -1,17 +1,18 @@
|
|||||||
## Chatbot Whatsapp (OpenSource)
|
## Chatbot Whatsapp (OpenSource)
|
||||||
#### Actualizado Enero 2022
|
#### Actualizado Abril 2022
|
||||||
|
|
||||||
El siguiente proyecto se realizó con fines educativos para el canal de [Youtube (Leifer Mendez)](https://www.youtube.com/channel/UCgrIGp5QAnC0J8LfNJxDRDw?sub_confirmation=1) donde aprendemos a crear y implementar un chatbot increíble usando [node.js](https://codigoencasa.com/tag/nodejs/) además le agregamos inteligencia artificial gracias al servicio de __dialogflow__.
|
El siguiente proyecto se realizó con fines educativos para el canal de [Youtube (Leifer Mendez)](https://www.youtube.com/channel/UCgrIGp5QAnC0J8LfNJxDRDw?sub_confirmation=1) donde aprendemos a crear y implementar un chatbot increíble usando [node.js](https://codigoencasa.com/tag/nodejs/) además le agregamos inteligencia artificial gracias al servicio de __dialogflow__.
|
||||||
|
|
||||||
[](https://youtu.be/5lEMCeWEJ8o)
|
[](https://youtu.be/5lEMCeWEJ8o)
|
||||||
|
|
||||||
### ATENCION 1 🔴
|
### ATENCION 🔴
|
||||||
> 💥💥 Si te aparece el Error Multi-device es porque tienes la cuenta de whatsapp afiliada al modo "BETA de Multi dispositivo" por el momento no se tiene soporte para esas personas si tu quieres hacer uso de este __BOT__ debes de salir del modo BETA y intentarlo de la manera tradicional
|
> 💥💥 Si te aparece el Error Multi-device es porque tienes la cuenta de whatsapp afiliada al modo "BETA de Multi dispositivo" por el momento no se tiene soporte para esas personas si tu quieres hacer uso de este __BOT__ debes de salir del modo BETA y intentarlo de la manera tradicional
|
||||||
|
|
||||||
### ATENCION 2 🔴
|
|
||||||
> El core de whatsapp esta en constante actualizaciones por lo cual siempre revisa la ultima fecha de la actualizacion
|
> El core de whatsapp esta en constante actualizaciones por lo cual siempre revisa la ultima fecha de la actualizacion
|
||||||
> [VER](https://github.com/leifermendez/bot-whatsapp/commits/main)
|
> [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
|
||||||
|
|
||||||
#### Acceso rápido
|
#### Acceso rápido
|
||||||
> Si tienes una cuenta en __heroku__ puedes desplegar este proyecto con (1 click)
|
> Si tienes una cuenta en __heroku__ puedes desplegar este proyecto con (1 click)
|
||||||
@@ -31,7 +32,7 @@ El siguiente proyecto se realizó con fines educativos para el canal de [Youtube
|
|||||||
| JSON File | ✅ |
|
| JSON File | ✅ |
|
||||||
| QR Scan (route) | ✅ |
|
| QR Scan (route) | ✅ |
|
||||||
| Easy deploy heroku | ✅ |
|
| Easy deploy heroku | ✅ |
|
||||||
| Buttons | ✅ |
|
| Buttons | ✅ℹ️ (No funciona en multi-device)|
|
||||||
| Send Voice Note | ✅ |
|
| Send Voice Note | ✅ |
|
||||||
| Add support ubuntu/linux | ✅ |
|
| Add support ubuntu/linux | ✅ |
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
const dialogflow = require('@google-cloud/dialogflow');
|
const dialogflow = require('@google-cloud/dialogflow');
|
||||||
const fs = require('fs')
|
const fs = require('fs')
|
||||||
const nanoid = require('nanoid')
|
const crypto = require('crypto');
|
||||||
/**
|
/**
|
||||||
* Debes de tener tu archivo con el nombre "chatbot-account.json" en la raíz del proyecto
|
* Debes de tener tu archivo con el nombre "chatbot-account.json" en la raíz del proyecto
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
const KEEP_DIALOG_FLOW = (process.env.KEEP_DIALOG_FLOW === 'true')
|
||||||
let PROJECID;
|
let PROJECID;
|
||||||
let CONFIGURATION;
|
let CONFIGURATION;
|
||||||
let sessionClient;
|
let sessionClient;
|
||||||
@@ -30,7 +32,7 @@ const checkFileCredentials = () => {
|
|||||||
// Detect intent method
|
// Detect intent method
|
||||||
const detectIntent = async (queryText) => {
|
const detectIntent = async (queryText) => {
|
||||||
let media = null;
|
let media = null;
|
||||||
const sessionId = nanoid.nanoid()
|
const sessionId = KEEP_DIALOG_FLOW ? 1 : crypto.randomUUID();
|
||||||
const sessionPath = sessionClient.projectAgentSessionPath(PROJECID, sessionId);
|
const sessionPath = sessionClient.projectAgentSessionPath(PROJECID, sessionId);
|
||||||
const languageCode = process.env.LANGUAGE
|
const languageCode = process.env.LANGUAGE
|
||||||
const request = {
|
const request = {
|
||||||
@@ -54,7 +56,7 @@ const detectIntent = async (queryText) => {
|
|||||||
const { fields } = parsePayload.payload
|
const { fields } = parsePayload.payload
|
||||||
media = fields.media.stringValue || null
|
media = fields.media.stringValue || null
|
||||||
}
|
}
|
||||||
// const customPayload = parsePayload['payload']
|
const customPayload = parsePayload['payload']
|
||||||
|
|
||||||
const parseData = {
|
const parseData = {
|
||||||
replyMessage: queryResult.fulfillmentText,
|
replyMessage: queryResult.fulfillmentText,
|
||||||
|
|||||||
@@ -82,6 +82,7 @@ const saveMessage = ( message, trigger, number ) => new Promise( async (resolve
|
|||||||
resolve( await saveMessageJson( message, trigger, number ) )
|
resolve( await saveMessageJson( message, trigger, number ) )
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
resolve(true)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ getReply = (option_key = '', callback) => connection.query(
|
|||||||
replyMessage:response?.replyMessage || '',
|
replyMessage:response?.replyMessage || '',
|
||||||
trigger:response?.trigger || '',
|
trigger:response?.trigger || '',
|
||||||
media:response?.media || ''
|
media:response?.media || ''
|
||||||
|
|
||||||
}
|
}
|
||||||
callback(value)
|
callback(value)
|
||||||
});
|
});
|
||||||
@@ -51,13 +52,15 @@ saveMessageMysql = ( message, date, trigger, number ) => new Promise((resolve,re
|
|||||||
connection.query(
|
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`, `trigger`, `number`)"+` VALUES ('${message}','${date}','${trigger}', '${number}')` , (error, results) => {
|
||||||
if(error) {
|
if(error) {
|
||||||
if( error.code === 'ER_NO_SUCH_TABLE' ){
|
//TODO esta parte es mejor incluirla directamente en el archivo .sql template
|
||||||
connection.query( `CREATE TABLE ${DATABASE_NAME}.messages `+"( `date` DATE NOT NULL , `message` VARCHAR(450) NOT NULL , `trigger` VARCHAR(450) NOT NULL , `number` VARCHAR(50) NOT NULL ) ENGINE = InnoDB", async (error, results) => {
|
console.log('DEBES DE CREAR LA TABLA DE MESSAGE')
|
||||||
setTimeout( async () => {
|
// if( error.code === 'ER_NO_SUCH_TABLE' ){
|
||||||
return resolve( await this.saveMessageMysql( message, date, trigger, number ) )
|
// connection.query( `CREATE TABLE ${DATABASE_NAME}.messages `+"( `date` DATE NOT NULL , `message` VARCHAR(450) NOT NULL , `trigger` VARCHAR(450) NOT NULL , `number` VARCHAR(50) NOT NULL ) ENGINE = InnoDB", async (error, results) => {
|
||||||
}, 150)
|
// setTimeout( async () => {
|
||||||
})
|
// return resolve( await this.saveMessageMysql( message, date, trigger, number ) )
|
||||||
}
|
// }, 150)
|
||||||
|
// })
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
console.log('Saved')
|
console.log('Saved')
|
||||||
console.log( results )
|
console.log( results )
|
||||||
|
|||||||
129
app.js
129
app.js
@@ -6,10 +6,10 @@ const fs = require('fs');
|
|||||||
const express = require('express');
|
const express = require('express');
|
||||||
const cors = require('cors')
|
const cors = require('cors')
|
||||||
const qrcode = require('qrcode-terminal');
|
const qrcode = require('qrcode-terminal');
|
||||||
const { Client, LegacySessionAuth } = require('whatsapp-web.js');
|
const { Client,LocalAuth } = require('whatsapp-web.js');
|
||||||
const mysqlConnection = require('./config/mysql')
|
const mysqlConnection = require('./config/mysql')
|
||||||
const { middlewareClient } = require('./middleware/client')
|
const { middlewareClient } = require('./middleware/client')
|
||||||
const { generateImage, cleanNumber, checkEnvFile } = require('./controllers/handle')
|
const { generateImage, cleanNumber, checkEnvFile, createClient, isValidNumber } = require('./controllers/handle')
|
||||||
const { connectionReady, connectionLost } = require('./controllers/connection')
|
const { connectionReady, connectionLost } = require('./controllers/connection')
|
||||||
const { saveMedia } = require('./controllers/save')
|
const { saveMedia } = require('./controllers/save')
|
||||||
const { getMessages, responseMessages, bothResponse } = require('./controllers/flows')
|
const { getMessages, responseMessages, bothResponse } = require('./controllers/flows')
|
||||||
@@ -17,35 +17,23 @@ const { sendMedia, sendMessage, lastTrigger, sendMessageButton, readChat } = req
|
|||||||
const app = express();
|
const app = express();
|
||||||
app.use(cors())
|
app.use(cors())
|
||||||
app.use(express.json())
|
app.use(express.json())
|
||||||
|
const MULTI_DEVICE = process.env.MULTI_DEVICE || 'true';
|
||||||
const server = require('http').Server(app)
|
const server = require('http').Server(app)
|
||||||
const io = require('socket.io')(server, {
|
|
||||||
cors: {
|
|
||||||
origins: ['http://localhost:4200']
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
let socketEvents = {sendQR:() => {} ,sendStatus:() => {}};
|
|
||||||
|
|
||||||
io.on('connection', (socket) => {
|
|
||||||
const CHANNEL = 'main-channel';
|
|
||||||
socket.join(CHANNEL);
|
|
||||||
socketEvents = require('./controllers/socket')(socket)
|
|
||||||
console.log('Se conecto')
|
|
||||||
})
|
|
||||||
|
|
||||||
app.use('/', require('./routes/web'))
|
|
||||||
|
|
||||||
const port = process.env.PORT || 3000
|
const port = process.env.PORT || 3000
|
||||||
const SESSION_FILE_PATH = './session.json';
|
|
||||||
var client;
|
var client;
|
||||||
var sessionData;
|
app.use('/', require('./routes/web'))
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Escuchamos cuando entre un mensaje
|
* Escuchamos cuando entre un mensaje
|
||||||
*/
|
*/
|
||||||
const listenMessage = () => client.on('message', async msg => {
|
const listenMessage = () => client.on('message', async msg => {
|
||||||
const { from, body, hasMedia } = msg;
|
const { from, body, hasMedia } = msg;
|
||||||
|
|
||||||
|
if(!isValidNumber(from)){
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// Este bug lo reporto Lucas Aldeco Brescia para evitar que se publiquen estados
|
// Este bug lo reporto Lucas Aldeco Brescia para evitar que se publiquen estados
|
||||||
if (from === 'status@broadcast') {
|
if (from === 'status@broadcast') {
|
||||||
return
|
return
|
||||||
@@ -68,6 +56,7 @@ const listenMessage = () => client.on('message', async msg => {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
if (process.env.DATABASE === 'dialogflow') {
|
if (process.env.DATABASE === 'dialogflow') {
|
||||||
|
if(!message.length) return;
|
||||||
const response = await bothResponse(message);
|
const response = await bothResponse(message);
|
||||||
await sendMessage(client, from, response.replyMessage);
|
await sendMessage(client, from, response.replyMessage);
|
||||||
if (response.media) {
|
if (response.media) {
|
||||||
@@ -101,6 +90,7 @@ const listenMessage = () => client.on('message', async msg => {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
await sendMessage(client, from, response.replyMessage, response.trigger);
|
await sendMessage(client, from, response.replyMessage, response.trigger);
|
||||||
|
|
||||||
if(response.hasOwnProperty('actions')){
|
if(response.hasOwnProperty('actions')){
|
||||||
const { actions } = response;
|
const { actions } = response;
|
||||||
await sendMessageButton(client, from, null, actions);
|
await sendMessageButton(client, from, null, actions);
|
||||||
@@ -134,105 +124,38 @@ const listenMessage = () => client.on('message', async msg => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
|
||||||
* Revisamos si tenemos credenciales guardadas para inciar sessio
|
|
||||||
* este paso evita volver a escanear el QRCODE
|
client = new Client({
|
||||||
*/
|
authStrategy: new LocalAuth(),
|
||||||
const withSession = () => {
|
puppeteer: { headless: true }
|
||||||
// Si exsite cargamos el archivo con las credenciales
|
|
||||||
console.log(`Validando session con Whatsapp...`)
|
|
||||||
sessionData = require(SESSION_FILE_PATH);
|
|
||||||
client = new Client({
|
|
||||||
authStrategy: new LegacySessionAuth({
|
|
||||||
session: sessionData // saved session object
|
|
||||||
}),
|
|
||||||
restartOnAuthFail: true,
|
|
||||||
puppeteer: {
|
|
||||||
args: [
|
|
||||||
'--no-sandbox'
|
|
||||||
],
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
client.on('ready', () => {
|
client.on('qr', qr => generateImage(qr, () => {
|
||||||
connectionReady()
|
|
||||||
listenMessage()
|
|
||||||
loadRoutes(client);
|
|
||||||
socketEvents.sendStatus()
|
|
||||||
});
|
|
||||||
|
|
||||||
client.on('auth_failure', () => connectionLost())
|
|
||||||
|
|
||||||
client.initialize();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Generamos un QRCODE para iniciar sesion
|
|
||||||
*/
|
|
||||||
const withOutSession = () => {
|
|
||||||
console.log('No tenemos session guardada');
|
|
||||||
console.log([
|
|
||||||
'🙌 El core de whatsapp se esta actualizando',
|
|
||||||
'🙌 para proximamente dar paso al multi-device',
|
|
||||||
'🙌 falta poco si quieres estar al pendiente unete',
|
|
||||||
'🙌 http://t.me/leifermendez',
|
|
||||||
'________________________',
|
|
||||||
].join('\n'));
|
|
||||||
|
|
||||||
client = new Client({
|
|
||||||
session: { },
|
|
||||||
// authStrategy: new LegacySessionAuth({
|
|
||||||
// session: { }
|
|
||||||
// }),
|
|
||||||
restartOnAuthFail: true,
|
|
||||||
puppeteer: {
|
|
||||||
args: [
|
|
||||||
'--no-sandbox'
|
|
||||||
],
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
client.on('qr', qr => generateImage(qr, () => {
|
|
||||||
qrcode.generate(qr, { small: true });
|
qrcode.generate(qr, { small: true });
|
||||||
|
|
||||||
console.log(`Ver QR http://localhost:${port}/qr`)
|
console.log(`Ver QR http://localhost:${port}/qr`)
|
||||||
socketEvents.sendQR(qr)
|
socketEvents.sendQR(qr)
|
||||||
}))
|
}))
|
||||||
|
|
||||||
client.on('ready', (a) => {
|
client.on('ready', (a) => {
|
||||||
connectionReady()
|
connectionReady()
|
||||||
listenMessage()
|
listenMessage()
|
||||||
loadRoutes(client);
|
|
||||||
// socketEvents.sendStatus(client)
|
// socketEvents.sendStatus(client)
|
||||||
});
|
});
|
||||||
|
|
||||||
client.on('auth_failure', (e) => {
|
client.on('auth_failure', (e) => {
|
||||||
// console.log(e)
|
// console.log(e)
|
||||||
// connectionLost()
|
// connectionLost()
|
||||||
});
|
});
|
||||||
|
|
||||||
client.on('authenticated', (session) => {
|
client.on('authenticated', () => {
|
||||||
sessionData = session;
|
console.log('AUTHENTICATED');
|
||||||
fs.writeFile(SESSION_FILE_PATH, JSON.stringify(session), function (err) {
|
});
|
||||||
if (err) {
|
|
||||||
console.log(`Ocurrio un error con el archivo: `, err);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
client.initialize();
|
client.initialize();
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Cargamos rutas de express
|
|
||||||
*/
|
|
||||||
|
|
||||||
const loadRoutes = (client) => {
|
|
||||||
app.use('/api/', middlewareClient(client), require('./routes/api'))
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Revisamos si existe archivo con credenciales!
|
|
||||||
*/
|
|
||||||
(fs.existsSync(SESSION_FILE_PATH)) ? withSession() : withOutSession();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verificamos si tienes un gesto de db
|
* Verificamos si tienes un gesto de db
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
const mysql = require('mysql');
|
const mysql = require('mysql');
|
||||||
const connection = mysql.createConnection({
|
const connection = mysql.createConnection({
|
||||||
host : process.env.SQL_HOST || 'localhost',
|
host : process.env.SQL_HOST || 'localhost',
|
||||||
user : process.env.SQL_USER || 'me',
|
user : process.env.SQL_USER || 'root',
|
||||||
password : process.env.SQL_PASS || '',
|
password : process.env.SQL_PASS || '',
|
||||||
database : process.env.SQL_DATABASE || 'my_db'
|
database : process.env.SQL_DATABASE || 'pruebas'
|
||||||
});
|
});
|
||||||
|
|
||||||
const connect = () => connection.connect(function(err) {
|
const connect = () => connection.connect(function(err) {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
const connectionReady = (cb = () =>{}) => {
|
const connectionReady = (cb = () =>{}) => {
|
||||||
console.log('Listo para escuchas mensajes')
|
console.log('Listo para escuchas mensajes')
|
||||||
console.log('Client is ready!');
|
console.log('Client is ready!');
|
||||||
|
console.log('🔴 escribe: hola');
|
||||||
cb()
|
cb()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
|
const { Client, LegacySessionAuth, LocalAuth } = require('whatsapp-web.js');
|
||||||
const http = require('http'); // or 'https' for https:// URLs
|
const http = require('http'); // or 'https' for https:// URLs
|
||||||
const https = require('https'); // or 'https' for https:// URLs
|
const https = require('https'); // or 'https' for https:// URLs
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const qr = require('qr-image')
|
const qr = require('qr-image')
|
||||||
|
|
||||||
|
const MULTI_DEVICE = process.env.MULTI_DEVICE || 'true';
|
||||||
|
|
||||||
const cleanNumber = (number) => {
|
const cleanNumber = (number) => {
|
||||||
number = number.replace('@c.us', '');
|
number = number.replace('@c.us', '');
|
||||||
@@ -57,4 +59,25 @@ const checkEnvFile = () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {cleanNumber, saveExternalFile, generateImage, checkIsUrl, checkEnvFile}
|
/**
|
||||||
|
*
|
||||||
|
* @param {*} session
|
||||||
|
* @param {*} cb
|
||||||
|
*/
|
||||||
|
const createClient = () => {
|
||||||
|
client = new Client({
|
||||||
|
authStrategy: new LocalAuth(
|
||||||
|
{dataPath: './sessions/',
|
||||||
|
clientId: 'bot'}),
|
||||||
|
puppeteer: { headless: false }
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const isValidNumber = (rawNumber) => {
|
||||||
|
const regexGroup = /\@g.us\b/gm;
|
||||||
|
const exist = rawNumber.match(regexGroup);
|
||||||
|
return !exist
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {cleanNumber, saveExternalFile, generateImage, checkIsUrl, checkEnvFile, createClient, isValidNumber}
|
||||||
@@ -15,13 +15,18 @@ const { saveMessage } = require('../adapter')
|
|||||||
* @param {*} fileName
|
* @param {*} fileName
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const sendMedia = (client, number, fileName) => {
|
const sendMedia = (client, number = null, fileName = null) => {
|
||||||
number = cleanNumber(number)
|
if(!client) return cosnole.error("El objeto cliente no está definido.");
|
||||||
|
try {
|
||||||
|
number = cleanNumber(number || 0)
|
||||||
const file = `${DIR_MEDIA}/${fileName}`;
|
const file = `${DIR_MEDIA}/${fileName}`;
|
||||||
if (fs.existsSync(file)) {
|
if (fs.existsSync(file)) {
|
||||||
const media = MessageMedia.fromFilePath(file);
|
const media = MessageMedia.fromFilePath(file);
|
||||||
client.sendMessage(number, media, { sendAudioAsVoice: true });
|
client.sendMessage(number, media, { sendAudioAsVoice: true });
|
||||||
}
|
}
|
||||||
|
} catch(e) {
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -30,15 +35,21 @@ const sendMedia = (client, number, fileName) => {
|
|||||||
* @param {*} fileName
|
* @param {*} fileName
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const sendMediaVoiceNote = (client, number, fileName) => {
|
const sendMediaVoiceNote = (client, number = null, fileName = null) => {
|
||||||
number = cleanNumber(number)
|
if(!client) return cosnole.error("El objeto cliente no está definido.");
|
||||||
|
try {
|
||||||
|
number = cleanNumber(number || 0)
|
||||||
const file = `${DIR_MEDIA}/${fileName}`;
|
const file = `${DIR_MEDIA}/${fileName}`;
|
||||||
if (fs.existsSync(file)) {
|
if (fs.existsSync(file)) {
|
||||||
const media = MessageMedia.fromFilePath(file);
|
const media = MessageMedia.fromFilePath(file);
|
||||||
client.sendMessage(number, media ,{ sendAudioAsVoice: true });
|
client.sendMessage(number, media ,{ sendAudioAsVoice: true });
|
||||||
|
|
||||||
}
|
}
|
||||||
|
}catch(e) {
|
||||||
|
throw e;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* Enviamos un mensaje simple (texto) a nuestro cliente
|
* Enviamos un mensaje simple (texto) a nuestro cliente
|
||||||
* @param {*} number
|
* @param {*} number
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ const fs = require('fs')
|
|||||||
const { sendMessage } = require('../controllers/send')
|
const { sendMessage } = require('../controllers/send')
|
||||||
|
|
||||||
const sendMessagePost = (req, res) => {
|
const sendMessagePost = (req, res) => {
|
||||||
|
console.log('asdasdasdasdasd')
|
||||||
const { message, number } = req.body
|
const { message, number } = req.body
|
||||||
const client = req.clientWs || null;
|
const client = req.clientWs || null;
|
||||||
sendMessage(client, number, message)
|
sendMessage(client, number, message)
|
||||||
|
|||||||
@@ -27,7 +27,7 @@
|
|||||||
"\n Si necesitas ver más info sobre las capacitacion tecnicas ",
|
"\n Si necesitas ver más info sobre las capacitacion tecnicas ",
|
||||||
"escribe *cursos* o *info* o escribe *audio*"
|
"escribe *cursos* o *info* o escribe *audio*"
|
||||||
],
|
],
|
||||||
"media":null,
|
"media":"https://media2.giphy.com/media/VQJu0IeULuAmCwf5SL/giphy.gif",
|
||||||
"trigger":null,
|
"trigger":null,
|
||||||
"actions":{
|
"actions":{
|
||||||
"title":"¿Que te interesa ver?",
|
"title":"¿Que te interesa ver?",
|
||||||
|
|||||||
7191
package-lock.json
generated
7191
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
56
package.json
56
package.json
@@ -1,38 +1,58 @@
|
|||||||
{
|
{
|
||||||
"name": "test-ws-bot",
|
"name": "bot-whatsapp",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"description": "",
|
"description": "Bot de wahtsapp open source para MVP o pequeños negocios",
|
||||||
"main": "app.js",
|
"main": "app.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "node ./app.js",
|
"start": "node ./app.js",
|
||||||
"test": "echo \"Error: no test specified\" && exit 1"
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
},
|
},
|
||||||
"keywords": [],
|
"keywords": [
|
||||||
"author": "",
|
"whatsapp",
|
||||||
|
"bot-whatsapp",
|
||||||
|
"node-bot-whatsapp"
|
||||||
|
],
|
||||||
|
|
||||||
|
"contributors": [
|
||||||
|
{
|
||||||
|
"email": "leifer33@gmail.com",
|
||||||
|
"name": "Leifer Mendez",
|
||||||
|
"url": "https://leifermendez.github.io"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "aurik3",
|
||||||
|
"email": "aurik3@aurik3.com",
|
||||||
|
"url": "https://github.com/aurik3"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/leifermendez/bot-whatsapp"
|
||||||
|
},
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@google-cloud/dialogflow": "^4.6.0",
|
"@google-cloud/dialogflow": "^5.2.0",
|
||||||
"cors": "^2.8.5",
|
"cors": "^2.8.5",
|
||||||
"dotenv": "^11.0.0",
|
"dotenv": "^16.0.1",
|
||||||
"exceljs": "^4.3.0",
|
"exceljs": "^4.3.0",
|
||||||
"express": "^4.17.2",
|
"express": "^4.18.1",
|
||||||
"file-type": "^16.5.3",
|
"file-type": "^17.1.6",
|
||||||
"mime-db": "^1.51.0",
|
"mime-db": "^1.52.0",
|
||||||
"moment": "^2.29.1",
|
"moment": "^2.29.4",
|
||||||
"mysql": "^2.18.1",
|
"mysql": "^2.18.1",
|
||||||
"nanoid": "^3.1.32",
|
|
||||||
"qr-image": "^3.2.0",
|
"qr-image": "^3.2.0",
|
||||||
"qrcode-terminal": "^0.12.0",
|
"qrcode-terminal": "^0.12.0",
|
||||||
"socket.io": "^4.4.1",
|
"socket.io": "^4.5.1",
|
||||||
"stormdb": "^0.5.2",
|
"stormdb": "^0.6.0",
|
||||||
"whatsapp-web.js": "^1.16.4",
|
"whatsapp-web.js": "^1.17.1",
|
||||||
"xlsx": "^0.16.9"
|
"xlsx": "^0.18.5"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"pm2": "^5.1.2",
|
"pm2": "^5.2.0",
|
||||||
"prettier": "2.5.1"
|
"prettier": "2.7.1"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "14.x"
|
"node": "16.x"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
const express = require('express')
|
const express = require('express')
|
||||||
const router = express.Router();
|
const router = express.Router();
|
||||||
const { sendMessagePost } = require('../controllers/web')
|
const { sendMessagePost } = require('../controllers/web')|
|
||||||
|
|
||||||
router.post('/send', sendMessagePost)
|
router.post('/send', sendMessagePost)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user