Sunday 30 April 2017

Accessing Gmail API through Cloud Functions

I'm attempting to build an email parser that responds to a gmail pubsub message. I am currently able to receive and parse the pubsub message and extract the historyId, but I'm having trouble authenticating my request to the gmail api. Here's what I have up to now:

  //function defined outside the scope of the main function
  //used to create auth client
  function getAuthClient(event, callback) {
    var GoogleAuth = require('google-auth-library');

    var authFactory = new GoogleAuth();

    authFactory.getApplicationDefault(function (err, authClient) {
     if (err) {
       console.log('Unable to get application default credentials.');
       callback(err);
       return;
     }

     // Create the oAuth scopes you need
     if (authClient.createScopedRequired && authClient.createScopedRequired()) {
    console.log('creating scoped client');
      authClient = authClient.createScoped([
          'https://mail.google.com/'
      ]);
    }
   callback(null, authClient);
  });
}

exports.gmailParser = function gmailParser (event, callback) {
 var path = require('path');
 var base64 = require('base-64');

 // Set your service account key file into the environment for the auth lib 
to pick up
 process.env['GOOGLE_APPLICATION_CREDENTIALS'] = path.resolve(__dirname, 
'auth_credentials.json');
 console.log(process.env['GOOGLE_APPLICATION_CREDENTIALS']);


 console.log(__dirname);

 //parse pubsub message
 var pubsubMessage = event.data;
 var baseMessage = pubsubMessage.data;
 var decodedMessage = base64.decode(baseMessage);
 var messageJSON = JSON.parse(decodedMessage);

 // Extract emailAddress and historyId from gmail pubsub message
 var historyId = messageJSON.historyId;
 var email = messageJSON.emailAddress;

 getAuthClient(null, function(err, authClient) {

   //import necessary libraries
   var google = require('googleapis');
   var gmail = google.gmail('v1');

   if(err) {
     callback(err);
   }

  // Construct a params object
  var params = {
    userId: email,
    startHistoryId: historyId
 };


//Attempt to call gmail api. This is where the error occurs.
gmail.users.history.list(params, function(error, response) {
  if (error) {  
    console.log('Encountered error', error);
    callback(error);
  } else {
    console.log('Response', response);
    callback(response);
  }
});
 });
};

The code runs successfully but I get the following error:

"Error: Login Required
at Request._callback (/user_code/node_modules/googleapis/node_modules/google-auth-library/lib/transporters.js:85:15)
at Request.self.callback (/user_code/node_modules/googleapis/node_modules/request/request.js:188:22)
at emitTwo (events.js:106:13)
at Request.emit (events.js:191:7)
at Request.<anonymous> (/user_code/node_modules/googleapis/node_modules/request/request.js:1171:10)
at emitOne (events.js:96:13)
at Request.emit (events.js:188:7)
at IncomingMessage.<anonymous> (/user_code/node_modules/googleapis/node_modules/request/request.js:1091:12)
at IncomingMessage.g (events.js:291:16)
at emitNone (events.js:91:20)"   

I've tried adding the authClient to the param object but it returns a "Bad request" error. I've tried changing the order of the imports, created new credentials, but I haven't been able to get anywhere. If anyone has any pointers it would be greatly appreciated.



via kevinivan05

No comments:

Post a Comment