-
Notifications
You must be signed in to change notification settings - Fork 0
/
original.js
453 lines (346 loc) · 14.6 KB
/
original.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
/**
* ⚡ DECLARAMOS LAS LIBRERIAS y CONSTANTES A USAR! ⚡
*/
const fs = require('fs');
const mimeDb = require('mime-db')
const express = require('express');
const moment = require('moment');
const ora = require('ora');
const chalk = require('chalk');
const ExcelJS = require('exceljs');
const qrcode = require('qrcode-terminal');
const { flowConversation } = require('./conversation')
const { Client, MessageMedia } = require('whatsapp-web.js');
const app = express();
app.use(express.urlencoded({ extended: true }))
const SESSION_FILE_PATH = './session.json';
let client;
let sessionData;
const { presentacion, info1, info2, info3, info4 } = require('./mensajes');
const { time } = require('console');
const { resolve } = require('path');
/**
* Guardamos archivos multimedia que nuestro cliente nos envie!
* @param {*} media
*/
const saveMedia = (media) => {
const extensionProcess = mimeDb[media.mimetype]
const ext = extensionProcess.extensions[0]
fs.writeFile(`./media/${media.filename}.${ext}`, media.data, { encoding: 'base64' }, function (err) {
console.log('** Archivo Media Guardado **');
});
}
/**
* Enviamos archivos multimedia a nuestro cliente
* @param {*} number
* @param {*} fileName
*/
const sendMedia = (number, fileName) => {
number = number.replace('@c.us', '');
number = `${number}@c.us`
const media = MessageMedia.fromFilePath(`./mediaSend/${fileName}`);
client.sendMessage(number, media);
}
/**
* Enviamos un mensaje simple (texto) a nuestro cliente
* @param {*} number
*/
const sendMessage = (number = null, text = null) => {
number = number.replace('@c.us', '');
number = `${number}@c.us`
const message = text || `Hola soy un BOT recuerda https://www.youtube.com/leifermendez`;
client.sendMessage(number, message);
readChat(number, message)
console.log(`${chalk.green('📺 Mensaje a: '+ number)}`);
}
/**
* Escuchamos cuando entre un mensaje
*/
const listenMessage = () => {
client.on('message', async msg => {
const { from, to, body } = msg;
//34691015468@c.us
if (msg.hasMedia) {
console.log(`${chalk.grey("Tiene media> "+msg.hasMedia)}`)
const media = await msg.downloadMedia();
saveMedia(media);
// do something with the media data here
}
await greetCustomer(from);
console.log(`NUMERO NUEVO
${chalk.yellow(`📩 Recibido a las ${timeNow()} de ${from}: `)}
"${body}"\n`)
await replyAsk(from, body);
// await readChat(from, body)
// console.log(`${chalk.red('⚡⚡⚡ Enviando mensajes....')}`);
// console.log('Guardar este número en tu Base de Datos:', from);
});
}
/**
* Response a pregunta
*/
const replyAsk = (from, answer) => new Promise((resolve, reject) => {
console.log(`${chalk.yellow(`📩 Recibido a las ${timeNow()} de ${from}`)}
"${answer}"\n`)
/*
if (answer.toLowerCase()==='info'||answer.toLowerCase()==='informacion') {
sendMessageSync(from, presentacion, 1)
sendMessageSync(from, info1, 500)
sendMessageSync(from, info2, 1000)
sendMessageSync(from, info3, 1500)
sendMessageSync(from, info4, 2000)
sendMessageSync(from, '*Modelos de certificados*', 2500)
sendMediaSync(from, './todosCertificados.png', 3000)
ultimoMensaje(from, 4000)
} */
if (answer.toLowerCase()==='instructor'||answer.toLowerCase()==='intructor'||answer.toLowerCase()==='ezequiel') {
sendMessageSync(from, `🤖 *El instructor Ezequiel se contactará con usted cuando sea posible (estamos atendiendo muchas consultas)* ⏳ \nMientras tanto puede consultarme a mi lo que desee
*Envieme un mensaje con algunos de los siguientes números para tener mas informacion, o envie la palabra info para tener toda la informacion del curso*
• Envie un *1* para saber cómo inscribirse de forma gratuita (sin certificado)
• Envie un *2* para saber cómo inscribirse de forma paga (con certificado) y para saber cuando cuestan los certificados
• Envie un *3* para saber cómo son los cursos, duración, pasos a seguir etc.
• Envie un *4* para saber horarios del encuentro virtual de cada curso
• Envie un *5* para saber de donde somos
• Envie un *6* para saber si las clases son virtuales
• Envie un *7* para saber cuanto tarda en llegar el certificado
• Envie un *8* para ver modelos de certificados
`, 10)
}
else if (answer === "1"|| answer =="*1*" || answer =="uno") {
sendMessageSync(from, info1, 10)
ultimoMensaje(from, 1000)
}
else if (answer === "2"|| answer =="*2*" || answer =="dos") {
sendMessageSync(from, info2, 10)
ultimoMensaje(from, 1000)
}
else if (answer === "3"|| answer =="*3*" || answer =="tres") {
sendMessageSync(from, info3, 10)
ultimoMensaje(from, 1000)
}
else if (answer === "4"|| answer =="*4*" || answer =="cuatro") {
sendMessageSync(from, info4, 10)
ultimoMensaje(from, 1000)
}
else if (answer === "5"|| answer =="*5*" || answer =="cinco" || answer =="sinco") {
sendMessageSync(from, "*El instructor es de Buenos Aires, pero los cursos se dan en todo el pais.*", 10)
ultimoMensaje(from, 1000)
}
else if (answer === "6"|| answer =="*6*" || answer =="seis") {
sendMessageSync(from, "*Las clases son 100% virtuales*", 10)
ultimoMensaje(from, 1000)
}
else if (answer === "7"|| answer =="*7*" || answer =="siete") {
sendMessageSync(from, "*Luego de aprobar un curso, si abono un certificado deberá completar una planilla con sus datos para solicitarlo, y en menos de un minuto le estará llegando a su casilla de mail, firmado digitalmente y con dos códigos de autenticidad. Al enviar la planilla un programa comprueba si es de las personas aprobadas, genera un certificado y se los envia automaticamente*", 10)
ultimoMensaje(from, 1000)
}
else if (answer === "8"|| answer =="*8*" || answer =="ocho") {
sendMessageSync(from, `*Modelos de certificados*
https://photos.app.goo.gl/Grm54bW161weeXB26`, 10)
sendMediaSync(from, './todosCertificados.png', 500)
ultimoMensaje(from, 1000)
}
else if(answer==="🤖") sendMessageSync(from, '*🤖 Soy el bot Dominique Larrey, tomo mi nombre del inventor de la ambulancia y del triage. "Dominique-Jean Larrey fue un cirujano que, en las guerras napoleónicas, creó el transporte por ambulancia e introdujo los principios de la sanidad militar moderna, realizando los primeros triaje en los campos de batalla.". Mas info en Wikipedia https://es.wikipedia.org/wiki/Dominique-Jean_Larrey*', 10)
resolveSync(resolve, 4500)
})
/**
* Revisamos si tenemos credenciales guardadas para inciar sessio
* este paso evita volver a escanear el QRCODE
*/
const withSession = () => {
// Si exsite cargamos el archivo con las credenciales
const spinner = ora(`Cargando ${chalk.yellow('Validando session con Whatsapp...')}`);
sessionData = require(SESSION_FILE_PATH);
spinner.start();
client = new Client({
session: sessionData //creo el cliente pero con esta secion iniciada, es como una forma de emular la persistencia de la secion
});
client.on('ready', () => {
console.log('Client is ready!');
spinner.stop();//para el spinner
// sendMessage();
// sendMedia();
connectionReady();
});
client.on('auth_failure', () => {
spinner.stop();
console.log('** Error de autentificacion vuelve a generar el QRCODE (Borrar el archivo session.json) **');
})
client.initialize();
}
/**
* Generamos un QRCODE para iniciar sesion
*/
const withOutSession = () => {
console.log('No tenemos session guardada');
client = new Client();
client.on('qr', qr => {
qrcode.generate(qr, { small: true });
});
client.on('ready', () => {
console.log('Client is ready!');
connectionReady();
});
client.on('auth_failure', () => {
console.log('** Error de autentificacion vuelve a generar el QRCODE **');
})
client.on('authenticated', (session) => {
// Guardamos credenciales de de session para usar luego
sessionData = session;
fs.writeFile(SESSION_FILE_PATH, JSON.stringify(session), function (err) {
if (err) {
console.log(err);
}
});
});
client.initialize();
}
const connectionReady = () => {
listenMessage();
readExcel();
}
/**
* Difundir mensaje a clientes
*/
const readExcel = async () => {
const pathExcel = `./chats/clientes-saludar.xlsx`;
const workbook = new ExcelJS.Workbook();
await workbook.xlsx.readFile(pathExcel);
const worksheet = workbook.getWorksheet(1);
const columnNumbers = worksheet.getColumn('A');
columnNumbers.eachCell((cell, rowNumber) => {
const numberCustomer = cell.value
const columnDate = worksheet.getRow(rowNumber);
let prevDate = columnDate.getCell(2).value;
prevDate = moment.unix(prevDate);
const diffMinutes = moment().diff(prevDate, 'minutes');
// Si ha pasado mas de 60 minuitos podemos enviar nuevamente
if (diffMinutes > 60) {
sendMessage(numberCustomer)
columnDate.getCell(2).value = moment().format('X')
columnDate.commit();
}
});
workbook.xlsx.writeFile(pathExcel);
}
/**
* Guardar historial de conversacion
* @param {*} number
* @param {*} message
*/
const readChat = async (number, message) => {
const pathExcel = `./chats/${number}.xlsx`;
const workbook = new ExcelJS.Workbook();
const today = moment().format('DD-MM-YYYY hh:mm')
if (fs.existsSync(pathExcel)) {
/**
* Si existe el archivo de conversacion lo actualizamos
*/
const workbook = new ExcelJS.Workbook();
workbook.xlsx.readFile(pathExcel)
.then(() => {
const worksheet = workbook.getWorksheet(1);
const lastRow = worksheet.lastRow;
var getRowInsert = worksheet.getRow(++(lastRow.number));
getRowInsert.getCell('A').value = today;
getRowInsert.getCell('B').value = message;
getRowInsert.commit();
workbook.xlsx.writeFile(pathExcel);
});
} else {
/**
* NO existe el archivo de conversacion lo creamos
*/
const worksheet = workbook.addWorksheet('Chats');
worksheet.columns = [
{ header: 'Fecha', key: 'number_customer' },
{ header: 'Mensajes', key: 'message' }
];
worksheet.addRow([today, message]);
workbook.xlsx.writeFile(pathExcel)
.then(() => {
console.log("saved");
})
.catch((err) => {
console.log("err", err);
});
}
}
/**
* Saludos a primera respuesta
* @param {*} req
* @param {*} res
*/
const greetCustomer = (from) => new Promise((resolve, reject) => {
from = from.replace('@c.us', '');
const pathExcel = `./chats/${from}@c.us.xlsx`;
if (!fs.existsSync(pathExcel)) {
const firstMessage = [
`🤖 *Hola soy un bot, me llamo Dominique Larrey, intentaré responder a sus consultas.*
Como recibimos muchísimas preguntas me contrataron a mi para responderlas, como soy un robot no me canso, aunque podrían pagarme algo no? 😒
`
].join(' ')
sendMessageSync(from, firstMessage, 100)
sendMessageSync(from, presentacion, 1000)
sendMessageSync(from, info1, 2000)
sendMessageSync(from, info2, 3000)
sendMessageSync(from, info3, 4000)
sendMessageSync(from, info4, 5000)
sendMessageSync(from, `*Modelos de certificados*
https://photos.app.goo.gl/Grm54bW161weeXB26`, 6000)
sendMediaSync(from, './todosCertificados.png', 7000)
sendMediaSync(from, './Mundo hd.png', 8000)
ultimoMensaje(from, 9000)
}
resolveSync(resolve, 10000)
})
/**
* Controladores
*/
/* *☼* Si desea recibir toda la info sobre los cursos envie como mensaje la palabra *info*
*☼* Si quiere hablar un tema en especifico con el profesor Ezequiel envie como mensaje la palabra *instructor* */
const sendMessagePost = (req, res) => {
const { message, number } = req.body
console.log(message, number);
//sendMessage(number, message) ACA DESCOMENTAR
res.send({ status: 'Enviado!' })
}
/**
* Rutas
*/
app.post('/send', sendMessagePost);
/**
* Revisamos si existe archivo con credenciales!
*/
(fs.existsSync(SESSION_FILE_PATH)) ? withSession() : withOutSession();
app.listen(9000, () => {
console.log('Server ready!');
})
function sendMessageSync(from, message, timer) {
setTimeout(() => sendMessage(from, message), timer)
}
function sendMediaSync(from, media, timer) {
setTimeout(() => sendMedia(from, media), timer)
}
function resolveSync(resolve, timer) {
setTimeout(() => resolve(true), timer)
}
function ultimoMensaje(from, timer) {
sendMessageSync(from, `*🤖 Si le quedó una duda envieme un mensaje con algunos de los siguientes números para tener mas informacion*
*IMPORTANTE LEER*: escriba el numero sin letras o números adicionales, luego envie el mensaje y le llegara la info que precisa.
• *Cómo inscribirse de manera gratuita*: envíe 1
• *Cómo inscribirse de forma paga (con certificado):* envie 2
• *cómo son los cursos, duración, pasos a seguir etc.:* envie 3
• *Horarios del encuentro virtual de cada curso:* envie 4
• *De donde somos:* envie 5
• *Si las clases son virtuales:* envie 6
• *Cuanto tarda en llegar el certificado:* envie 7
• *Modelos de certificados:* envie 8
• Escriba la palabra *instructor* si desea hablar un tema en especifico con el instructor
*🤖 IMPORTANTE* si contesta algo diferente a lo de esta lista no podre responderle de manera adecuada. Recuerde que si desea hablar con el instructor debe enviar la palabra *instructor* como mensaje
`, timer)
}
function timeNow () {const date = new Date();
const minutes = date.getMinutes();
return date.getHours() + ':' + (minutes < 10 ? '0' + minutes : minutes);
}