yyewdg
Last Updated: February 25, 2016
·
1.736K
· analogj
57a90b685ef5eb6b17edf33fa91c4ea8

Google Analytics Events on Server Side

While working on QuietThyme, our cloud ebook manager, I realized that our Google analytics dashboard was missing some key requests due to the nature of Google's tracking code. Since Google only provides developers with a javascript analytics api, it is impossible to track xml documents, image requests or any dynamically generated content that will not be opened by a browser.

QuietThyme supports the Open Publication Distribution System (OPDS) standard which is simply a series of structured XML document that lists each users' books, ordered by category, author, title, etc. We generate each user's OPDS catalog dynamically, and not only that, the OPDS catalog url that we provide our users with is usually entered into a mobile ebook reader app, definitely not viewed in a browser. All this put together results in the fact that we were unable to track popular categories, or even searches on user catalogs.

The first step to add Google Analytics to our MVC app was to add the GoogleAnalyticsTracking, which is an open source (MS-PL License) library written by Maarten Balliauw. (nuget link)

With GoogleAnalyticsTracking installed, I then proceeded to create a GoogleAnalyticsTrackEvent action filter, that could be placed within any Controller or registered in the Global.asax.

The GoogleAnalyticsTrackEvent action filter was very simple, and looked as follows:

public class GoogleAnalyticsTrackEvent : ActionFilterAttribute
{
    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        var gaTracker = new Tracker(ConfigurationManager.AppSettings["Analytics_Google_ID"], ConfigurationManager.AppSettings["Analytics_Google_Domain"]);

        if (filterContext.HttpContext.User.Identity.IsAuthenticated)
        {
            gaTracker.TrackEvent(filterContext.ActionDescriptor.ControllerDescriptor.ControllerName, filterContext.ActionDescriptor.ActionName, filterContext.HttpContext.User.Identity.Name, 0);
            return;
        }
        gaTracker.TrackEvent(
                filterContext.ActionDescriptor.ControllerDescriptor.ControllerName,
                filterContext.ActionDescriptor.ActionName, null, 0);


    }
}

I then added it to my controller as I would any other Action Filter.

[GoogleAnalyticsTrackEvent]
public class HomeController : Controller
{
...
}

However I soon realized that I also needed to track some data that would be present in my view model. Since I still wanted the GoogleAnalyticsTracker code to execute AFTER the action had finished executing, I wouldn't be able to access the Model data in the OnActionExecuted handler. I would need to use the OnActionExecuting handler to store some view model data, and then retrieve it in the OnActionExecuted handler. To do this I used the filterContext.HttpContext.Items dictionary.

public class GoogleAnalyticsTrackEventWithModelData : ActionFilterAttribute
{

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        if (filterContext.ActionParameters.ContainsKey("id"))
        {
           filterContext.HttpContext.Items.Add("id", filterContext.ActionParameters["id"]);
        }
        if(filterContext.ActionParameters.ContainsKey("guid"))
        {
            filterContext.HttpContext.Items.Add("guid",filterContext.ActionParameters["guid"]);
        }

    }


    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        var gaTracker = new Tracker(ConfigurationManager.AppSettings["Analytics_Google_ID"], ConfigurationManager.AppSettings["Analytics_Google_Domain"]);

        String guid = (String)filterContext.HttpContext.Items["guid"];

        Int32 id = 0;
        if(filterContext.HttpContext.Items.Contains("id"))
        {
            id = (Int32?) filterContext.HttpContext.Items["id"] ?? 0;
        }

        gaTracker.TrackEvent(
                filterContext.ActionDescriptor.ControllerDescriptor.ControllerName,
                filterContext.ActionDescriptor.ActionName, guid, id);

    }
}

And Voila, QuietThyme now has server side analytics events enabled for dynamically generated non-browser documents. Not too bad for an hour or two in a coffee shop.

If I piqued your interest talking about QuietThyme, our Cloud Ebook Manager, you might want to take a look at my Introducing QuietThyme post.

-Jason Kulatunga

Say Thanks
Respond