E-mail open rate tracking with Google Analytics' Measurement Protocol - Demo

Edit 4th Feb 2015 - Google have published an email tracking guide with the Measurement Protocol.  The below goes a bit beyond that showing how to link the user sessions etc.

The Measurement Protocol was launched at the same time as Universal Analytics, but I've seen less adoption of it with clients, so this post is an attempt to show what can be done with it with a practical example.

The demo app is available here: http://ua-post-to-push.appspot.com/

With this demo you should be able to track the following:

  1. You have an email address from an interested customer
  2. You send them an email and they look at it, but don't click through.
  3. Three days later they open the email again at home, and click through to the offer on your website.
  4. They complete the form on the page and convert.

Within GA, you will be able to see for that campaign 2 opens, 1 click/visit and 1 conversion for that user.  As with all email open tracking, you are dependent on the user downloading the image, which is why I include the option to upload an image and not just a pixel, as it may be more enticing to allow images in your newsletter.


The Measurement Protocol lets you track beyond the website, without the need of client-side JavaScript.  You construct the URL and when that URL is loaded, you see the hit in your Google Analytics account.  That's it. 

The clever bit is that you can link user sessions together via the CID (Customer ID), so you can track the upcoming Internet of Things off-line to on-line, but also things like email opens and affiliate thank you pages.  It also works with things like enhanced e-commerce, so can be used for customer refunds or product impressions. 

This demo looks at e-mail opens for its example, but its minor modifications to track other things.  For instance, I use a similar script to measure in GA when my Raspberry Pi is backing up our home computers via Time Machine.

Demo on App Engine

To use the Measurement Protocol in production most likely needs server-side code.  I'm running a demo on Google App Engine coded in Python, which is pretty readable so should make it fairly easy for a developer to replicate in their favourite language.  App Engine is also a good choice if you are wanting to run it in production, since it has a free tier for tracking 1000s of email opens a day, but scalability to handle millions.

This code is available on Github here - http://github.com/MarkEdmondson1234/ga-get-to-post

App running that code is here: http://ua-post-to-push.appspot.com/

There are instructions on Github on how it works, but I'll run through some of the key concepts here in this post.

What the code does

The example has four main URLs:
  • The homepage explaining the app
  • The image URL itself, that when loaded creates the hit to GA
  • A landing page with example custom GA tracking script
  • An upload image form to change the image you would display in the e-mail.
The URLs above are controlled server side with the code in main.py


This does nothing server side aside serve up the page

Image URL

This is the main point of the app - it turns a GET request for the image uploaded into a POST with the parameters found in the URL.  It handles the different options and sends the hit to GA as a virtual pageview or event, with a unique user CID and campaign name. An example URL here is:

Landing Page

This does little but take the cid you put in the email URL, and outputs the CID that will be used in Google Analytics.  If this is the same CID as in the image URL and the user clicks in the email, those sessions will be linked. You can also add the GA campaign parameters, but the sever side script ignores those - the javascript on the page will take care of it. An example URL here is:

The CID in the landing page URL is then captured and turned into an anonymous CID for GA.  This is then served up to the Universal Analytics JavaScript on the landing page, shown below.  Use the same UA code for both, else it won't work (e.g. UA-123456-1)

Upload Image

This just handles the image uploading and serves the image up via App Engines blobstore.  Nothing pertinent to GA here so see the Github code if interested.


Its hoped this helps sell using the Measurement Protocol to more developers, as it offers a solution to a lot of the problems with digital measurement today, such as attribution of users beyond the website.  The implementation is reasonably simple, but the power is in what you send and what situations.  Hopefully this inspires what you could do with your setup.

There are some limitations to be aware of - the CID linking won't stitch sessions together, it just discards a user's old CID if they already had one, so you may want to look at userID or how to customise the CID for users who visit your website first before the email is sent.  The best scenario would be if a user is logged in for every session, but this may not be practical.  It may be that the value of linking sessions is so advantageous in the future, entire website strategies will be focused on getting users to ID themselves, such as via social logins.

