I am trying to post an event to google analytics using Measurement Protocol from my Google App Engine (Java) web app.
I have tested the URL by submitting the URL directly, and it immediately shows up (realtime) in Google Analytics. But when I try to post it in the app nothing shows up.
So I assumed to start with my Java code was flawed (perhaps was), so I replaced my code with Google's example code to integrate from Google App Engine to Google Analytics here. I changed it a bit, but here are the key bits...
private static final URL GA_URL_ENDPOINT = getGoogleAnalyticsEndpoint();
private static URL getGoogleAnalyticsEndpoint() {
try {
return new URL("http", "www.google-analytics.com", "/collect");
} catch (MalformedURLException e) {
throw new RuntimeException(e);
}
}
public boolean trackEvent(
String category, String action, String label, String value) {
try {
Map<String, String> map = new LinkedHashMap<>();
map.put("v", "1"); // Version.
map.put("tid", gaTrackingId);
map.put("cid", "555");
map.put("t", "event"); // Event hit type.
map.put("ec", encode(category, true));
map.put("ea", encode(action, true));
map.put("el", encode(label, false));
map.put("ev", encode(value, false));
HTTPRequest request = new HTTPRequest(GA_URL_ENDPOINT, HTTPMethod.POST);
request.addHeader(CONTENT_TYPE_HEADER);
request.setPayload(getPostData(map));
HTTPResponse httpResponse = urlFetchService.fetch(request);
// Return True if the call was successful.
log.info("Response code for GA event is: " + httpResponse.getResponseCode());
return httpResponse.getResponseCode() >= 200;
} catch ( Exception e ) {
//HANDLE EXCEPTION
return false;
}
}
private static byte[] getPostData(Map<String, String> map) {
StringBuilder sb = new StringBuilder();
for (Map.Entry<String, String> entry : map.entrySet()) {
sb.append(entry.getKey());
sb.append('=');
sb.append(entry.getValue());
sb.append('&');
}
if (sb.length() > 0) {
sb.setLength(sb.length() - 1); // Remove the trailing &.
}
log.info("GA event string is: " + sb.toString());
return sb.toString().getBytes(StandardCharsets.UTF_8);
}
private static String encode(String value, boolean required)
throws UnsupportedEncodingException {
if (value == null) {
if (required) {
throw new IllegalArgumentException("Required parameter not set.");
}
return "";
}
return URLEncoder.encode(value, StandardCharsets.UTF_8.name());
}
When this bit of code is called, I get the parameter string out of my log file:
v=1&tid=UA-XXXXXXXX-1&cid=555&t=event&ec=settings&ea=autopost-on&el=rkAutoPost&ev=5
I also see that I get a 2xx response code from the call to google. But nothing shows up in GA interface (realtime or otherwise).
So then I try just doing a GET from inside my browser...
http://www.google-analytics.com/collect?v=1&tid=UA-XXXXXXXX-1&cid=555&t=event&ec=settings&ea=autopost-on&el=rkAutoPost&ev=5
... and that immediately hits GA realtime. So this tells me it isn't a problem with the content of the message.
Note I also created a brand new clean view to make sure nothing was being filtered out... did't help.
Any ideas please? Thank you!
TL:DR; GA filters events from GAE via the User Agent
request header. Override the User Agent
via the measurement protocol's ua
parameter.
Google Analytics (GA) is filtering Google App Engine (GAE) traffic based on the User Agent
header containing the string "AppEngine-Google; (+http://code.google.com/appengine; appid: APPID)"
. I attempted to set the User Agent
to a custom string, though as stated here, GAE appends the aforementioned string to any custom User Agent
string and that is enough for GA to filter the events.
It is suggested in other answers that updating the view settings by unchecking the "Exclude all hits from known bots and spiders" Bot Filtering option would permit events from GAE though this did not work for me. Filtering bot traffic seems useful anyways so I wasn't too eager to uncheck this option anyways.
The solution was to override the User Agent
via the measurement protocol's ua
option which is not updated by GAE. The resulting parameter string from the example provided in the question would then be :
v=1&t=event&tid=UA-XXXXXXXX-1&cid=555&ec=settings&ea=autopost-on&el=rkAutoPost&ev=5&ua=Custom%20User%20Agent
Where my ua
parameter is set to Custom User Agent
.
Hope this saves someone some time in the future :)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With