From b3c13d5f983a8ca4168b9a9e7adef5e431c6bf30 Mon Sep 17 00:00:00 2001 From: HKong31 <113340082+HKong31@users.noreply.github.com> Date: Wed, 7 Dec 2022 07:52:13 -0400 Subject: [PATCH 1/8] DialogFlow botones por payload --- adapter/diaglogflow.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/adapter/diaglogflow.js b/adapter/diaglogflow.js index 1d0d9a8..9a4586c 100644 --- a/adapter/diaglogflow.js +++ b/adapter/diaglogflow.js @@ -1,5 +1,6 @@ const dialogflow = require('@google-cloud/dialogflow'); const fs = require('fs') +const {struct} = require('pb-util'); /** * Debes de tener tu archivo con el nombre "chatbot-account.json" en la raíz del proyecto @@ -32,6 +33,7 @@ const checkFileCredentials = () => { // Detect intent method const detectIntent = async (queryText, waPhoneNumber) => { let media = null; + let actions = null; const sessionId = KEEP_DIALOG_FLOW ? 1 : waPhoneNumber; const sessionPath = sessionClient.projectAgentSessionPath(PROJECID, sessionId); const languageCode = process.env.LANGUAGE @@ -54,6 +56,7 @@ const detectIntent = async (queryText, waPhoneNumber) => { // console.log(singleResponse) if (parsePayload && parsePayload.payload) { const { fields } = parsePayload.payload + actions = struct.decode(fields.actions.structValue) || null; media = fields.media.stringValue || null } const customPayload = parsePayload ? parsePayload['payload'] : null @@ -61,6 +64,7 @@ const detectIntent = async (queryText, waPhoneNumber) => { const parseData = { replyMessage: queryResult.fulfillmentText, media, + actions, trigger: null } return parseData @@ -74,4 +78,4 @@ const getDataIa = (message = '', sessionId = '', cb = () => { }) => { checkFileCredentials(); -module.exports = { getDataIa } \ No newline at end of file +module.exports = { getDataIa } From f88607c2c2945553ce46a6a3ec688219d597ffd6 Mon Sep 17 00:00:00 2001 From: HKong31 <113340082+HKong31@users.noreply.github.com> Date: Wed, 7 Dec 2022 08:02:00 -0400 Subject: [PATCH 2/8] DialogFlow botones por payload Evita crash si el mensaje excede los 256 caracteres + botones por el payload de DialogFlow --- app.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/app.js b/app.js index 36580c1..77d773a 100644 --- a/app.js +++ b/app.js @@ -57,8 +57,12 @@ const listenMessage = () => client.on('message', async msg => { if (process.env.DATABASE === 'dialogflow') { if (!message.length) return; - const response = await bothResponse(message, number); + const response = await bothResponse(message.substring(256,-1), number); await sendMessage(client, from, response.replyMessage); + if(response.actions){ + await sendMessageButton(client, from, null, response.actions); + return + } if (response.media) { sendMedia(client, from, response.media); } @@ -168,4 +172,4 @@ if (process.env.DATABASE === 'mysql') { server.listen(port, () => { console.log(`El server esta listo por el puerto ${port}`); }) -checkEnvFile(); \ No newline at end of file +checkEnvFile(); From 2d6c1879cedcc47a936e21b44c255756fff32849 Mon Sep 17 00:00:00 2001 From: HKong31 <113340082+HKong31@users.noreply.github.com> Date: Wed, 7 Dec 2022 08:18:32 -0400 Subject: [PATCH 3/8] DialogFlow botones por payload --- package-lock.json | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/package-lock.json b/package-lock.json index 589ad0f..af9632e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18,6 +18,7 @@ "mime-db": "^1.52.0", "moment": "^2.29.4", "mysql": "^2.18.1", + "pb-util": "^1.0.3", "qr-image": "^3.2.0", "qrcode-terminal": "^0.12.0", "socket.io": "^4.5.1", @@ -3415,6 +3416,11 @@ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" }, + "node_modules/pb-util": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/pb-util/-/pb-util-1.0.3.tgz", + "integrity": "sha512-8+weUH2YEYnPf5sTpZ3q7Drq41tSEL8vDSU96/CzSvu2qrbspbjbbuKLjHocAQpmyMbICTcvovVl3cETwxwIkQ==" + }, "node_modules/peek-readable": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/peek-readable/-/peek-readable-5.0.0.tgz", @@ -7965,6 +7971,11 @@ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" }, + "pb-util": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/pb-util/-/pb-util-1.0.3.tgz", + "integrity": "sha512-8+weUH2YEYnPf5sTpZ3q7Drq41tSEL8vDSU96/CzSvu2qrbspbjbbuKLjHocAQpmyMbICTcvovVl3cETwxwIkQ==" + }, "peek-readable": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/peek-readable/-/peek-readable-5.0.0.tgz", From b24c005e3e2d406ee43508ed4a9ae95810ba1b00 Mon Sep 17 00:00:00 2001 From: HKong31 <113340082+HKong31@users.noreply.github.com> Date: Wed, 7 Dec 2022 08:20:30 -0400 Subject: [PATCH 4/8] DialogFlow botones por payload --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index 20a8d94..fcb275f 100644 --- a/package.json +++ b/package.json @@ -39,6 +39,7 @@ "mime-db": "^1.52.0", "moment": "^2.29.4", "mysql": "^2.18.1", + "pb-util": "^1.0.3", "qr-image": "^3.2.0", "qrcode-terminal": "^0.12.0", "socket.io": "^4.5.1", From babff11c70df7b05e104ca0e08d13f8938fa5064 Mon Sep 17 00:00:00 2001 From: HKong31 <113340082+HKong31@users.noreply.github.com> Date: Wed, 7 Dec 2022 08:33:14 -0400 Subject: [PATCH 5/8] Fix crash when voice message recieved Fix crash si recibe nota de voz --- controllers/save.js | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/controllers/save.js b/controllers/save.js index 92555e0..3adfda0 100644 --- a/controllers/save.js +++ b/controllers/save.js @@ -8,11 +8,17 @@ const fs = require('fs') const saveMedia = (media) => { - const extensionProcess = mimeDb[media.mimetype] - const ext = extensionProcess.extensions[0] + const extensionProcess = mimeDb[media.mimetype]; + let ext; + if (!extensionProcess) { + const fileType = media.mimetype.split('/'); + ext = fileType[1].split(';')[0]; + } else { + ext = extensionProcess.extensions[0]; + } fs.writeFile(`./media/${Date.now()}.${ext}`, media.data, { encoding: 'base64' }, function (err) { console.log('** Archivo Media Guardado **'); }); } -module.exports = {saveMedia} \ No newline at end of file +module.exports = {saveMedia} From e8aed880d8c9b89e67df52c99a88309be5f68a13 Mon Sep 17 00:00:00 2001 From: HKong31 <113340082+HKong31@users.noreply.github.com> Date: Wed, 7 Dec 2022 12:19:06 -0400 Subject: [PATCH 6/8] =?UTF-8?q?Retraso=20en=20el=20env=C3=ADo=20de=20boton?= =?UTF-8?q?es?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Modificado para que los botones sean enviados después del mensaje --- controllers/send.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/controllers/send.js b/controllers/send.js index d081381..5cda9ac 100644 --- a/controllers/send.js +++ b/controllers/send.js @@ -69,12 +69,14 @@ const sendMessage = async (client, number = null, text = null, trigger = null) = * @param {*} number */ 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(message,[...buttons], title, footer); client.sendMessage(number, button); - + await readChat(number, message, actionButtons) console.log(`⚡⚡⚡ Enviando mensajes....`); + }, DELAY_TIME) } From 33490dc737e80b52ea163bd19c61555e9a9ea438 Mon Sep 17 00:00:00 2001 From: jzvi12 Date: Thu, 8 Dec 2022 16:57:18 -0500 Subject: [PATCH 7/8] fixed typo in controllers/send.js --- controllers/send.js | 4 ++-- package-lock.json | 13 ++++++------- package.json | 2 +- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/controllers/send.js b/controllers/send.js index 5cda9ac..8ec66a4 100644 --- a/controllers/send.js +++ b/controllers/send.js @@ -16,7 +16,7 @@ const { saveMessage } = require('../adapter') */ const sendMedia = (client, number = null, fileName = null) => { - if(!client) return cosnole.error("El objeto cliente no está definido."); + if(!client) return console.error("El objeto cliente no está definido."); try { number = cleanNumber(number || 0) const file = `${DIR_MEDIA}/${fileName}`; @@ -36,7 +36,7 @@ const sendMedia = (client, number = null, fileName = null) => { */ const sendMediaVoiceNote = (client, number = null, fileName = null) => { - if(!client) return cosnole.error("El objeto cliente no está definido."); + if(!client) return console.error("El objeto cliente no está definido."); try { number = cleanNumber(number || 0) const file = `${DIR_MEDIA}/${fileName}`; diff --git a/package-lock.json b/package-lock.json index af9632e..cf333c3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -23,7 +23,7 @@ "qrcode-terminal": "^0.12.0", "socket.io": "^4.5.1", "stormdb": "^0.6.0", - "whatsapp-web.js": "^1.18.4", + "whatsapp-web.js": "github:pedroslopez/whatsapp-web.js#fix-buttons-list", "xlsx": "^0.18.5" }, "devDependencies": { @@ -5028,9 +5028,9 @@ "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" }, "node_modules/whatsapp-web.js": { - "version": "1.18.4", - "resolved": "https://registry.npmjs.org/whatsapp-web.js/-/whatsapp-web.js-1.18.4.tgz", - "integrity": "sha512-Dqu6Q37tDDAcVJ44aMdRE76sI/9rBCUG+NTz1Kxh2w4obX2WtpoRetilxqgx1r4+pFUl58Lf21wGOEwPZ1pT/A==", + "version": "1.18.3-alpha.0", + "resolved": "git+ssh://git@github.com/pedroslopez/whatsapp-web.js.git#c8fe80635afc6fba9913577a3097e8bf1f557a0b", + "license": "Apache-2.0", "dependencies": { "@pedroslopez/moduleraid": "^5.0.2", "fluent-ffmpeg": "^2.1.2", @@ -9178,9 +9178,8 @@ "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" }, "whatsapp-web.js": { - "version": "1.18.4", - "resolved": "https://registry.npmjs.org/whatsapp-web.js/-/whatsapp-web.js-1.18.4.tgz", - "integrity": "sha512-Dqu6Q37tDDAcVJ44aMdRE76sI/9rBCUG+NTz1Kxh2w4obX2WtpoRetilxqgx1r4+pFUl58Lf21wGOEwPZ1pT/A==", + "version": "git+ssh://git@github.com/pedroslopez/whatsapp-web.js.git#c8fe80635afc6fba9913577a3097e8bf1f557a0b", + "from": "whatsapp-web.js@github:pedroslopez/whatsapp-web.js#fix-buttons-list", "requires": { "@pedroslopez/moduleraid": "^5.0.2", "archiver": "^5.3.1", diff --git a/package.json b/package.json index fcb275f..147e1c8 100644 --- a/package.json +++ b/package.json @@ -44,7 +44,7 @@ "qrcode-terminal": "^0.12.0", "socket.io": "^4.5.1", "stormdb": "^0.6.0", - "whatsapp-web.js": "^1.18.4", + "whatsapp-web.js": "github:pedroslopez/whatsapp-web.js#fix-buttons-list", "xlsx": "^0.18.5" }, "devDependencies": { From 748262302c143f39e0652e38fad87060ea6dba11 Mon Sep 17 00:00:00 2001 From: jzvi12 Date: Thu, 22 Dec 2022 20:43:16 -0500 Subject: [PATCH 8/8] added dialogflow filter for media --- .env.example | 4 +- .gitignore | 4 +- adapter/gdrive.js | 103 +++++++++++++++++++++++++++++++++++++++++++ app.js | 52 ++++++++++++++++++---- controllers/flows.js | 22 ++++++--- controllers/save.js | 24 +++++++--- flow/dialogflow.json | 8 ++++ package-lock.json | 89 ++++++++++++++++++++++++++++++++++--- package.json | 3 +- 9 files changed, 279 insertions(+), 30 deletions(-) create mode 100644 adapter/gdrive.js create mode 100644 flow/dialogflow.json diff --git a/.env.example b/.env.example index beb1bb7..69d8a2e 100644 --- a/.env.example +++ b/.env.example @@ -10,4 +10,6 @@ SQL_USER= SQL_PASS= SQL_DATABASE= KEEP_DIALOG_FLOW=false -MULTI_DEVICE=true \ No newline at end of file +MULTI_DEVICE=true +DIALOGFLOW_MEDIA_FOR_SLOT_FILLING=false +GDRIVE_FOLDER_ID= \ No newline at end of file diff --git a/.gitignore b/.gitignore index b38ba23..4a4afc4 100644 --- a/.gitignore +++ b/.gitignore @@ -9,4 +9,6 @@ mediaSend/* !mediaSend/.gitkeep !mediaSend/nota-de-voz.mp3 .env -.wwebjs_auth \ No newline at end of file +.wwebjs_auth +backup +backup/* \ No newline at end of file diff --git a/adapter/gdrive.js b/adapter/gdrive.js new file mode 100644 index 0000000..2e3ad30 --- /dev/null +++ b/adapter/gdrive.js @@ -0,0 +1,103 @@ +require('dotenv').config({ path: `${__dirname}/../.env` }); +const { google } = require('googleapis'); +const path = require('path'); +const fs = require('fs'); +//const clientEmail = require(`${__dirname}/../chatbot-account.json`); + +/** + * La funcion 'generatePublicUrl' genera un error muy menor al enviar el 'requestBody' + * siempre y cuando necesites que el acceso sea restringido y solo ciertos usuarios puedan acceder. + * Esto se logra con la combinacion requerida: 'reader', 'user' y 'emailAddress': + * requestBody: { + * role: 'reader', + * type: 'user', + * emailAddress: usuario@gmail.com, + * }, + * Segun la documentacion https://developers.google.com/drive/api/v3/reference/permissions/create#request-body, + * los datos se envian correctamente, pero la respuesta del API regresa este error: + * Bad Request. User message: "You cannot share this item because it has been flagged as inappropriate." + * Al parecer, es un error conocido en stackoverflow.com entre varios usuarios del API. + */ + +if (process.env.DATABASE === 'dialogflow') { + + /** + * Debes de tener tu archivo con el nombre "chatbot-account.json" en la raíz del proyecto + */ + + const KEYFILEPATH = path.join(`${__dirname}/../chatbot-account.json`); + const SCOPES = ['https://www.googleapis.com/auth/drive']; + + const auth = new google.auth.GoogleAuth({ + keyFile: KEYFILEPATH, + scopes: SCOPES, + }); + + const drive = google.drive({ + version: 'v3', + auth, + }); + + const uploadSingleFile = async (fileName, filePath) => { + const folderId = process.env.GDRIVE_FOLDER_ID; + const { data: { id, name } = {} } = await drive.files.create({ + resource: { + name: fileName, + parents: [folderId], + }, + media: { + mimeType: 'image/jpg', + body: fs.createReadStream(filePath), + }, + fields: 'id,name', + }); + generatePublicUrl(id).then(() => { + console.log(`Se generó enlace https://drive.google.com/open?id=${id} para el archivo ${name}`); + }); + return `https://drive.google.com/open?id=${id}` + }; + + const scanFolderForFiles = async (folderPath) => { + const folder = await fs.promises.opendir(folderPath); + for await (const dirent of folder) { + if (dirent.isFile() && dirent.name.endsWith('.jpeg')) { + await uploadSingleFile(dirent.name, path.join(folderPath, dirent.name)); + await fs.promises.rm(filePath); + } + } + }; + + async function generatePublicUrl(id) { + try { + const fileId = id; + await drive.permissions.create({ + fileId: fileId, + supportsAllDrives: true, + requestBody: { + role: 'reader', + type: 'domain', // 'anyone' da acceso al publico vía enlace https://drive.google.com... + domain: 'gserviceaccount.com', // Si tu cuenta esta bajo un dominio (usuario@empresa.com) y no bajo gmail.com + allowFileDiscovery: false, + }, + }); + + /* + webViewLink: Ver el archivo en el navegador + webContentLink: Enlace de descarga directa + */ + const result = await drive.files.get({ + fileId: fileId, + fields: 'webViewLink, webContentLink', + }); + console.log(result.data); + } catch (error) { + //console.log(error.message); // Imprime 'Internal Error', pero aún así genera el enlace + console.error = () => { }; // No muestra el error anterior + } + } + + module.exports = { uploadSingleFile, scanFolderForFiles } + +} else { + console.log(`Actualmente, la base de datos es:\n\t'DATABASE=${process.env.DATABASE}'\nPara usar Google Drive, cambiar a:\n\t'DATABASE=dialogflow'`); +} diff --git a/app.js b/app.js index 77d773a..4092ee1 100644 --- a/app.js +++ b/app.js @@ -11,8 +11,8 @@ const mysqlConnection = require('./config/mysql') const { middlewareClient } = require('./middleware/client') const { generateImage, cleanNumber, checkEnvFile, createClient, isValidNumber } = require('./controllers/handle') const { connectionReady, connectionLost } = require('./controllers/connection') -const { saveMedia } = require('./controllers/save') -const { getMessages, responseMessages, bothResponse } = require('./controllers/flows') +const { saveMedia, saveMediaToGoogleDrive } = require('./controllers/save') +const { getMessages, responseMessages, bothResponse, waitFor } = require('./controllers/flows') const { sendMedia, sendMessage, lastTrigger, sendMessageButton, readChat } = require('./controllers/send') const app = express(); app.use(cors()) @@ -22,6 +22,7 @@ const server = require('http').Server(app) const port = process.env.PORT || 3000 var client; +var dialogflowFilter = false; app.use('/', require('./routes/web')) /** @@ -46,7 +47,7 @@ const listenMessage = () => client.on('message', async msg => { /** * Guardamos el archivo multimedia que envia */ - if (process.env.SAVE_MEDIA && hasMedia) { + if (process.env.SAVE_MEDIA === 'true' && hasMedia) { const media = await msg.downloadMedia(); saveMedia(media); } @@ -56,12 +57,27 @@ const listenMessage = () => client.on('message', async msg => { */ if (process.env.DATABASE === 'dialogflow') { + + if (process.env.DIALOGFLOW_MEDIA_FOR_SLOT_FILLING === 'true' && dialogflowFilter) { + waitFor(_ => hasMedia, 30000) + .then(async _ => { + if (hasMedia) { + const media = await msg.downloadMedia(); + message = await saveMediaToGoogleDrive(media); + const response = await bothResponse(message.substring(256, -1), number); + await sendMessage(client, from, response.replyMessage); + } + return + }); + dialogflowFilter = false; + } + if (!message.length) return; - const response = await bothResponse(message.substring(256,-1), number); + const response = await bothResponse(message.substring(256, -1), number); await sendMessage(client, from, response.replyMessage); - if(response.actions){ - await sendMessageButton(client, from, null, response.actions); - return + if (response.actions) { + await sendMessageButton(client, from, null, response.actions); + return } if (response.media) { sendMedia(client, from, response.media); @@ -128,7 +144,26 @@ const listenMessage = () => client.on('message', async msg => { } }); +/** + * Este evento es necesario para el filtro de Dialogflow + */ +const listenMessageFromBot = () => client.on('message_create', async botMsg => { + const { body } = botMsg; + const dialogflowFilterConfig = fs.readFileSync('./flow/dialogflow.json', 'utf8'); + const keywords = JSON.parse(dialogflowFilterConfig); + + for (i = 0; i < keywords.length; i++) { + key = keywords[i]; + for (var j = 0; j < key.phrases.length; j++) { + let filters = key.phrases[j]; + if (body.includes(filters)) { + dialogflowFilter = true; + //console.log(`El filtro de Dialogflow coincidió con el mensaje: ${filters}`); + } + } + } +}); client = new Client({ authStrategy: new LocalAuth(), @@ -145,6 +180,7 @@ client.on('qr', qr => generateImage(qr, () => { client.on('ready', (a) => { connectionReady() listenMessage() + listenMessageFromBot() // socketEvents.sendStatus(client) }); @@ -159,8 +195,6 @@ client.on('authenticated', () => { client.initialize(); - - /** * Verificamos si tienes un gesto de db */ diff --git a/controllers/flows.js b/controllers/flows.js index b0fc9d3..ed323c6 100644 --- a/controllers/flows.js +++ b/controllers/flows.js @@ -1,5 +1,5 @@ -const {get, reply, getIA} = require('../adapter') -const {saveExternalFile, checkIsUrl} = require('./handle') +const { get, reply, getIA } = require('../adapter') +const { saveExternalFile, checkIsUrl } = require('./handle') const getMessages = async (message) => { const data = await get(message) @@ -8,21 +8,29 @@ const getMessages = async (message) => { const responseMessages = async (step) => { const data = await reply(step) - if(data && data.media){ + if (data && data.media) { const file = checkIsUrl(data.media) ? await saveExternalFile(data.media) : data.media; - return {...data,...{media:file}} + return { ...data, ...{ media: file } } } return data } const bothResponse = async (message, sessionId) => { const data = await getIA(message, sessionId) - if(data && data.media){ + if (data && data.media) { const file = await saveExternalFile(data.media) - return {...data,...{media:file}} + return { ...data, ...{ media: file } } } return data } +const waitFor = (conditionFunction, WAIT_TIME) => { + const poll = resolve => { + if (conditionFunction()) + resolve(); + else setTimeout(_ => poll(resolve), WAIT_TIME); + } + return new Promise(poll); +} -module.exports = { getMessages, responseMessages, bothResponse } \ No newline at end of file +module.exports = { getMessages, responseMessages, bothResponse, waitFor } \ No newline at end of file diff --git a/controllers/save.js b/controllers/save.js index 3adfda0..375abaa 100644 --- a/controllers/save.js +++ b/controllers/save.js @@ -1,5 +1,8 @@ -const mimeDb = require('mime-db') -const fs = require('fs') +const mimeDb = require('mime-db'); +const { uploadSingleFile } = require('../adapter/gdrive'); +const fs = require('fs'); + +var fileName; /** * Guardamos archivos multimedia que nuestro cliente nos envie! @@ -16,9 +19,20 @@ const saveMedia = (media) => { } else { ext = extensionProcess.extensions[0]; } - fs.writeFile(`./media/${Date.now()}.${ext}`, media.data, { encoding: 'base64' }, function (err) { - console.log('** Archivo Media Guardado **'); + fileName = `${Date.now()}.${ext}`; + fs.writeFile(`./media/${fileName}`, media.data, { encoding: 'base64' }, function (err) { + console.log(`** Archivo Media ${fileName} Guardado **`); }); + return fileName } -module.exports = {saveMedia} +const saveMediaToGoogleDrive = async (media) => { + + fileName = saveMedia(media); + filePath = `${__dirname}/../media/${fileName}` + + const googleDriveUrl = await uploadSingleFile(fileName, filePath); + return googleDriveUrl +} + +module.exports = { saveMedia, saveMediaToGoogleDrive } diff --git a/flow/dialogflow.json b/flow/dialogflow.json new file mode 100644 index 0000000..41111c8 --- /dev/null +++ b/flow/dialogflow.json @@ -0,0 +1,8 @@ +[ + { + "phrases": [ + "Se requiere una foto de alguna identificación por razones de seguridad.", + "Por favor envíenos una foto de su ID para completar su formulario." + ] + } +] \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index cf333c3..508f65c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,6 +15,7 @@ "exceljs": "^4.3.0", "express": "^4.18.1", "file-type": "^17.1.6", + "googleapis": "^109.0.1", "mime-db": "^1.52.0", "moment": "^2.29.4", "mysql": "^2.18.1", @@ -23,7 +24,7 @@ "qrcode-terminal": "^0.12.0", "socket.io": "^4.5.1", "stormdb": "^0.6.0", - "whatsapp-web.js": "github:pedroslopez/whatsapp-web.js#fix-buttons-list", + "whatsapp-web.js": "^1.18.4", "xlsx": "^0.18.5" }, "devDependencies": { @@ -2282,6 +2283,42 @@ "node": ">=12.0.0" } }, + "node_modules/googleapis": { + "version": "109.0.1", + "resolved": "https://registry.npmjs.org/googleapis/-/googleapis-109.0.1.tgz", + "integrity": "sha512-x286OtNu0ngzxfGz2XgRs4aMhrwutRCkCE12dh2M1jIZOpOndB7ELFXEhmtxaJ7z3257flKIbiiCJZeBO+ze/Q==", + "dependencies": { + "google-auth-library": "^8.0.2", + "googleapis-common": "^6.0.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/googleapis-common": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/googleapis-common/-/googleapis-common-6.0.4.tgz", + "integrity": "sha512-m4ErxGE8unR1z0VajT6AYk3s6a9gIMM6EkDZfkPnES8joeOlEtFEJeF8IyZkb0tjPXkktUfYrE4b3Li1DNyOwA==", + "dependencies": { + "extend": "^3.0.2", + "gaxios": "^5.0.1", + "google-auth-library": "^8.0.2", + "qs": "^6.7.0", + "url-template": "^2.0.8", + "uuid": "^9.0.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/googleapis-common/node_modules/uuid": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz", + "integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==", + "bin": { + "uuid": "dist/bin/uuid" + } + }, "node_modules/graceful-fs": { "version": "4.2.10", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", @@ -4953,6 +4990,11 @@ "safe-buffer": "~5.1.0" } }, + "node_modules/url-template": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/url-template/-/url-template-2.0.8.tgz", + "integrity": "sha512-XdVKMF4SJ0nP/O7XIPB0JwAEuT9lDIYnNsK8yGVe43y0AWoKeJNdv3ZNWh7ksJ6KqQFjOO6ox/VEitLnaVNufw==" + }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -5028,9 +5070,9 @@ "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" }, "node_modules/whatsapp-web.js": { - "version": "1.18.3-alpha.0", - "resolved": "git+ssh://git@github.com/pedroslopez/whatsapp-web.js.git#c8fe80635afc6fba9913577a3097e8bf1f557a0b", - "license": "Apache-2.0", + "version": "1.18.4", + "resolved": "https://registry.npmjs.org/whatsapp-web.js/-/whatsapp-web.js-1.18.4.tgz", + "integrity": "sha512-Dqu6Q37tDDAcVJ44aMdRE76sI/9rBCUG+NTz1Kxh2w4obX2WtpoRetilxqgx1r4+pFUl58Lf21wGOEwPZ1pT/A==", "dependencies": { "@pedroslopez/moduleraid": "^5.0.2", "fluent-ffmpeg": "^2.1.2", @@ -7061,6 +7103,35 @@ "node-forge": "^1.3.1" } }, + "googleapis": { + "version": "109.0.1", + "resolved": "https://registry.npmjs.org/googleapis/-/googleapis-109.0.1.tgz", + "integrity": "sha512-x286OtNu0ngzxfGz2XgRs4aMhrwutRCkCE12dh2M1jIZOpOndB7ELFXEhmtxaJ7z3257flKIbiiCJZeBO+ze/Q==", + "requires": { + "google-auth-library": "^8.0.2", + "googleapis-common": "^6.0.0" + } + }, + "googleapis-common": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/googleapis-common/-/googleapis-common-6.0.4.tgz", + "integrity": "sha512-m4ErxGE8unR1z0VajT6AYk3s6a9gIMM6EkDZfkPnES8joeOlEtFEJeF8IyZkb0tjPXkktUfYrE4b3Li1DNyOwA==", + "requires": { + "extend": "^3.0.2", + "gaxios": "^5.0.1", + "google-auth-library": "^8.0.2", + "qs": "^6.7.0", + "url-template": "^2.0.8", + "uuid": "^9.0.0" + }, + "dependencies": { + "uuid": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz", + "integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==" + } + } + }, "graceful-fs": { "version": "4.2.10", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", @@ -9119,6 +9190,11 @@ } } }, + "url-template": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/url-template/-/url-template-2.0.8.tgz", + "integrity": "sha512-XdVKMF4SJ0nP/O7XIPB0JwAEuT9lDIYnNsK8yGVe43y0AWoKeJNdv3ZNWh7ksJ6KqQFjOO6ox/VEitLnaVNufw==" + }, "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -9178,8 +9254,9 @@ "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" }, "whatsapp-web.js": { - "version": "git+ssh://git@github.com/pedroslopez/whatsapp-web.js.git#c8fe80635afc6fba9913577a3097e8bf1f557a0b", - "from": "whatsapp-web.js@github:pedroslopez/whatsapp-web.js#fix-buttons-list", + "version": "1.18.4", + "resolved": "https://registry.npmjs.org/whatsapp-web.js/-/whatsapp-web.js-1.18.4.tgz", + "integrity": "sha512-Dqu6Q37tDDAcVJ44aMdRE76sI/9rBCUG+NTz1Kxh2w4obX2WtpoRetilxqgx1r4+pFUl58Lf21wGOEwPZ1pT/A==", "requires": { "@pedroslopez/moduleraid": "^5.0.2", "archiver": "^5.3.1", diff --git a/package.json b/package.json index 147e1c8..43cf588 100644 --- a/package.json +++ b/package.json @@ -36,6 +36,7 @@ "exceljs": "^4.3.0", "express": "^4.18.1", "file-type": "^17.1.6", + "googleapis": "^109.0.1", "mime-db": "^1.52.0", "moment": "^2.29.4", "mysql": "^2.18.1", @@ -44,7 +45,7 @@ "qrcode-terminal": "^0.12.0", "socket.io": "^4.5.1", "stormdb": "^0.6.0", - "whatsapp-web.js": "github:pedroslopez/whatsapp-web.js#fix-buttons-list", + "whatsapp-web.js": "^1.18.4", "xlsx": "^0.18.5" }, "devDependencies": {