Files
botGuna/adapter/gdrive,.js
2022-12-27 02:30:32 -06:00

103 lines
3.5 KiB
JavaScript

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'`);
}