Google Drive API in node.js
Tags: javascript, webdev, node, googledriveapi
Published: 2020-08-28 00:00:00

---
title: Google Drive API in node.js
date: '2020-08-28'
og:
  description: 'How to create a nodejs server easily? How to get authentication for google drive ? How to upload file to Google Drive API?'
  image: 'https://kamalhossain.me/assets/img/og/google-drive-api-in-nodejs.png'
  blognum: '#2'
author:
  twitter: 'kamalhossain_me'
  name: 'Kamal Hossain'
---

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:

```bash
mkdir google-drive-api-v3 && cd google-drive-api-v3
```

```bash
npm init -y && npm install express --save
```

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

```js
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}...`);
});
```

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:

```bash
node server.js
```

Congratulations! we have started our server successfully. So now we can check this route via [postman](https://www.postman.com/) 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](https://developers.google.com/drive/api/v3/quickstart/nodejs) 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:

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

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

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

The [readline](https://nodejs.org/api/readline.html) module provides an interface for reading data from a Readable stream (such as process.stdin) one line at a time.

[googleapis](https://www.npmjs.com/package/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.

```js
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;

// ...
```

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.

```js
// ...
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));
});
```

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**.

```js
// ...

/**
 * 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;
  });
}
```

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.

```js
// ...

/**
 * 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;
    });
  });
}
```

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

```js
node server.js
```

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:

```js
// ...

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,
        });
      }
    }
  );
});
```

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](https://www.postman.com/) to send this `post` request)

```
{
    "fileID": "1w-wsh2nJsT0cldTf_fJnOsfdJwsuPpWzp"
}
```

---

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.