DEV Community

Mukesh Rajbanshi
Mukesh Rajbanshi

Posted on

Uploading Files to Dropbox Using NodeJS(NestJS)

In this tutorial, we will explore how to upload files to Dropbox using NestJS. We will implement a feature where a file is first downloaded from a URL and then uploaded to Dropbox using OAuth authentication.

Prerequisites

Before we begin, make sure you have the following:

  • Node.js installed
  • A NestJS application set up
  • A Dropbox account
  • Dropbox API credentials (Refresh Token, Client ID, Client Secret)

Step 1: Setting Up Dropbox API

  1. Go to the Dropbox Developer Console.
  2. Create a new app and choose the "Scoped access" option.
  3. Select the appropriate permissions for your application.
  4. Generate a refresh token, client ID, and client secret. Store them securely.

Step 2: Install Required Packages

Install the required dependencies for making API calls to Dropbox:

npm install @nestjs/common @nestjs/core @nestjs/platform-express axios dotenv qs
Enter fullscreen mode Exit fullscreen mode

Step 3: Configure Environment Variables

Create a .env file in the root of your project and add the following:

DROPBOX_REFRESH_TOKEN=your_dropbox_refresh_token
DROPBOX_CLIENT_ID=your_dropbox_client_id
DROPBOX_CLIENT_SECRET=your_dropbox_client_secret
Enter fullscreen mode Exit fullscreen mode

Step 4: Create a File Upload Service

Create a new service dropbox.service.ts to handle file downloads and uploads to Dropbox.

import { BadRequestException, Injectable, InternalServerErrorException } from '@nestjs/common';
import axios from 'axios';
// eslint-disable-next-line @typescript-eslint/no-var-requires
const qs = require('qs');

@Injectable()
export class DropboxService {
  constructor() {
    if (!process.env.DROPBOX_REFRESH_TOKEN || !process.env.DROPBOX_CLIENT_ID || !process.env.DROPBOX_CLIENT_SECRET) {
      throw new InternalServerErrorException('DROPBOX credentials not found in env!');
    }
  }

  async uploadFileToDropbox() {
    const fileUrl = `https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf`;
    const dropboxPdfPath = `/upload/${new Date().getTime()}.pdf`;

    try {
      // Step 1: Download file from URL
      const response = await axios.get(fileUrl, { responseType: 'arraybuffer' });
      const fileBuffer = response.data;

      // Step 2: Generate Access Token
      const accessToken = await this.generateAccessToken();

      // Step 3: Upload to Dropbox
      await axios.post('https://content.dropboxapi.com/2/files/upload', fileBuffer, {
        headers: {
          Authorization: `Bearer ${accessToken}`,
          'Dropbox-API-Arg': JSON.stringify({
            path: dropboxPdfPath,
            mode: 'add',
            autorename: false,
            mute: false,
            strict_conflict: false,
          }),
          'Content-Type': 'application/octet-stream',
        },
      });
    } catch (error) {
      throw new InternalServerErrorException('Error uploading file to Dropbox');
    }
  }

  async generateAccessToken(): Promise<string> {
    try {
      const data = qs.stringify({
        grant_type: 'refresh_token',
        refresh_token: process.env.DROPBOX_REFRESH_TOKEN,
        client_id: process.env.DROPBOX_CLIENT_ID,
        client_secret: process.env.DROPBOX_CLIENT_SECRET,
      });

      const response = await axios.post('https://api.dropbox.com/oauth2/token', data, {
        headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
      });

      return response.data.access_token;
    } catch (error) {
      throw new BadRequestException('Error generating access token');
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Step 5: Create a Controller to Handle File Upload Requests

Create a dropbox.controller.ts file to handle API requests.

import { Controller, Post } from '@nestjs/common';
import { DropboxService } from './dropbox.service';

@Controller('dropbox')
export class DropboxController {
  constructor(private readonly dropboxService: DropboxService) {}

  @Post('upload')
  async uploadFile() {
    return this.dropboxService.uploadFileToDropbox();
  }
}
Enter fullscreen mode Exit fullscreen mode

Step 6: Register the Service and Controller

Modify the dropbox.module.ts file to register the service and controller.

import { Module } from '@nestjs/common';
import { DropboxService } from './dropbox.service';
import { DropboxController } from './dropbox.controller';

@Module({
  controllers: [DropboxController],
  providers: [DropboxService],
})
export class DropboxModule {}
Enter fullscreen mode Exit fullscreen mode

Step 7: Integrate with the Main Module

Import the DropboxModule in app.module.ts:

import { Module } from '@nestjs/common';
import { DropboxModule } from './dropbox/dropbox.module';

@Module({
  imports: [DropboxModule],
})
export class AppModule {}
Enter fullscreen mode Exit fullscreen mode

Step 8: Test the API

Run your NestJS application:

npm run start:dev
Enter fullscreen mode Exit fullscreen mode

Use Postman or curl to send a POST request to http://localhost:3000/dropbox/upload.

Example using curl:

curl -X POST "http://localhost:3000/dropbox/upload"
Enter fullscreen mode Exit fullscreen mode

If successful, you should receive a response confirming the file upload.

Conclusion

In this guide, we explored how to download a file from a URL and upload it to Dropbox using NestJS with OAuth authentication. This implementation securely retrieves an access token using a refresh token before uploading the file. You can extend this further by adding file retrieval, deletion, or sharing functionalities. Happy coding!

Top comments (0)