193 lines
4.7 KiB
TypeScript
193 lines
4.7 KiB
TypeScript
// src/drive/drive.service.ts
|
|
import {
|
|
BadRequestException,
|
|
Injectable,
|
|
InternalServerErrorException,
|
|
} from '@nestjs/common';
|
|
import { google } from 'googleapis';
|
|
import * as fs from 'fs';
|
|
|
|
@Injectable()
|
|
export class DriveService {
|
|
private SCOPES = ['https://www.googleapis.com/auth/drive'];
|
|
|
|
private loadCredentials() {
|
|
try {
|
|
const oAuth2Client = new google.auth.OAuth2(
|
|
process.env.CLIENT_ID,
|
|
process.env.CLIENT_SECRET,
|
|
);
|
|
|
|
oAuth2Client.setCredentials({
|
|
refresh_token: process.env.REFRESH_TOKEN,
|
|
});
|
|
|
|
return oAuth2Client;
|
|
} catch (err) {
|
|
throw new InternalServerErrorException(
|
|
'Error al cargar credenciales de Google Drive',
|
|
);
|
|
}
|
|
}
|
|
|
|
async list(pageToken = '') {
|
|
const authClient = this.loadCredentials();
|
|
const drive = google.drive({ version: 'v3', auth: authClient });
|
|
|
|
try {
|
|
const res = await drive.files.list({
|
|
corpora: 'user',
|
|
supportsAllDrives: true,
|
|
includeItemsFromAllDrives: true,
|
|
spaces: 'drive',
|
|
pageSize: 1000,
|
|
pageToken,
|
|
orderBy: 'name',
|
|
});
|
|
return res.data;
|
|
} catch (err) {
|
|
throw new InternalServerErrorException(
|
|
'Error al listar archivos: ' + err.message,
|
|
);
|
|
}
|
|
}
|
|
|
|
async deleteFile(fileId: string) {
|
|
if (fileId === process.env.CARPETA) {
|
|
throw new BadRequestException(
|
|
'No se puede eliminar este archivo/carpeta.',
|
|
);
|
|
}
|
|
console.log('Eliminando archivo de Drive, ID:', fileId);
|
|
const authClient = this.loadCredentials();
|
|
const drive = google.drive({ version: 'v3', auth: authClient });
|
|
|
|
try {
|
|
return await drive.files.delete({ fileId });
|
|
} catch (err) {
|
|
console.error('Error al eliminar archivo de Drive:', err.message);
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
async uploadFile(
|
|
filePath: string,
|
|
name: string,
|
|
mimeType: string,
|
|
parent: string,
|
|
) {
|
|
const authClient = this.loadCredentials();
|
|
const drive = google.drive({ version: 'v3', auth: authClient });
|
|
|
|
const requestBody = {
|
|
name,
|
|
parents: [parent],
|
|
};
|
|
|
|
const media = {
|
|
mimeType,
|
|
body: fs.createReadStream(filePath),
|
|
};
|
|
|
|
try {
|
|
const res = await drive.files.create({
|
|
requestBody,
|
|
media,
|
|
fields: 'id',
|
|
supportsAllDrives: true,
|
|
});
|
|
|
|
fs.unlinkSync(filePath);
|
|
console.log('Archivo subido a Drive, ID:', res.data.id);
|
|
return res.data.id!;
|
|
} catch (err) {
|
|
throw new InternalServerErrorException(
|
|
'Error al subir archivo: ' + err.message,
|
|
);
|
|
}
|
|
}
|
|
|
|
async mkDir(name: string): Promise<string> {
|
|
if (!name) {
|
|
throw new BadRequestException('Nombre de carpeta inválido');
|
|
}
|
|
|
|
if (!process.env.CARPETA) {
|
|
throw new InternalServerErrorException('CARPETA no configurada');
|
|
}
|
|
|
|
const authClient = this.loadCredentials();
|
|
const drive = google.drive({ version: 'v3', auth: authClient });
|
|
|
|
const requestBody = {
|
|
name,
|
|
mimeType: 'application/vnd.google-apps.folder',
|
|
parents: [process.env.CARPETA],
|
|
};
|
|
|
|
try {
|
|
const res = await drive.files.create({
|
|
requestBody,
|
|
fields: 'id',
|
|
supportsAllDrives: true,
|
|
});
|
|
|
|
if (!res.data.id) {
|
|
throw new BadRequestException('No se pudo crear la carpeta');
|
|
}
|
|
|
|
return res.data.id;
|
|
} catch (err) {
|
|
throw new InternalServerErrorException(
|
|
'Error al crear carpeta: ' + err.message,
|
|
);
|
|
}
|
|
}
|
|
|
|
async update(fileId: string, addParents: string, removeParents: string) {
|
|
const authClient = this.loadCredentials();
|
|
const drive = google.drive({ version: 'v3', auth: authClient });
|
|
|
|
try {
|
|
const res = await drive.files.update({
|
|
fileId,
|
|
addParents,
|
|
removeParents,
|
|
supportsAllDrives: true,
|
|
});
|
|
return res.data;
|
|
} catch (err) {
|
|
throw new InternalServerErrorException(
|
|
'Error al actualizar archivo: ' + err.message,
|
|
);
|
|
}
|
|
}
|
|
|
|
async folder(numeroCuenta: string): Promise<string> {
|
|
if (!process.env.CARPETA) {
|
|
throw new InternalServerErrorException('CARPETA no configurada');
|
|
}
|
|
|
|
const authClient = this.loadCredentials();
|
|
const drive = google.drive({ version: 'v3', auth: authClient });
|
|
|
|
const res = await drive.files.list({
|
|
q: `
|
|
mimeType='application/vnd.google-apps.folder'
|
|
and name='${numeroCuenta}'
|
|
and '${process.env.CARPETA}' in parents
|
|
and trashed=false
|
|
`,
|
|
fields: 'files(id, name)',
|
|
supportsAllDrives: true,
|
|
includeItemsFromAllDrives: true,
|
|
});
|
|
|
|
if (res.data.files?.length) {
|
|
return res.data.files[0].id!;
|
|
}
|
|
|
|
return this.mkDir(numeroCuenta);
|
|
}
|
|
}
|