Skip to content

Instantly share code, notes, and snippets.

@ryanlunka
Last active December 13, 2015 21:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save ryanlunka/4978294 to your computer and use it in GitHub Desktop.
Save ryanlunka/4978294 to your computer and use it in GitHub Desktop.
This JSP can be included in CQ5 page components to integrate with Google Analytics for browsers that do not allow JavaScript. This code is modified from what Google provides (https://developers.google.com/analytics/devguides/collection/other/mobileWebsites) so that it can be used with Apache Sling. This script hasn't been tested with all Google …
<%@ page language="java"
import="java.io.ByteArrayOutputStream,
java.io.IOException,
java.io.OutputStream,
java.io.UnsupportedEncodingException,
java.math.BigInteger,
java.net.HttpURLConnection,
java.net.URLConnection,
java.net.URL,
java.net.URLEncoder,
java.net.URLDecoder,
java.security.MessageDigest,
java.security.NoSuchAlgorithmException,
javax.servlet.http.Cookie,
java.util.regex.Pattern,
java.util.regex.Matcher,
java.util.UUID" %><%!
private static final String GA_ACCOUNT = "MO-12345678-1"; // Google Analytics ID, with UA changed to MO.
// Tracker version.
private static final String version = "4.4sj";
private static final String COOKIE_NAME = "__utmmobile";
// The path the cookie will be available to, edit this to use a different
// cookie path.
private static final String COOKIE_PATH = "/";
// Two years in seconds.
private static final int COOKIE_USER_PERSISTENCE = 63072000;
// A string is empty in our terms, if it is null, empty or a dash.
private static boolean isEmpty(String in) {
return in == null || "-".equals(in) || "".equals(in);
}
// The last octect of the IP address is removed to anonymize the user.
private static String getIP(String remoteAddress) {
if (isEmpty(remoteAddress)) {
return "";
}
// Capture the first three octects of the IP address and replace the forth
// with 0, e.g. 124.455.3.123 becomes 124.455.3.0
String regex = "^([^.]+\\.[^.]+\\.[^.]+\\.).*";
Pattern getFirstBitOfIPAddress = Pattern.compile(regex);
Matcher m = getFirstBitOfIPAddress.matcher(remoteAddress);
if (m.matches()) {
return m.group(1) + "0";
}
else {
return "";
}
}
// Generate a visitor id for this hit.
// If there is a visitor id in the cookie, use that, otherwise
// use the guid if we have one, otherwise use a random number.
private static String getVisitorId(String guid, String account, String userAgent, Cookie cookie)
throws NoSuchAlgorithmException, UnsupportedEncodingException {
// If there is a value in the cookie, don't change it.
if (cookie != null && cookie.getValue() != null) {
return cookie.getValue();
}
String message;
if (!isEmpty(guid)) {
// Create the visitor id using the guid.
message = guid + account;
}
else {
// otherwise this is a new user, create a new random id.
message = userAgent + getRandomNumber() + UUID.randomUUID().toString();
}
MessageDigest m = MessageDigest.getInstance("MD5");
m.update(message.getBytes("UTF-8"), 0, message.length());
byte[] sum = m.digest();
BigInteger messageAsNumber = new BigInteger(1, sum);
String md5String = messageAsNumber.toString(16);
// Pad to make sure id is 32 characters long.
while (md5String.length() < 32) {
md5String = "0" + md5String;
}
return "0x" + md5String.substring(0, 16);
}
// Get a random number string.
private static String getRandomNumber() {
return Integer.toString((int) (Math.random() * 0x7fffffff));
}
// Track a page view, updates all the cookies and campaign tracker,
// makes a request to Google Analytics via a gif
private String trackPageView(HttpServletRequest request, HttpServletResponse response)
throws Exception {
String timeStamp = Long.toString(System.currentTimeMillis() / 1000);
String domainName = request.getServerName();
if (isEmpty(domainName)) {
domainName = "";
}
// Get the referrer from the utmr parameter, this is the referrer to the
// page that contains the tracking pixel, not the referrer for tracking
// pixel.
String documentReferer = request.getParameter("utmr");
if (isEmpty(documentReferer)) {
documentReferer = "-";
}
else {
documentReferer = URLDecoder.decode(documentReferer, "UTF-8");
}
String documentPath = "";
String query = request.getQueryString();
String path = request.getRequestURI();
if (path != null) {
if (query != null) {
path += "?" + query;
}
documentPath = URLEncoder.encode(path, "UTF-8");
}
if (isEmpty(documentPath)) {
documentPath = "";
}
else {
documentPath = URLDecoder.decode(documentPath, "UTF-8");
}
String account = GA_ACCOUNT;
String userAgent = request.getHeader("User-Agent");
if (isEmpty(userAgent)) {
userAgent = "";
}
// Try and get visitor cookie from the request.
Cookie[] cookies = request.getCookies();
Cookie cookie = null;
if (cookies != null) {
for(int i = 0; i < cookies.length; i++) {
if (cookies[i].getName().equals(COOKIE_NAME)) {
cookie = cookies[i];
}
}
}
String guidHeader = request.getHeader("X-DCMGUID");
if (isEmpty(guidHeader)) {
guidHeader = request.getHeader("X-UP-SUBNO");
}
if (isEmpty(guidHeader)) {
guidHeader = request.getHeader("X-JPHONE-UID");
}
if (isEmpty(guidHeader)) {
guidHeader = request.getHeader("X-EM-UID");
}
String visitorId = getVisitorId(guidHeader, account, userAgent, cookie);
// Always try and add the cookie to the response.
Cookie newCookie = new Cookie(COOKIE_NAME, visitorId);
newCookie.setMaxAge(COOKIE_USER_PERSISTENCE);
newCookie.setPath(COOKIE_PATH);
response.addCookie(newCookie);
String utmGifLocation = "http://www.google-analytics.com/__utm.gif";
// Construct the gif hit url.
String utmUrl = utmGifLocation + "?" +
"utmwv=" + version +
"&utmn=" + getRandomNumber() +
"&utmhn=" + URLEncoder.encode(domainName, "UTF-8") +
"&utmr=" + URLEncoder.encode(documentReferer, "UTF-8") +
"&utmp=" + URLEncoder.encode(documentPath, "UTF-8") +
"&utmac=" + account +
"&utmcc=__utma%3D999.999.999.999.999.1%3B" +
"&utmvid=" + visitorId +
"&utmip=" + getIP(request.getRemoteAddr());
return utmUrl;
}%>
<noscript>
<img src="<%= trackPageView(request, response) %>" />
</noscript>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment