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:
- Copy the refresh token above
- Add it to your
.env file
- Restart your application
- 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);
}
}