I want to track clicks with google analytics. Is there any tutorial for this?
I use the following jQuery code to add event tracking, assuming, that all external links begin with http://:
$(document).ready(function() {
$("a[#href^='http://']:not(.internal)").addClass("external").bind('click keypress', function(event) {
var code=event.charCode || event.keyCode;
if(!code || (code && code == 13)) {
if(pageTracker){
pageTracker._trackEvent('outgoing', 'click', this.href);
};
};
});
GA doesn't auto-track external links, so you have manually call one of its functions on all your exit links. You can track it as a virtual page view or as a custom variable or event, passing the relevant information you want to track, to the GA functions (like the exit link url).
Depending on how your links are setup, you can easily setup an click event listener to trigger the GA function call. For example, if all of the exit links have a specific css class attribute associated with them then you can hook the click event to that.
If all of your exit links point to your php script and only pass an ID number to it or something (no actual exit url), then you will not be able to pass to GA the exit link url. If you are fine with just passing the ID then you can use that instead of the url and pass as the virtual url or custom variable value "/exit/[id]" or whatever else makes sense to you. And you can also look for the php script's url as a way to hook the click event to all your exit links, if there is no other unique identifier.
If none of this is an option and you have to do it server-side...then you're kind of out of luck on doing it the "easy" way. GA has an API for interacting with it via server-side code but it's only 1-way. You can use it to get information out of GA but you can't use it to put information into it.
However, what you CAN do is...when a request to GA is made, take a look at that request in Firebug > NET tab or in Charles Proxy or some other request sniffer program, or take a look at the GA's url in its noscript tag. The way it works is a request is made to the GA server and variables and values are appended to the url as a query string.
So what you can do is build a url like that and use cURL to make a request to the GA server...but here's the tricky part: you have to fool GA into thinking the request was made from a browser, not your server. So you need to make sure you send header information with the cURL request to make it look like a browser made the request. Ideally you will want to use whatever header information was sent to your server from the client so that GA can record the hit as if it were the user, so that reports can populate accordingly.
You could send the requests to your server, and your server could send the user a 301 redirect.
Your could then do server-side google analytics, by sending requests to http://www.google-analytics.com/utm.gif to google, like this project does: http://code.google.com/p/php-ga/
You can use this jQuery library to help with sending click events to GA:
https://github.com/spilliton/track_that
Related
I am trying to remove Personally Identifiable Information (PII) from URLs in out Single Page Application (SPA) registered by Google Tag Manager.
The URLs have the form /customer/1234/invoice/5678, which I want to send to GA4 as /customer/(redacted)/invoice/(redacted)
What I did is the following:
In GTM, I created a Custom JavaScript variable called Page location without ids with the following content. (Note: using {{Page URL}} here, but also tried window.location.href with same effect.)
function() {
// including timestamp for debugging purposes
var url = Date.now() + {{Page URL}}.replace(/\d{4}/g, '(redacted)');
// outputting to console for debugging purposes
console.log(url);
return url;
}
In the GA4 configuration tag (which is fired on All Pages), I opened Fields to set and changed the field name page_location to {{Page location without ids}}.
I started Preview in GTM, and let GTM load the website. Tag Assistant comes up on the page, GTM reports it is connected.
Everything seems well so far:
I open the developer console on the website, and see some 20 output lines of the start page URL with timestamp, generated by my GTM script.
In GTM's Tag Assistant I can see the modified URL in both the GTM and GA4 containers, under Variables. (In the GTM container assigned to Page location without ids, in the GA4 container assigned to dl (Page Location).
In GA4, I can see the modified URL in DebugView, assigned to the page_location Parameter.
However, when I navigate to a page with ids in the URL:
The console outputs the redacted URL, good. (4 times actually, don't know why.)
However, the payload of the collect call shows the (redacted) starting page URL for the dl parameter. The actual page URL (redacted or not) is not included.
GTM show a History event logged by the GTM container with the redacted URL in the Page location without ids variable, good. The Page Path and Page URL variables however are not redacted, don't know if this is good or bad.
GTM shows for the GA4 container a Page View with the (redacted) starting page URL for the dl (Page Location) parameter!
And also GA4 in DebugView shows the starting page URL as page_location parameter.
So for some reason I am unable to push the redacted URL into the dl parameter for GA4, instead GA4 keeps on using the redacted initial (starting page) URL.
Well, no, no need really. GA4 configuration+pageview tag only needs to be called once. After that, it starts watching history changes and tracks every pageview on most SPAs. You need to only use the real page view trigger and only add more if your SPA doesn't issue history changes on navigations. But vast majority of SPA engines don't make that mistake anymore.
You should actually try implementing it and then ask your question. Update your question when you encounter non-theoretical issues and we'll help.
Let's say i created a google sheet to capture user's email addresses.
On my website there is a small form and once the submit button is clicked and an ajax request to a google web app that writes data to a sheet is fired:
// Let's select and cache all the fields
var $inputs = $form.find("input, select, button, textarea");
// Serialize the data in the form
var serializedData = $form.serialize();
// Fire off the request
request = $.ajax({
url: https://script.google.com/macros/s/longURLcode/exec,
type: "post",
data: serializedData
});
In the google script you now use doPost(e) or doGet(e) to handle any incoming http request. To allow this to work as a sign up mechanism permissions for the web app have to be set to (i think !?)
Execute the app as: Me (myemail#gmail.com)
Who has access to the app: Anyone, even anonymous
Given everything on the google script site is set up properly, this works like a charm. So whats wrong?
Problem:
Anyone can either look into the source code of my webpage or use the dev tools to extract the url to the google web app after clicking submit. This url can now in theory be used to flood the sheet with countless (undefined) entries.
Questions:
1) Is there a way to limit accepted http request to certain origins? I tried to do this by accessing the http headers within doPost() but there seems to be no way to do so.
2) Is "Who has access to the app: Anyone, even anonymous" the wrong approach? I thought this is necessary since you can only choose google users here and some url (mywebsite.com) seemed to fall within the anonymous category.
3) I don't think this is possible but maybe i missed an option: Is there a way to NOT expose the google web app url to anyone? I guess not because you can monitor any requests with dev tools.
4) Is using sheets for capturing that kind of data just a terrible idea in general (partly for above reasons) and i should find another solution asap?
When I send a one-off document to RightSignature via their API, I'm specifying a callback location in the XML document as specified in RightSignature's schema definition. I then get a signer-link value back from their API for the document. I display the HTML response from the signer-link URL in an iFrame on our website. When our user signs the document in this iFrame, which is rendering the responses from their website, I want their website to post to our callback location.
Can I do this with the RightSignature API and does it make sense?
So far, I'm only getting content in the iFrame that indicates that the signing was successful. The callback location does not seem to be getting called.
I got it solved just now. Basically, i was doing two things wrong first you have to go in RightSignature Account and set it there the CallBack url
Account > Settings > Advanced Settings
But the thing which RS is unable to mention to us that this url can not be of localhost, but it should be of https i mean like Live URL of your site like
https://stagingmysite.azurewebsites.net/User/CallBackFunction
And then in your CallBack just write these two lines and you will receive complete XML which would have the GUID and document status as well.
byte[] data = Request.BinaryRead(Request.TotalBytes);
string callBackXML = System.Text.Encoding.UTF8.GetString(data);
I found the answer with some help from the API team at RightSignature. I was using callback_location but what I really wanted is redirect_location. Their online documentation was difficult to follow and did not clearly point out the difference.
I got this working after a lot of trial and error.
I have the Snowplow event tracker snippet included on my website using Google Tag Manager, and Snowplow events are indeed being sent as GET requests to the endpoint I've configured. Many of the params from the Snowplow tracker protocol are present in the requests. However, I used
window.snowplow('setUserId', 'XXXX');
in the Tag to set the uid param, but it doesn't appear in the request. How can I enable it?
The Snowplow documentation implies this event is included automatically.
Try Modify the name "snowplow_name_here" ,some words not working.
example, if your name , start with "option", don't work.
I have a special situation where the sites visitors can access the page from a certain domain but no others. So HTML and assets are no problem as long as they are stored on the server. Google Analytics on the other hand requires a download of analytics.js from Googles servers, which is impossible.
So I'm looking for a way to proxy this. The webserver itself has internet access and could relay the trafic. To report to Google about my page view, a single pixel GIF is downloaded from Google, described here: https://developers.google.com/analytics/resources/concepts/gaConceptsTrackingOverview
I think it would be kind of easy to get all the parameters in the GIF and use the measurement protocol to report to Google from the server - but the hard bit is to get all this info to the server. To download analytics.js and modify it to go to my own server seems to me as a hack that ain't future proof at all. To just get the current page from the user to the server is not a big deal, but we would like to get the user id, browser version and everything you get with Analytics.
How would you do it? Do you find a solution for this?
Update: Google has since released server-side GTM, which allows you to proxy requests and scripts through a custom domain. In most use cases I can imagine, this would be the much superior solution to a dyi proxy.
As pointed out in my comment the utm.gif is no longer used. Google Analytics has completely switched to the Measurement Protocol and data is now sent to the Endpoint for the Measurement Protocol at google-analytics.com/collect. Actually this still return a transparent pixel since calling an image with parameters is a probate way of transmitting informations across domain boundaries.
Now, you could just the Measurement Protocol to implement your own Google Analytics tracker.
To quote myself:
Each calls includes at least the ID of the account you want to send
data to, a client id that allows to group interactions into sessions
(so it should be unique per visitor, but it must not identify a user
personally), an interaction type (pageview, event, timing etc., some
interactions types require additional parameters) and the version of
the protocol you are using (at the moment there is only one version).
So the most basic example to record a pageview would look like this:
www.google-analytics.com/collect/v=1&tid=UA-XXXXY&cid=555&t=pageview&dp=%2Fmypage
You probably would want to add the users IP (will be anonymized automatically) and the user agent.
However it sounds like you prefer to use the standard Analytics code to collect the data and relay the tracking call via your own server. While I haven't used the following in production I don't see any reason why it wouldn't work.
First you need the analytics.js file. Self-hosting the file is discouraged, but the given reason is that the code is updated sometimes by Google and if you host it yourself you might miss the updates. This can be remedied by setting up a cron job that downloads the file regularly to your server so you always have a current version.
Next you'd adapt the GA bootstrap function to load the code from your own server:
(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','//www.myserver.com/analytics.js','ga');
Now you have the code, but the tracking call will still be sent to the Analytics Server (i.e. in your case it won't be sent at all). So you need to re-route the call via your server.
To make this possible the Google (Universal) Analytics Code has a feature called "tasks". Tasks are functions within the tracking code in which the tracking call is being assembled.
It is possible to modify tasks by using the "set" function of the tracker object, using the taskname as parameter and passing a function that overwrites/overloads the task function.
The following is pretty much the example from the Google documentation (except I omitted the part where data is still being sent to Google - you don't need this at this point):
ga('create', 'UA-XXXXX-Y', 'auto');
ga(function(tracker) {
tracker.set('sendHitTask', function(model) {
var payLoad = model.get('hitPayload');
var gifRequest = new XMLHttpRequest();
var gifPath = "/__ua.gif";
gifRequest.open('get', gifPath + '?' + payLoad, true);
gifRequest.send();
});
});
ga('send', 'pageview');
Now this sends the data to a file called __ua.gif at your own server (if you need to send data cross-domain you can simply do a var ua = new Image; ua.src = gifPath + '?' + payLoad to create an image request).
The model parameter to the sendHitTask-function contains (apart from a lot of overhead) the payload, that is the assembled query string that contains the analytics data. You can then make your _ua.gif a script that proxies the request to the google-analytics.com/collect.
At this point the user agent will be your script and the IP adress will be that of your server, so you need to include &uip (User IP override) and &ua (User agent override) parameters ( https://groups.google.com/forum/#!msg/google-analytics-measurement-protocol/8TAp7_I1uTk/KNjI5IGwT58J) to get geo and technical information.
If you are feeling more adventurous you can override the buildHitTask instead and try and add the additional parameters there (more hassle probably since you'd need to get the IP address from somewhere).
For additional parameter see the reference for analytics.js and the Measurement Protocol.