Campaign parameters/tracking with Google Analytics (Universal) in a Facebook App Page

This is a follow-up post where I was explaining how to set/override GA campaign variables programmatically with JS.

The unique element of this problem is that all query string parameters are not passed along to your application’s iframe, so by default, we cannot use UTM campaign parameters. Otherwise stated: when GA campaign parameters are passed into your Facebook Page Tab URL, it will simply disregard it.

With some additional modifications, and understanding what parameters Facebook does pass in we are able to work around these limitations to get accurate campaign tracking.

The general idea is:

  1. Pass in a specific string that represents an “encoded” utm parameter string
  2. Use Facebook’s app_data parameter to pass in this specially encoded string
  3. Parse out the string in your application (server-side code)
  4. Take the extracted values and put them in your JS calls to “set” the campaign variables in GA

To further preface my solution, some general assumptions I am making/accounting for are:

  1. I want to ensure that many parameters can be passed in via app_data and not just our GA campaign params.
  2. The pipe (|) and double-pipe (||) chars are “reserved”. These are being used as delimiters in the app_data string to separate “main and sub-vars”.
  3. At various stages of the script, I am replacing the pipe chars with ampersands so I can simulate the creation of a query string and to leverage a native PHP function that parses this format
  4. There are alternative ways that I can structure my query strings for easier consumption, but I prefer this delimiter approach as it closely resembles the universal query string format.

The final url will look something like: https://www.facebook.com/pages/pagename?id=xxxxxxxx&sk=app_xxxxxxxxxxx&app_data=ga=utm_source=googly|utm_medium=hobo|utm_campaign=gdcampaign||otherparams=youdontwanttodisturb

Face book will take the app_data parameters and pass in in as a string. So the string we are eventually working with is: ga=utm_source=googly|utm_medium=hobo|utm_campaign=gdcampaign||otherparams=youdontwanttodisturb

In the first stage of parsing, you’ll have access to the “ga” along with the “otherparams” , but our main concern for now is the “ga” key – the second parameter was simply for demonstrative purposes on how to append other variables that are useful to your application.

Onto the commented code which should explain the rest of the technique:

  1. <?php
  2. #ensure the facebook SDK is loaded
  3. require '../vendor/facebook/php-sdk/src/facebook.php';
  4. $config = array(
  5. 'appId' => 'xxxxxxxx',
  6. 'secret' => 'xxxxxxxxxxxxxxxxxxxxxx',
  7. 'allowSignedRequest' => true
  8. );
  9. $facebook = new Facebook($config);
  10. #get the signed request
  11. $sr = $facebook->getSignedRequest();
  12.  
  13. #if the signed request exists and has some app_data start parsing
  14. if(isset($sr['app_data'])){
  15. #expects a "pseudo querystring" of the format:
  16. #ga=utm_source=google|utm_medium=cpc|utm_campaign=grandcampaign||otherparams=youdontwanttodisturb
  17. #notice that the above string separates other values with double pipes || so you can have many querystring vars and not just GA
  18. #individual variables within each "key-value" are separated by single pipes |
  19.  
  20. #replace the double pipes with an apersand - prepare the string for parsing
  21. $appdata = str_replace("||", "&", $sr['app_data']);
  22. #parse the querystring
  23. parse_str($appdata, $param_arr);
  24.  
  25. if(isset($param_arr['ga'])){
  26. #replace the single pipes with an apersand - prepare the string for parsing
  27. $ga_params = str_replace("|", "&", $param_arr['ga']);
  28. #parse the querystring
  29. parse_str($ga_params, $ga_param_arr);
  30. #escape the string values and prepare them for JS output
  31. $clean_ga_params = array_map("json_encode", $ga_param_arr);
  32.  
  33. #set some defaults and merge it with the ga params found. Just want to ensure all values exist in the array;
  34. $defaults = array("utm_source" => "", "utm_campaign" => "", "utm_medium" => "");
  35. $clean_ga_params = array_merge($defaults, $clean_ga_params);
  36. }
  37. }
  38.  
  39. ?>
JS Source   
  1. (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
  2. (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
  3. m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
  4. })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
  5.  
  6. ga('create', 'UA-xxxxxxxx-x');
  7. <?php if(isset($clean_ga_params)) : ?>
  8. ga('set', 'campaignName', <?php echo $clean_ga_params['utm_campaign'] ?>);
  9. ga('set', 'campaignSource', <?php echo $clean_ga_params['utm_source'] ?>);
  10. ga('set', 'campaignMedium', <?php echo $clean_ga_params['utm_medium'] ?>);
  11. <?php endif; ?>
  12. ga('send', 'pageview');
  13.  
  14. </script>

References: https://developers.facebook.com/docs/reference/login/signed-request/

Leave a Reply

Your email address will not be published.