DEV Community

Kamal Hossain
Kamal Hossain

Posted on

Google Drive API in node.js

Let's go straight to the point. Here we are going to do the followings:

  • Create a node.js server by using express.js
  • Get authentication for Google Drive
  • Upload an image file to Google Drive from node.js server

Create a node.js server by using express.js

Run the followings in your terminal:

mkdir google-drive-api-v3 && cd google-drive-api-v3
Enter fullscreen mode Exit fullscreen mode
npm init -y && npm install express --save
Enter fullscreen mode Exit fullscreen mode

Now let's create a server.js file in your project folder. And fill the file with the followings:

const express = require('express');
const app = express();
const PORT = 5000;

app.get('/testRoute', (req, res) => res.end('Hello from Server!'));

app.listen(PORT, () => {
  console.log(`Node.js App running on port ${PORT}...`);
});
Enter fullscreen mode Exit fullscreen mode

Let's go through what we have done!

At first, we have imported express.js in our server. Then we created a brand new application by calling express().

Then we initialized our port variable to 5000.

And then we have created a test route called /testRoute to check if our server is working properly or not. Finally, we have started to listen to our server by calling app.listen().

Start the server from your terminal by:

node server.js
Enter fullscreen mode Exit fullscreen mode

Congratulations! we have started our server successfully. So now we can check this route via postman with a get request to localhost:5000/testRoute


Get authentication for Google Drive

At first, we need to enable our Drive API to get the requried credentials.json file. So let's jump into this page.

Click on Enable the Drive API. If you are not logged in, then logged in with your account.

If you are already logged in then it will open up a modal with the heading of Enable the Drive API Let the project name to be default or enter a suitable name. Click NEXT.

Now it will say Configure your OAuth client. I will leave it as Desktop app and create. Click on the DOWNLOAD CLIENT CONFIGURATION.

That's it you are all set for now.

Now save the credentials.json file in the root directory of your server folder.

In order to get the token for google drive, add the following lines:

const express = require('express');
const app = express();
const PORT = 5000;

const fs = require('fs');
const readline = require('readline');
const { google } = require('googleapis');
Enter fullscreen mode Exit fullscreen mode

Here we are importing fs to access the local file system of node.js server.

The readline module provides an interface for reading data from a Readable stream (such as process.stdin) one line at a time.

googleapis is a node.js client library for using Google APIs. Support for authorization and authentication with OAuth 2.0, API Keys, and JWT tokens is included.

We have included the required libraries. Now let's use it in action. Add the following lines.

const fs = require('fs');
const readline = require('readline');
const { google } = require('googleapis');

// If modifying these scopes, delete token.json.
const SCOPES = ['https://www.googleapis.com/auth/drive'];

// The file token.json stores the user's access and refresh tokens, and is
// created automatically when the authorization flow completes for the first
// time.
const TOKEN_PATH = 'token.json';

let auth;

// ...
Enter fullscreen mode Exit fullscreen mode

Let's take a look at what have we added so far.

The SCOPES variable contains what type of permission we are getting for google drive. For example, if we want read-only permission for metadata then we should add */drive.metadata.readonly* at the end of the link.

For TOKEN_PATH read the comment lines above. (Hope you have already read it)

auth will contain the authentication that we will get soon from google to accomplish our tasks.

Now that we have successfully imported what we need so far. Let's use them in action now.

// ...
let auth;

// Load client secrets from a local file.
fs.readFile('credentials.json', (err, content) => {
  if (err) return console.log('Error loading client secret file:', err);
  // Authorize a client with credentials, then call the Google Drive API.
  authorize(JSON.parse(content));
});
Enter fullscreen mode Exit fullscreen mode

The credential.json file that we have stored in the root folder of our server, in order to read the file we are taking the help of the fs module of node.js.

So, by using this above function we will read the file and call the authorize function to get the authorization from google. So, let's write the function called authorize.

// ...

/**
 * Create an OAuth2 client with the given credentials, and then execute the
 * given callback function.
 * @param {Object} credentials The authorization client credentials.
 * @param {function} callback The callback to call with the authorized client.
 */
function authorize(credentials) {
  const { client_secret, client_id, redirect_uris } = credentials.installed;
  const oAuth2Client = new google.auth.OAuth2(
    client_id,
    client_secret,
    redirect_uris[0]
  );

  // Check if we have previously stored a token.
  fs.readFile(TOKEN_PATH, (err, token) => {
    if (err) return getAccessToken(oAuth2Client);
    oAuth2Client.setCredentials(JSON.parse(token));
    auth = oAuth2Client;
  });
}
Enter fullscreen mode Exit fullscreen mode

