4

I want to write an app that can process some of my gmail emails that are labeled a certain way.

The example code here gave me a starting point for my code (which I've rewritten using promises instead of async await):

'use strict';

const path = require('path');
const { google } = require('googleapis');
const { authenticate } = require('@google-cloud/local-auth');

authenticate({
    keyfilePath: path.join(__dirname, 'key.json'),
    scopes: [
        'https://www.googleapis.com/auth/gmail.readonly',
    ],
}).then(auth => {
    google.options({ auth })

    gmail.users.messages.list({
        userId: "me",
    }).then((res) => {
        console.log(res.data)
    }).catch(err => {
        console.log(err)
    })
}).catch(err => {
    console.log(err);
})

Here are the steps I've taken so far:

  • created a google cloud project
  • created a service account with the owner role
  • downloaded the key file from the service account and copied it to my code directory as key.json
  • ran the code:
GOOGLE_APPLICATION_CREDENTIALS="$(pwd)/key.json" node index.js

Here's the error I am getting:

TypeError: Cannot read property 'redirect_uris' of undefined
    at authenticate (/home/user/dev/gmail-processor/node_modules/@google-cloud/local-auth/build/src/index.js:46:15)
    at Object.<anonymous> (/home/user/dev/gmail-processor/index.js:7:1)
    at Module._compile (internal/modules/cjs/loader.js:778:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:789:10)
    at Module.load (internal/modules/cjs/loader.js:653:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:593:12)
    at Function.Module._load (internal/modules/cjs/loader.js:585:3)
    at Function.Module.runMain (internal/modules/cjs/loader.js:831:12)
    at startup (internal/bootstrap/node.js:283:19)
    at bootstrapNodeJSCore (internal/bootstrap/node.js:622:3)

It seems like it is expecting oauth credentials with a redirect url. Also, it seems redundant that I am exportingGOOGLE_APPLICATION_CREDENTIALS when I include keyfilePath when I call authenticate. What am I doing wrong, how can I get this code to execute successfully?

  • The library you're using is in **beta** mode: [Ref](https://github.com/googleapis/nodejs-local-auth). Do you want to specifically use `local-auth`? Would the workflow specified [here](https://stackoverflow.com/a/60092848/10612011) be an option? – Iamblichus May 21 '20 at 10:41
  • 1
    Did you find a way around this issue? I'm having the same issue with the Youtube Data API. – Nelson King Aug 17 '20 at 02:10

2 Answers2

0

Inside your key.json file, you'll have to pass your redirect_uris:

{
  ...
  "web": {
   // put your callback here:
    "redirect_uris": ["http://localhost:3000/oauth2callback"]
  }
}

After that, it should work. The docs are not clear about that, though. I'm still figuring things out.

EDIT 1:

Alright, I got it...

Go to your credentials section on Google Cloud Console and create your OAuth 2.0 Client IDs if you didn't already and download the JSON file. Use that JSON file as your keys.json. It worked for me :)

Douglas Pires
  • 36
  • 2
  • 5
0

I fixed this problem by using:

const auth = new google.auth.GoogleAuth({
  keyFile: path.join(__dirname, 'key.json'),
  scopes: ['https://www.googleapis.com/auth/gmail.readonly'],
});

instead of:

const auth = await authenticate({
  keyfilePath: path.join(__dirname, 'key.json'),
  scopes: ['https://www.googleapis.com/auth/gmail.readonly'],
});
stena
  • 437
  • 2
  • 12