Always consider privacy: look for user's to opt in, and make sure to use GA filters to take out any PII you may put into GA as a result.  Current policy looks to be that if the data within GA is not able to be tracked to an individual (e.g. a name, address or email) then you are able to record an anonymous personal ID, that could be exported and linked to PII outside of GA.  This is a bit of a shifting target, but in all cases keeping it as user focused and not profit focused as possible should see you through any ethical questions.

Run R, RStudio and OpenCPU on Google Compute Engine [free VM image]

File this under "what I wished was on the web whilst trying to do this myself."

edit 20th November, 2016 - now everything in this post is abstracted away and available in the googleComputeEngineR package - I would say its a lot easier to use that.  Here is a post on getting started with it. http://code.markedmondson.me/launch-rstudio-server-google-cloud-in-two-lines-r/

edit 30th April, 2016: I now have a new post up on how to install RStudio Server on Google Compute Engine using Docker, which is a better way to do it. 

edit 30th Nov, 2015: Oscar explains why some users couldn't use their username

edit 5th October: Added how to login, add users and migrated from gcutil to gcloud

Google Compute Engine is a very scalable and quick alternative to Amazon Web Services, but a bit less evolved in the images available for users. 

If you would like to have a VM with R 3.01, RStudio Server 0.98 and OpenCPU installed, then you can click on the link below, and install a pre-configured version for you to build upon.

With this image, you have a cloud server with the most popular R / Cloud interfaces available, which you can use to apply statistics, machine learning or other R applications on web APIs.  It is a fundamental building block for a lot of my projects.

The VM image is here. [940.39MB]

To use, follow these steps:

Downloading the instance and uploading to your project

  1. Create your own Google Cloud Compute project if you haven't one already.
  2. Put in billing details.  Here are the prices you'll pay for running the machine. Its usually under $10 a month.
  3. Download the image from the link above (and here) and then upload it to your own project's Cloud Storage. Details here
  4. Add the uploaded image to your project with a nice name that is only lowercase, numbers or includes hyphens (-).  Details here. You can do this using gcloud and typing: 
$ gcloud compute images create IMAGE_NAME --source-uri URI

Creating the new Instance

  1. Now go to Google Compute Engine, and select Create New Instance
  2. Select the zone, machine type you want (i.e. you can select a 50GB RAM machine if needed for big jobs temporarily)
  3. In the dropdown for images you should be able to see the image from step 4 above.  Here is a screenshot of how it should look, I called my image "r-studio-opencpu20140628"

Or, if you prefer using command line, you can do the steps above in one command with gcloud like this:

$ gcloud compute instances create INSTANCE [INSTANCE ...] --image IMAGE

Using your instance

You should now have RStudio running on http://your-ip-address/rstudio/ and openCPU running on http://your-ip-address/ocpu/test and a welcome homepage running at the root http://your-ip-address

To login, your Google username is an admin as you created the Google cloud project. See here for adding users to Google Cloud projects

If you don't know your username, try this command using gcloud to see your user details:

$ gcloud auth login

Any users you add to Debian running on the instance will have a user in RStudio - to log into Debian and add new users, see below:

$ ## ssh into the running instance
$ gcloud compute ssh <your-username>@new-instance-name
$ #### It should now tell you that you are logged into your instance #####
$ #### Once logged in, add a user: example with jsmith
$ sudo useradd jsmith
$ sudo passwd jsmith
$ ## give the new user a directory and change ownership to them
$ sudo mkdir /home/jsmith $ sudo chown jsmith:users /home/jsmith

Oscar in the comments below also explains why sometimes your username may not work:

Like other comments, my username did not work.

Rather than creating a new user, you may need to simply add a password to your user account:

$ sudo passwd .

Also, the username will be your email address with the '.' replaced with '_'. So xx.yy@gmail.com became xx_yy

You may also want to remove my default user the image comes with:

$ sudo userdel markedmondson

...and remove my folder:

$ sudo rm -rf /home/markedmondson

The configuration used

If you would like to look before you leap, or prefer to install this yourself, a recipe is below. It largely cobbles together the instructions around the web supplied by these sources:

Many thanks to them.

It covers installation on the Debian Wheezy images available on GCE, with the necessary backports: