import { Controller, Post, Delete, Get, Res, UploadedFile, UseInterceptors, Query, BadRequestException, HttpStatus, HttpCode, } from '@nestjs/common'; import { FileInterceptor } from '@nestjs/platform-express'; import { ApiTags, ApiOperation, ApiConsumes, ApiBody, ApiQuery, ApiExcludeEndpoint, } from '@nestjs/swagger'; import type { Response } from 'express'; import { GoogleDriveService } from './google-drive.service'; import { FileTypeEnum } from './enums/file-type.enum'; import { LogToDiscord } from 'src/shared/decorators/log-to-discord.decorator'; @ApiTags('Upload: Google Drive Storage') @Controller('google-drive') @LogToDiscord() export class GoogleDriveController { constructor(private readonly googleDriveService: GoogleDriveService) {} @Get('oauth2/authorize') @ApiExcludeEndpoint() async getAuthUrl() { return this.googleDriveService.getAuthorizationUrl(); } @Get('oauth2callback') @ApiExcludeEndpoint() async oauth2Callback(@Query('code') code: string, @Res() res: Response) { const result = await this.googleDriveService.handleOAuthCallback(code); return res.send(` Authorization ${result.success ? 'Success' : 'Failed'}

${result.success ? '✅ Authorization Successful!' : '❌ Authorization Failed'}

${result.success ? 'Your Google account has been authorized.' : result.error}

${ result.success ? `

🔑 Your Refresh Token:

${result.refreshToken}

⚠️ IMPORTANT: Save this refresh token!

Add to your .env file:

GOOGLE_OAUTH2_REFRESH_TOKEN="${result.refreshToken}"

🚀 Next Steps:

  1. Copy the refresh token above
  2. Add it to your .env file
  3. Restart your application
  4. Try uploading a file!
` : `

Try again

` } `); } @Post('upload') @ApiOperation({ summary: 'Upload file to Google Drive' }) @ApiConsumes('multipart/form-data') @ApiQuery({ name: 'fileType', enum: FileTypeEnum, required: false }) @ApiQuery({ name: 'customFilename', required: false, description: 'Custom filename (optional)', }) @ApiBody({ schema: { type: 'object', properties: { file: { type: 'string', format: 'binary', }, }, }, }) @UseInterceptors(FileInterceptor('file')) async uploadFile( @UploadedFile() file: any, @Query('fileType') fileType?: FileTypeEnum, @Query('customFilename') customFilename?: string, ) { if (!file) { throw new BadRequestException('No file uploaded'); } return this.googleDriveService.uploadFile({ fileBuffer: file.buffer, filename: file.originalname, fileType: fileType || FileTypeEnum.IMAGE, customFilename: customFilename, mimetype: file.mimetype, }); } @Delete('by-url') @HttpCode(HttpStatus.OK) @ApiOperation({ summary: 'Delete file by public URL' }) @ApiQuery({ name: 'url', required: true, description: 'Public URL of the file to delete (e.g., https://drive.google.com/uc?id=FILE_ID)', type: 'string', }) async deleteFileByUrl(@Query('url') url: string) { if (!url) { throw new BadRequestException('URL is required'); } return this.googleDriveService.handleFileDelete(url); } }