mardi 31 janvier 2017

Add Google analytics to SharePoint online, display view count on page


From masterpage add this code to enable user navigation, just before body tag close

 <SharePoint:ScriptLink ID="ScriptLink52"  Name="~SiteCollection/Style Library/Scripts/GoogleAnalyticsInclude.js" runat="server"/>  
</body>
</SharePoint:SPHtmlTag> 

With GoogleAnalyticsInlude.js code:
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
 
//Code generated from Google analytics home page
ga('create', 'UA-XXXXXX-1', 'auto');
//From /sites/mykiosk/fr/.... to  /fr/....
var page = document.location.pathname.substring(14);

// Sets the page value on the tracker.
ga('set', 'page', page);
// Sending the pageview no longer requires passing the page
// value since it's now stored on the tracker object.
ga('send', 'pageview');


to register Google Tag, get ID for console.google.com

       
$(document).ready(function () {

    GetViewCount();

 //Add onclick function for navigation link
        $('.ms-navedit-linkNode').click(function() 
 {
  //click on link
  if($(this)[0] !=null)
  {
   //for external link open in new windows.
   if($(this)[0].classList.contains("new-window"))
   {
    trackOutboundLink($(this).attr('href'));
   }else
   {
    trackOutboundLinkCurrent($(this).attr('href'));
   }
  }else
  {
   trackOutboundLinkCurrent($(this).attr('href'));
  }
     return false;
 });
});

//click event for current site
function trackOutboundLinkCurrent(url) {
   ga('send', 'event', 'outbound', 'click', url, {
  'transport': 'beacon',
  'hitCallback': function(){window.location.href = url;}
   });
}

//click event for different site open new windows.
var trackOutboundLink = function(url) {
   ga('send', 'event', 'outbound', 'click', url, {
  'transport': 'beacon',
  'hitCallback': function(){window.open(url);}
   });
}
 


To get view count for a page use following code, replace email for service account, and JSON private key generated.


 /* View function */
