Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Morphing GA into an Affiliate Analytics Monster

923 views

Published on

How to hack GA's native campaign tracking, leverage 1st party cookie power and align GA's sessionisation logic more closely with 30 day affiliate systems.

Published in: Data & Analytics
  • Be the first to comment

Morphing GA into an Affiliate Analytics Monster

  1. 1. Morphing GA into an Affiliate Analytics Monster By Phil Pearce #MeasureCamp @PHILPEARCE London 25th March 2017
  2. 2. Warning / Disclaimer 1. GA is design for audience measurement (not affiliates tracking) 2. Run this on a parallel GA account (not your main GA account) as it will report very different numbers and use _ga2 cookie. 3. This is not a simple process…
  3. 3. Pls Download and import this GTM file: bit.ly/affiliatemonsterdownload Or use this generic login: username: coolgtmstuff@gmail.com password: philrulesgtm7 Select "Affiliate Monster container" Working Demo
  4. 4. …but, I like to push the boundaries of what`s possible (with GA)…
  5. 5. …and I`m a slightly Mad Analytics Scientist!
  6. 6. Note: It has taken lots of <body>s to get to this point…
  7. 7. GTM <body>`s from the past...
  8. 8. But it worked! and… the data came alive :)
  9. 9. Before vs After
  10. 10. Agenda
  11. 11. Agenda 1. Define the problem – Business Alignment (custom business logic in affiliate industry) – 1st party vs 3rd party cookies – GA is whitelisted on Adblocker plus – Existing affiliateId=123 params ignored by GA (and utm_id not used by affiliates) 2. Solution – Mapping affiliateId to utm_id – Overwriting setLocation & setReferral – DimensionWidening via CSV upload of affiliateId >> source/medium/campaign 3. Learnings/Mistakes – Enabling utm campaign cookie to prevent session reset on 2nd page – Accounting for #utm vs ?utm 4. Future improvements – Organic and Social organic cookie – Cross-domain tracking of source and affiliateId (#_ga=xxx.xxx pigybacking) – GoogleSheet for affiliateId DimensionWidening 5. Questions
  12. 12. This is the story of one such mad Analytics Experiment…
  13. 13. So, new super-affiliate client just signed! • GA classic >> GA universal migration via GTM • 5 CMS environments (Desktop, New Mobile, Old mobile site, Tablet, Campaign Site) • utm tags only used on email and banners • Affiliates 90% of traffic but missing utm tags. Hence, Direct was 80% of traffic! • Marketing Channel Analysis not possible in GA!!
  14. 14. Source: builtwith.com/detailed/behemothclient.com 5 CMS platforms: Desktop, New Mobile, Old mobile site, Tablet and Campaign Site. Cleaning & Standardise Equipment before the big operation
  15. 15. Testing on Mice 1. Parallel Tracker 2. Unit Tests & Sinario Tests 3. Query Time utm_id widening
  16. 16. Alive indefinitely Unit Test / Mice Test Code Refinements 1 day Live test Standardise GTM SetupAffiliate Monster Project Timeline 3 months bring the beast to life
  17. 17. In Reality… It was really hard! Insert Picture of - Phil with no hair and - lots of dead mice
  18. 18. But we did get there :) But about those dead mice…
  19. 19. Why not use native GA? 1. setSource utm field (rather than setLocation) 2. Custom Multi-channel funnels 3. BigQuery sessionisation [GA Prem. feature] 4. GA 6 mth sessions setting changed to 30days 5. utm_nooveride=1 not used
  20. 20. Recipe for a Affiliate Monster 1. Have GTM on all pages 2. Declare affiliateTracker name 3. Declare ga2 object 4. Declare ga2 cookie 5. setLocation override in pageview 6. setReferral override in pageview 7. Be on SSL (or enable meta always send referral)
  21. 21. Mistakes to Avoid 1. cleaning/removing existing utm params 2. Accounting for the order of params 3. #utm vs ?utm or both 4. removing double-quotes 5. JS logic: gclid/dclid >> utm >> affiliateId >> organic >> social referral >> referral
  22. 22. Pls Download and import this GTM file: bit.ly/affiliatemonsterdownload Or use this generic login: username: coolgtmstuff@gmail.com password: philrulesgtm7 Select "Affiliate Monster container" Working Demo
  23. 23. part1: jsv_pageHostnameTLD function(){ var domain={{Page Hostname - www removed}}; var rootDomain = undefined; if (domain) { domain.toLowerCase(); } if (domain.substring(0,4)=="www.") { domain=domain.substring(4,domain.length); } var domParts = domain.split('.'); for(var i=1;i<=domParts.length;i++) { document.cookie="gtmtestcookie1=1; path=/; domain="+domParts.slice(i*-1).join('.'); if(document.cookie.indexOf("gtmtestcookie1") != -1){ var rootDomain = domParts.slice(i*-1).join('.'); document.cookie="gtmtestcookie1=1; expires=Thu, 01 Jan 1970 00:00:01 GMT; path=/; domain="+domParts.slice(i*-1).join('.'); break; } } return rootDomain; }
  24. 24. part2: setCookie for utm_id setTrackingSessionCookie <script> function setTrackingSessionCookie(trackingCookieName, cookieValue, cookieDaysDuration) { var pageHostnameTLD = {{jsv_pageHostnameTLD}}; var cookieExpires = ""; if (cookieDaysDuration) { var date = new Date(); date.setTime(date.getTime() + (cookieDaysDuration *24*60*60*1000) ); cookieExpires = "; expires=" + date.toGMTString(); // If not provided, it will be a session cookie. } // Session SetCookie if (trackingCookieName && cookieValue) { document.cookie = trackingCookieName + '=' + cookieValue + cookieExpires + '; domain=' + pageHostnameTLD + '; path=/'; } }; // Set Based on URL or URL Hash setTrackingSessionCookie("gclid", {{Page URL Query tracking gclid}} , "30"); setTrackingSessionCookie("dclid", {{Page URL Query tracking dclid}} , "30"); setTrackingSessionCookie("utm_id", {{Page URL Query tracking utm_id}} , "30"); setTrackingSessionCookie("utm_source", {{Page URL Query tracking utm_source}} , "30"); setTrackingSessionCookie("utm_medium", {{Page URL Query tracking utm_medium}} , "30"); setTrackingSessionCookie("utm_campaign", {{Page URL Query tracking utm_campaign}} , "30"); setTrackingSessionCookie("utm_content", {{Page URL Query tracking utm_content}} , "30"); setTrackingSessionCookie("utm_keyword", {{Page URL Query tracking utm_keyword}} , "30"); setTrackingSessionCookie("utm_userid", {{Page URL Query tracking utm_userid}} , "30"); </script>
  25. 25. part3: setLocation <script> function setTrackingLocation() { var pageProtocol = {{Page URL Protocol}}; var pageHostname = {{Page Hostname}}; var pagePath = {{Page Path}}; var pageQuery = {{Page URL Query}}; var referrerHostname = {{Referrer Hostname - www removed}}; var countryCode = {{Lookup CountryCode from Country1 - PP reminder to check DE SH or DESH or SH}}; var deviceType = {{Lookup bespokeDeviceCategory from ContainerID}}; var cookieGoogleClickid = {{cookie gclid}}; var cookieDoubleClickId = {{cookie dclid}}; var cookieUtmId = {{cookie utm_id}}; var cookieUtmSource = {{cookie utm_source}}; var cookieUtmMedium = {{cookie utm_medium}}; var cookieUtmCampaign = {{cookie utm_campaign}}; var cookieUtmContent = {{cookie utm_content}}; var cookieUtmKeyword = {{cookie utm_keyword}}; var cookieAffiliateId = {{cookie affiliateId}}; var cookieIsLandingPageHit = {{cookie session gtm_isLandingPageHit}}; cookieIsLandingPageHit = ( cookieIsLandingPageHit == undefined ) ? "true" : "false"; // 0. Remove double-quote within utm tags... ""textlink"/adcash" to "textlink/adcash" // 0. Change undefined to empty string so no risk of "utm_source=undefined" pageQuery = (typeof pageQuery !== 'undefined') ? pageQuery.replace(/["]+/g, '') : ""; cookieAffiliateId = (typeof cookieAffiliateId !== 'undefined') ? cookieAffiliateId.replace(/["]+/g, '') : ""; cookieUtmId = (typeof cookieUtmId !== 'undefined') ? cookieUtmId.replace(/["]+/g, '') : ""; cookieUtmSource = (typeof cookieUtmSource !== 'undefined') ? cookieUtmSource.replace(/["]+/g, '') : ""; cookieUtmMedium = (typeof cookieUtmMedium !== 'undefined') ? cookieUtmMedium.replace(/["]+/g, '') : ""; cookieUtmCampaign = (typeof cookieUtmCampaign !== 'undefined') ? cookieUtmCampaign.replace(/["]+/g, '') : ""; cookieUtmContent = (typeof cookieUtmContent !== 'undefined') ? cookieUtmContent.replace(/["]+/g, '') : ""; cookieUtmKeyword = (typeof cookieUtmKeyword !== 'undefined') ? cookieUtmKeyword.replace(/["]+/g, '') : "";
  26. 26. Part4: isLandingPage cookie check
  27. 27. part5: isLandingPageHit function() { return function() { setTrackingSessionCookie("gtm_isLandingPageHit", "false"); } }
  28. 28. Part5: Bring it all together Scripts activated here {{jsv_setLandingPageHit - TRUE}}
  29. 29. Wins 1. No need to email 1000 Affiliates to re-tag links! 2. No IT dept involvement (all done in GTM) 3. Better cookie retention vs Affiliate cookies (esp. on Safari) 4. Better internal trust & actionability in GA data 5. Free!
  30. 30. Next iteration 1. Engagement scoring per AffilaiteID 2. utilise affiliateId/gaClientId cross-domain tracking and better affiliateId retention 3. CRM integration (similar to utmz method) 4. MeasurementProtocol 4 qualified affiliate sales 5. utm_userid respawn on mailchimp email
  31. 31. Questions & Prizes Phil Pearce Senior Web Analyst and GTM specialist phildpearce@gmail.com linkedin.com/in/philpearce Web Analytics Exchange mentor 750 GA questions answered Tracking protection group Free Prize for the best question(s).
  32. 32. bit.ly/gtmdevguide2 (free) Prize: GTM developer guide free!! bit.ly/gtmdevguide2

×