6

I would like to get a callback each time Google Analytics sends data to the server. I would like also to send the same data to my server. Is it possible and if so, how?

https://jsfiddle.net/bk1j8u7o/2/

<script async src="https://www.googletagmanager.com/gtag/js?id=UA-143361924-1"></script>
<script>
  window.dataLayer = window.dataLayer || [];
  function gtag(){dataLayer.push(arguments);}
  gtag('js', new Date());

  gtag('config', 'UA-143361924-1');
</script>
CertainPerformance
  • 356,069
  • 52
  • 309
  • 320
SexyMF
  • 10,657
  • 33
  • 102
  • 206
  • You could consider using a serviceworker. You should be able to intercept GA network requests (probably POST), and respond as you wish. I would advise checking GA terms and conditions before doing this. – ecc521 Jul 09 '19 at 16:33

3 Answers3

5

Google is actually using gif to sync the data to its server, so intercepting the XHR requests wont work.

In analytics.js there is an official way to do that. via Tasks, here is some small untested example:

ga(function(tracker) {
    var originalSendHitTask = tracker.get('sendHitTask');
    tracker.set('sendHitTask', function(model) {
        var payLoad = model.get('hitPayload');
        originalSendHitTask(model);
        var gifRequest = new XMLHttpRequest();
        var gifPath = "http://localhost/collect";
        gifRequest.open('get', gifPath + '?' + payLoad, true);
        gifRequest.send();
    });
});

make sure that the pageView is sent after this code is executed.

Avi Fatal
  • 1,550
  • 8
  • 8
2

I would demonstrate how you can intercept any AJAX call. Taking from this generic solution, you can filter the GA requests and take the actions you want.

I modified this answer.

The idea behind this solution is modifying the open and send prototype methods of XMLHttpRequest object and do the interception there. The IIFE gets the XMLHttpRequest object, saves the original prototype methods, install new methods and call the original methods from within the new methods. And, of course, do what you want with the data in the mean time.

(function(XHR) {

    //Save the original methods
    var open = XHR.prototype.open;
    var send = XHR.prototype.send;


    //Hook new open method in order to get the url    
    XHR.prototype.open = function(method, url, async, user, pass) {
        this._url = url;

        //Call the original
        open.call(this, method, url, async, user, pass);
    };


    //Hook here too. This will be executed just before the data is sent
    XHR.prototype.send = function(data) {

        if (this_url === GA_URL_CONST)     //Symbolic const  
             SendDataToMyServer(data);     //Symbolic Fn  


        //Call the original
        send.call(this, data);
    }
})(XMLHttpRequest);
Charlie
  • 22,886
  • 11
  • 59
  • 90
  • Please do it in my jsfiddle. As far as i know, its not working in for ga – SexyMF Jul 12 '19 at 07:42
  • 1
    This will not work because Analytics is not limited to using XHR for event reporting. The [transport method](https://developers.google.com/analytics/devguides/collection/analyticsjs/field-reference#transport) (image, beacon, XHR) is selected automatically by default but I believe that tracking pixels (image load requests) are used most frequently. – Petr Srníček Jul 15 '19 at 09:49
1

Possible? Yes, practical? No. Take a look of what the BigQuery schema for GA looks like and you'll get a sense of the complexity that goes behind the scenes.

That said, I think what you COULD do is:

  1. Use GTM to implement GA.
  2. Set up a custom tag template to refer to your own server that will collect the information. Passing just the data that you need, instead of everything GA collects.
  3. Trigger your new custom tags wherever you're triggering your GA tags.
XTOTHEL
  • 5,098
  • 1
  • 9
  • 17