SKIP TO CONTENT

concise example of an authenticated Google API request

July 13, 2021

written by
Joren Mathews

I recently had to read data from google docs about an API we wanted to install. It was difficult to find a simple, working example code for authentication and API requests. What a pain. Pull out the old soapbox, here’s what I would like to see as documentation for developers like myself. It should be a useful starting point for many types of Google API access.

Create service account credentials file.

  1. Go here: https://console.cloud.google.com/apis/credentials and select or create your project.
  2. Click “Create Credentials” and create a Service Account. See here for details: https://cloud.google.com/iam/docs/creating-managing-service-accounts
  3. Click on your created service account, go to the “KEYS” tab, click “ADD KEY” and choose “Create new key”. Choose JSON for your key type.
  4. Save your new json file somewhere in your project.

Share your document with your service account. This probably isn’t necessary if your document is public, but I haven’t tried.

  1. Go into your service account “DETAILS” tab.
  2. Copy the Email listed there.
  3. In your document click Share and add the service account email.

Here’s the example code for acquiring the access token and making the request:

const serviceAccount = require('[your credentials file].json')
const jwt = require('jsonwebtoken')

const createJwt = ({client_email, private_key}, scope) => {
    const token = {
        iat: parseInt(Date.now() / 1000),
        exp: parseInt(Date.now() / 1000) + 20 * 60, // 20 minutes
        aud: 'https://oauth2.googleapis.com/token',
        scope: scope,
        iss: client_email
    }

    return jwt.sign(token, private_key, {algorithm: 'RS256'});
}

const createToken = async (jwt) => {
    const res = await fetch(
        'https://oauth2.googleapis.com/token', {
            method: 'POST',
            body: JSON.stringify({
                grant_type: 'urn:ietf:params:oauth:grant-type:jwt-bearer',
                assertion: jwt
            })
        }
    )

    const resJson = await res.json()

    return resJson.access_token
}

const getAccessKey = async (scope) => {
    const jwt = createJwt(serviceAccount, scope)
    const token = await createToken(jwt)

    return token
}


const getDocumentData = async (documentId) => {
    // Get your access key with the desired scope.
    // See here: https://developers.google.com/identity/protocols/oauth2/scopes#docs
    const accessKey = await getAccessKey('https://www.googleapis.com/auth/documents.readonly')

    // The url for the api request.
    const requestUrl = `https://docs.googleapis.com/v1/documents/${documentId}`

    const res = await fetch(
        requestUrl, {
            method: 'GET',
            headers: {
                'Content-Type': 'application/json',
                'Accept': 'application/json',
                'Authorization': `Bearer ${accessKey}`,
            }
        }
    )

    const document = await res.json()

    if (document.error) {
        console.log('Failed to fetch google doc')
        return null
    }

    return document
}