Creating a node script that can write to google docs
Tags: node, oauth2, googledocs, javascript
Published: 2019-10-07 22:21:02

---
title: Creating a node script that can write to google docs
published: true
description: Using oauth2, this shows how you can use nodejs to write to a google doc programmatically
tags: nodejs, oauth2, google docs, javascript
---

My wife and I use a shared google doc for our grocery list, and I often find myself forgetting to add groceries to our list which then results in us forgetting to buy things at the grocery store.

So I setup an automation when I tell google to `add "something"`, IFTTT knows that when I say that, it sends a web request to my heroku server which then uses the google javascript api to update my google doc.  I am happy with this setup and want to share with you all how I did it!

So this is Part 1 of a multi-part blog series on how to accomplish what I mentioned above! Stay tuned for the next parts!

Go to <a href="https://docs.new" target="_blank" rel="noopener noreferrer">https://docs.new</a> in your browser, and that will create a new google doc.
Title it Groceries (or whatever you want).

Note the id of the doc. It's between `d/` and `/edit` in the url.

Mine is `1OvhQtG2WYagqI-zBk_IXTRWhLijCu2_hB-ExdyCYI54`


## Creating oauth tokens with google nodejs apis

Run the following commands.

We'll be using yarn from here on out.

```
mkdir grocery-adder && cd grocery-adder
yarn init -y
git init
touch .gitignore
yarn add googleapis
mkdir src && touch src/index.js
```

Add the following to your `.gitignore` file:
```
.idea
node_modules
```

Keep in mind that I will have `credentials.json` and `token.json` ignored in my final example so I don't compromise my google account to you all :) 


For the rest of the oauth setup, I'm really just summarizing the following tutorial: https://developers.google.com/gmail/api/quickstart/nodejs

1. Go to https://console.developers.google.com/apis/library/docs.googleapis.com
1. Click `Enable`
1. Go to https://developers.google.com/gmail/api/quickstart/nodejs
1. Click `Enable the Gmail API`
1. Save `credentials.json` to `grocery-adder`
1. Paste the following code into `src/index.js`

```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/documents"];
// 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";

// 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 Gmail API.
  authorize(JSON.parse(content), () => console.log("authorized!"));
});

/**
 * 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, callback) {
  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 getNewToken(oAuth2Client, callback);
    oAuth2Client.setCredentials(JSON.parse(token));
    callback(oAuth2Client);
  });
}

/**
 * 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 getNewToken(oAuth2Client, callback) {
  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), error => {
        if (error) return console.error(error);
        console.log("Token stored to", TOKEN_PATH);
      });
      callback(oAuth2Client);
    });
  });
}

```

1. Run `node src/index.js`
1. Follow the prompts on the terminal
1. You'll get a warning saying `This app isn't verified`, that's ok! You are the app!!
1. Great now you have `token.json` stored at the root of `grocery-adder`
1. Run `node src/index.js` and you'll see that `authorized!` is printed on the terminal
1. Now we can delete a lot of that setup code and write to your google doc!

Your file should look like the following:

```js
const { google } = require("googleapis");
const token = require("../token.json");
const credentials = require("../credentials.json");

function authorize() {
  const { client_secret, client_id, redirect_uris } = credentials.installed;
  const oAuth2Client = new google.auth.OAuth2(
    client_id,
    client_secret,
    redirect_uris[0]
  );
  oAuth2Client.setCredentials(token);
  return oAuth2Client;
}

async function main(YOUR_DOCUMENT_ID) {
    const auth = await authorize();
    const docs = google.docs({
      version: "v1",
      auth
    });
    await docs.documents.batchUpdate({
      auth,
      documentId: YOUR_DOCUMENT_ID,
      requestBody: {
        requests: [
          {
            insertText: {
              location: {
                index: 1
              },
              text: "hello!\n"
            }
          }
        ]
      }
    });
}

main("YOUR_DOCUMENT_ID");

```
If you see `text: "hello!\n"`, you'll see what will be getting written to our doc!

Replace "YOUR_DOCUMENT_ID" with your document id and run it! 

Now, if you go to your new google doc, you'll see `hello!` printed there! If you keep running this, `hello!` will continue getting added.

The code to generate the token can be found <a href="https://github.com/mcrowder65/write-to-google-doc/blob/master/src/token-generator.js">here</a>

The code to write to the google doc can be found <a href="https://github.com/mcrowder65/write-to-google-doc/blob/master/src/index.js">here</a>