Google Analytics Measurement Protocol – Track Events C#

Recently I had a project that required to track events happening within the business layer and could not be tracked using JavaScript from the client. To do this a helper class was required in order to communicate with Google Analytics and track those extra events. Below you will find that class that can be used to do Page Tracking, Event Tracking, Ecommerce Tracking, Social Interactions and Exception Tracking within your C# code without requiring any JavaScript or any other script.

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Web;

namespace Spyriadis.net
{
    public class GoogleTracker
    {
        private string googleURL = "http://www.google-analytics.com/collect";
        private string googleVersion = "1";
        private string googleTrackingID = "UA-XXXX-Y";
        private string googleClientID = "555";

        public GoogleTracker(string trackingID)
        {
            this.googleTrackingID = trackingID;
        }

        public void trackEvent(string category, string action, string label, string value)
        {
            Hashtable ht = baseValues();
            
            ht.Add("t", "event");                   // Event hit type
            ht.Add("ec", category);                 // Event Category. Required.
            ht.Add("ea", action);                   // Event Action. Required.
            if (label != null) ht.Add("el", label); // Event label.
            if (value != null) ht.Add("ev", value); // Event value.

            postData(ht);
        }
        public void trackPage(string hostname, string page, string title)
        {
            Hashtable ht = baseValues();

            ht.Add("t", "pageview");                // Pageview hit type.
            ht.Add("dh", hostname);                 // Document hostname.
            ht.Add("dp", page);                     // Page.
            ht.Add("dt", title);                    // Title.

            postData(ht);
        }
        
        public void ecommerceTransaction(string id, string affiliation, string revenue, string shipping, string tax, string currency)
        {
            Hashtable ht = baseValues();
            
            ht.Add("t", "transaction");       // Transaction hit type.
            ht.Add("ti", id);                 // transaction ID.            Required.
            ht.Add("ta", affiliation);        // Transaction affiliation.
            ht.Add("tr", revenue);            // Transaction revenue.
            ht.Add("ts", shipping);           // Transaction shipping.
            ht.Add("tt", tax);                // Transaction tax.
            ht.Add("cu", currency);           // Currency code.

            postData(ht);
        }
        public void ecommerceItem(string id, string name, string price, string quantity, string code, string category, string currency)
        {
            Hashtable ht = baseValues();

            ht.Add("t", "item");              // Item hit type.
            ht.Add("ti", id);                 // transaction ID.            Required.
            ht.Add("in", name);               // Item name.                 Required.
            ht.Add("ip", price);              // Item price.
            ht.Add("iq", quantity);           // Item quantity.
            ht.Add("ic", code);               // Item code / SKU.
            ht.Add("iv", category);           // Item variation / category.
            ht.Add("cu", currency);           // Currency code.

            postData(ht);
        }

        public void trackSocial(string action, string network, string target)
        {
            Hashtable ht = baseValues();

            ht.Add("t", "social");                // Social hit type.
            ht.Add("dh", action);                 // Social Action.         Required.
            ht.Add("dp", network);                // Social Network.        Required.
            ht.Add("dt", target);                 // Social Target.         Required.

            postData(ht);
        }

        public void trackException(string description, bool fatal)
        {
            Hashtable ht = baseValues();

            ht.Add("t", "exception");             // Exception hit type.
            ht.Add("dh", description);            // Exception description.         Required.
            ht.Add("dp", fatal ? "1" : "0");      // Exception is fatal?            Required.

            postData(ht);
        }

        private Hashtable baseValues()
        {
            Hashtable ht = new Hashtable();
            ht.Add("v", googleVersion);         // Version.
            ht.Add("tid", googleTrackingID);    // Tracking ID / Web property / Property ID.
            ht.Add("cid", googleClientID);      // Anonymous Client ID.
            return ht;
        }
        private bool postData(Hashtable values)
        {
            string data = "";
            foreach (var key in values.Keys)
            {
                if (data != "") data += "&";
                if (values[key] != null) data += key.ToString() + "=" + HttpUtility.UrlEncode(values[key].ToString());
            }
            
            using (var client = new WebClient())
            {
                var result = client.UploadString(googleURL, "POST", data);                               
            }

            return true;
        }
    }
}

All you need to do afterwards initialize the class using the code below:

Spyriadis.net.GoogleTracker ga = new Spyriadis.net.GoogleTracker("UA-XXXXXXX-X");

And then you can use all the functions by Google as described here. For example to track an event you use:

ga.trackEvent("Category", "Action", "label", "value");

You can pass null values for all the non-required fields.

8 Comments

  1. Hi, have you ever had an issue where the events track in real time but then do not appear in the Google Analytics Behaviour => Event => Overview ?

    I am having this issue and not sure why?

    Event is tracking in real time but won’t ‘save’ as a tracked event.

    • Yes! The problem is that Google will only track events related to a page view. What that means is that if you sent events that are not received after a corresponding page view those events will probably not appear on your reports. If that is the case you will probably get a warning as I got on your Google Analytics account:
      The Landing Pages report has a (not set) entry. Verify that tracking code for property http://www.yourdomain.net sends a _trackPageview hit and that it does this before sending any events.

      • Turns out there was nothing wrong, it actually can just take up to 24 hours for the event to save in to the ‘Behaviour’ section of GA.

        Thanks for the above code, it has worked great for me after a few tweaks to customise for my needs.

  2. Hello Spyriadis,

    Your class seems great, thanks. What is the ClientID to use? I’m not sure where to find it…

  3. hello , can you explain , which function i need to use to get the my data on google ecommerce

Leave a Reply to Paul Connolly Cancel reply

Your email address will not be published. Required fields are marked *