function GetViewCount() {
    if (!g_disableCheckoutInEditMode) {
        if ($("span.ViewSpan") != null) {
        
          var pHeader = {"alg":"RS256","typ":"JWT"};
   var sHeader = JSON.stringify(pHeader);
  
   var pClaim = {};
   pClaim.aud = "https://www.googleapis.com/oauth2/v3/token";
   pClaim.scope = "https://www.googleapis.com/auth/analytics.readonly";
   //Service account email
   pClaim.iss = "XXXXXXXX@XXXXXXX.iam.gserviceaccount.com";
   pClaim.exp = KJUR.jws.IntDate.get("now + 1hour");
   pClaim.iat = KJUR.jws.IntDate.get("now");
  
   var sClaim = JSON.stringify(pClaim);
   
   //Replace with JSON private key generated from console.google.com
   var key = "-----BEGIN PRIVATE KEY-----\nMIIEv8T5rEa0e4AwD6vVWedrwitcIrF3gxpTKjH4zyP6ODUd1LKYI8IJDe+evK0C4SIMqk6otzU27F8X\npCY6RnsWL6v2Qx9WutzrRfG1/SmlJhMNPg9nkKv79dt9AX6qLUQNxS6lSuPWSSDW\n9H7cUF2NT+QbEZn4Ot5GHRR5a/y7Wpeg/aOhHB70kQKBgQD2NfHYWuIH76wpNLnR\nCVw2VOnRWSaX50DF+0AuGyNab660T8e7rFUSM7+VHwn5gMqNdhU3Ic/eH26/vkLo\nbrQou1ZXR9oHm2ls+S7hT+dS5ff2SdkeaE4+qtRW9hbAozS0SCBtQ1WofaJ0s8ni\n4td+6EAjkIUnbJ5tQyKVHeNSzwKBgQDoaBYUl+1AUK0pgXzwLtpDb5hSuEoGQrqy\nC/QNdOEVtsic6nrgJBaxNe3wHV/X7/AyuD6zA0VOCQp446SJa9815McOiCC+uh0j\nDolYYuXXmKDt7hylI9DYUusFMMrnCae4GpMJSSIZILxcCR2cbf0GZYgdM7DKj8fz\nERmBWTW4rQKBgQCNBvs/ZVdhGlyvwZ7J6KWkDWFc48bibbjBbpglkK/gZmZYq/YJ\nPr3/zhpn7T6GZsoe20ttp/VsEu8Z735dqsORLTVYizSM9O0fWWAL+PvUlRtCPKyb\n6T0gUjOMmCsSLqnKtiG01EPlXglG9ZCnYC31aE0M0gQjP+lDRpgxd8w1KwKBgQDM\njSAyC+4jl15xk6i1dWdhx0zYMZ/llsHfh6nMVjzt8azsf2ya7uiSHJdJqXD8DBDr\nc0KsKIrNPiPbdvEQisMxGiUhYyr+86xFeLvl8VW+xnWONO89YiKk44Y7UVCkvNjD\nr5AOsjGy0B85GkTXs+7pvF9q5F4MSzR/eWNrd2tTGQKBgQCZlS7+40V+9r+sbJcS\nDYBDAFqPSe8prjmA5lqFUPPLMjM1/sTR/yrdtBnw34UIB5xtniwT128tV7RLMO9k\njwMJ9QWsUIs7udg2eszwO4DFGMfa6FvU+2/CLOZvsm0CdC68W+muniJzUb103S98\nVl5xm7BTsfKjgmcdyrPPtEKfkg==\n-----END PRIVATE KEY-----\n";
   var sJWS = KJUR.jws.JWS.sign(null, sHeader, sClaim, key);
   
   var XHR = new XMLHttpRequest();
   var urlEncodedData = "";
   var urlEncodedDataPairs = [];
  
   urlEncodedDataPairs.push(encodeURIComponent("grant_type") + '=' + encodeURIComponent("urn:ietf:params:oauth:grant-type:jwt-bearer"));
   urlEncodedDataPairs.push(encodeURIComponent("assertion") + '=' + encodeURIComponent(sJWS));
   urlEncodedData = urlEncodedDataPairs.join('&').replace(/%20/g, '+');
  
   // We define what will happen if the data are successfully sent
   XHR.addEventListener('load', function(event) {
    var response = JSON.parse(XHR.responseText);
    token = response["access_token"];
    
    var requestUrl = getGaUrl(token);
    
    jQuery.get( requestUrl, function( response ) { 
     var res = response;
     var nbView="";
     if(response.totalsForAllResults != null)
     {
      nbView = response.totalsForAllResults['ga:pageviews'];
     }
     else
     {
      nbView = "0";
     }
     //alert(nbView);
     ChangeViewsText(nbView);
     // response contains site information
    } );
   });
  
   // We define what will happen in case of error
   XHR.addEventListener('error', function(event) {
    console.log('Oops! Something went wrong.');
   });
  
   XHR.open('POST', 'https://www.googleapis.com/oauth2/v3/token');
   XHR.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
   XHR.send(urlEncodedData);
        }
    }
}

function ChangeViewsText(count) {
    count = count.concat(" ").concat(Resource_Views);
    
    $(".ViewSpan").html(count);
}


function getGaUrl(token)
{
  var page = document.location.pathname.substring(14);
 var ga = "138991135";
 
 var comma = page.indexOf(",");
 if(comma >1)
 {
  page = page.substring(0,comma);
 }
 
 var pathName = "~".concat(page);// "~/fr/*"
 var res = "https://www.googleapis.com/analytics/v3/data/ga?ids=ga:".concat(ga);
 res = res.concat("&start-date=2007-01-01&end-date=yesterday&metrics=ga:pageviews&filters=ga:pagePath=");
 res = res.concat(pathName);
 res = res.concat("&access_token=");
 res = res.concat(token);
 res= encodeURI(res);
 return res;
 }
/* End View function */




For file dependencies

<SharePoint:ScriptLink ID="ScriptLink24"  Name="~SiteCollection/Style Library/Scripts/GoogleAnalyticsClient.js" runat="server"/>
<SharePoint:ScriptLink ID="ScriptLink21"  Name="~SiteCollection/Style Library/Scripts/json-sans-eval-min.js" runat="server"/>
<SharePoint:ScriptLink ID="ScriptLink22"  Name="~SiteCollection/Style Library/Scripts/jsrsasign-latest-all-min.js" runat="server"/>
<SharePoint:ScriptLink ID="ScriptLink23"  Name="~SiteCollection/Style Library/Scripts/jws-3.2.js" runat="server"/> 

All files available here :  https://1drv.ms/f/s!Au96h_Mp38velaQHd82OPH8B-QT0zA