Monday, December 8, 2014

Retrieving Google Analytics data from a Node.js backend

I've recently added the ability for a web app to display Google Analytics information, such as the number of sessions and users for a monitored application. My backend to this web app happens to be Node, and the documentation for getting this to work is pretty non-existent. I hope this post enables others to be able to easily integrate this type of feature into their Node applications!

First, in your package.json, add the dependency for "googleapis". For all google analytics integration, I created a ga.js file, and placed it in ./api/controllers. In my main Node app, app.js, I created a reference to this
var ga = require('./app/controllers/ga.js');


I then use this reference for an API GET as follows
app.get('/analytics/sessionsAndUsers/startDate/:startDate/endDate/:endDate', ensureAuthenticated, ga.getSessionsAndUsers);
Here, I created the endpoint and pass in a startDate and endDate to my function getSessionsAndUsers. I also call ensureAuthenticated, which validates the user making the GET call is logged in - this is set up using Passport.js, a completely different topic.

In order for the above to work, I need to create my function getSessionsAndUsers in ga.js
module.exports.getSessionsAndUsers = function(req, res, next) {

  ...

};

Now, I need to build out the guts for this to work. First, a little pre-setup needs to happen. You need to go to the Google Dev Console and enable the Analytics API. Then on the Credentials page, create a new Client ID, of type Service Account. This will provide you with a email address and automatically download a private key. Follow the steps here to convert this key to a .pem file. Additionally, go into your Google Analytics account and add the @developer.gserviceaccount.com email address as a user.

Once the above is done, we can build out the JavaScript. In ga.js, add the following to the top of the file, replacing with your service account email address and .pem path, as well as the profile Id of the analytics you want to monitor.
var google = require('googleapis');
var SERVICE_ACCOUNT_EMAIL = '*********@developer.gserviceaccount.com';
var SERVICE_ACCOUNT_KEY_FILE = '/MYPATH/googleapi-privatekey.pem';
var jwt = new google.auth.JWT(
        SERVICE_ACCOUNT_EMAIL,
        SERVICE_ACCOUNT_KEY_FILE,
        null,
        ['https://www.googleapis.com/auth/analytics.readonly']);

var analytics = google.analytics('v3');
var gaId = 'YOUR_PROFILE_ID';
Now, we are ready to finish up the getSessionsAndUsers function. Here is an example:
module.exports.getSessionsAndUsers = function(req, res, next) {
  var startDate = '2014-12-08';
  var endDate = '2014-12-08';
  try { startDate = req.params.startDate ? req.params.startDate : null; }
  catch (err) {
    res.send(404, 'startDate not found');
    return;
  }
  try { endDate = req.params.endDate ? req.params.endDate : null; }
  catch (err) {
    res.send(404, 'endDate not found');
    return;
  }

  jwt.authorize(function(err, result) {
    if(err) {
      console.log(err);
      return;
    }
    analytics.data.ga.get({
      auth: jwt,
      'ids': 'ga:' + gaId,
      'start-date': startDate,
      'end-date': endDate,
      'metrics': 'ga:sessions,ga:users'

      }, function(err, result) {
        if(!err){
          res.status(201).send(result);
        }
        else{
          next();
        }
    });
  });

};

And that's it! You will be able to make a call from your web app to this node backend like so:
var promise =  $.getJSON("analytics/sessionsAndUsers/startDate/"+startDate+"/endDate/"+endDate);