Woo! Wrote a huge amount of codes ha? Don't worry let's take a look at what we have done so far in this function.

At first, we have extracted three values from the credential.json file & stored them in three separate variables. After that, by using these variables we have called the google OAuth2 method to get the oAuth2Client to get the real authorization below.

Now with the help of fs module, we are reading the token.json file. For the first time we haven't any token.json file, so we are calling getAccessToken function to get the token from google. After getting the token.json for the first time will just set the credentials with oAuthClient each time whenever the server gets started.

Now let's write getAccessToken function which will get the token from google, in case if we don't have the token.json file in the root of our server.

// ...

/**
 * Get and store new token after prompting for user authorization, and then
 * execute the given callback with the authorized OAuth2 client.
 * @param {google.auth.OAuth2} oAuth2Client The OAuth2 client to get token for.
 * @param {getEventsCallback} callback The callback for the authorized client.
 */

function getAccessToken(oAuth2Client) {
  const authUrl = oAuth2Client.generateAuthUrl({
    access_type: 'offline',
    scope: SCOPES,
  });
  console.log('Authorize this app by visiting this url:', authUrl);
  const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout,
  });
  rl.question('Enter the code from that page here: ', (code) => {
    rl.close();
    oAuth2Client.getToken(code, (err, token) => {
      if (err) return console.error('Error retrieving access token', err);
      oAuth2Client.setCredentials(token);
      // Store the token to disk for later program executions
      fs.writeFile(TOKEN_PATH, JSON.stringify(token), (err) => {
        if (err) return console.error(err);
        console.log('Token stored to', TOKEN_PATH);
      });
      auth = authoAuth2Client;
    });
  });
}
Enter fullscreen mode Exit fullscreen mode

This getAccessToken() will do the following:

  • It will show a link in the console to get the drive permission
  • It will receive a code in the console that google drive provides
  • It will store the token.json file in the root folder of the server

Now let's start the server by this

node server.js
Enter fullscreen mode Exit fullscreen mode

This will provide us a URL to get permission from google. Open the link in the browser. Select your account if you have multiple accounts. If this shows you this app isn't verified then skip this by > advance > Go to Quickstart(unsafe).

Now allow permission. This will a code to copy. Copy it and paste it to the console.

That's it! Check the root folder of your server. A token.json file is already has been saved. From now there is no need to do this same procedure if you have your credentials.json and token.json file saved in the root folder of your server.


Upload an image file to Google Drive from node.js server

We are not going to upload the image from any kind of request from the UI/postman. Instead, we are going to upload the image from our existing server folder.

Let's manually save an image to ./demo-files/kamal-hossain.jpg. You can change the folder and image name if you want, but don't forget to change them in the code.

Now let's define a post route in our node.js server by these following lines:

// ...

app.post('/uploadAFile', (req, res) => {
  var fileMetadata = {
    name: 'kamal-hossain', // file name that will be saved in google drive
  };

  var media = {
    mimeType: 'image/jpg',
    body: fs.createReadStream('./demo-files/kamal-hossain.jpg'), // Reading the file from our server
  };

  // Authenticating drive API
  const drive = google.drive({ version: 'v3', auth });

  // Uploading Single image to drive
  drive.files.create(
    {
      resource: fileMetadata,
      media: media,
    },
    async (err, file) => {
      if (err) {
        // Handle error
        console.error(err.msg);

        return res
          .status(400)
          .json({ errors: [{ msg: 'Server Error try again later' }] });
      } else {
        // if file upload success then return the unique google drive id
        res.status(200).json({
          fileID: file.data.id,
        });
      }
    }
  );
});
Enter fullscreen mode Exit fullscreen mode

Please read the comments in the code, hope everyting wil be clear to your. If the file image upload is successfull then this kind of reponse will come probably. (I am using postman to send this post request)

{
    "fileID": "1w-wsh2nJsT0cldTf_fJnOsfdJwsuPpWzp"
}
Enter fullscreen mode Exit fullscreen mode

In Sha Allah (if Allah wills), Maybe in my another blog I will try to post how to download, delete or do other operations in google drive from node.js server. Stay tuned.

Top comments (2)

Collapse
 
ludocomito profile image
ludocomito

Hi, thanks for the great tutorial. I'm having a problem during the first test. Basically i copy and aste the url that is logged on the terminal, I manage to get to the login screen, and then when i accept the privacy alert and that's where the problem is. I expect to be redirected to a page which gives me the code to insert back, but instead i reach a blank page. I managed to read this error through the chrome developer console:
VM8:5553 crbug/1173575, non-JS module files deprecated.
Can you give any help?
Thanks.

Collapse
 
iftikhar profile image
iftikhar hussain

In ShaAllah :)