bogdanrada
2/20/2015 - 5:31 PM

zopim mixpanel tracking.js

zopim mixpanel tracking.js

//
// Track.js  - tracking scripts by alex miller
//
//
config = {};
config.track = true;// set to true in production, false in dev env
config.dump = true;// set to false in production env, true in dev
config.mixpanel = true; // <%= TRACKS_CONFIG['mixpanel'] %>; // set to true in production env, false in dev
config.googleAnaltyics = true;

$(window).load(function(){
	unique_id = getUniqueId(); // setup the unique id
	setMixpanelUniqueID(unique_id);
	dump('fired window.load, unique_id = ' + unique_id);
});

$(window).load(function(){ // for pinterest tracking
	$('a[data-pin-log=button_pinit]').on('click', function(){
		trackPinterestShare();
		$("#pinterest_link").click();
	});
});

$(document).ready(function(){ //for zopim tracking
	if(typeof $zopim == "function"){
		$zopim(function(a) { 
			$zopim.livechat.setOnChatStart(function(b){
				
				window.chatter = initalizeLiveChatter($zopim);
				track('chat_first_message', {
					name: window.chatter.name,
					phone: window.chatter.phone,
					email: window.chatter.email
				});
			});

			$zopim.livechat.setOnConnected(	function(){
				setInterval(function(){
					var newChatter = initalizeLiveChatter($zopim);
					var oldChatter = window.chatter;
					//dump("old: " + JSON.stringify(window.chatter));
					//dump("new: " + JSON.stringify(newChatter));

				 	if(areEquivalent(oldChatter, newChatter) )
				 	{
				 	//	dump("name not updated");
				 	//	window.chatter = newChatter;
				 		// do nothing
				 	}else{
				 		dump("name updated:");
				 		dump(newChatter);
				 		window.chatter = newChatter;
				 		track('update_people', { people: window.chatter, source: 'zopim' } );
				 	}
				}, 5000);
			});
		}); 
	}
});

function initalizeLiveChatter($zopim){
	var chatter = {};
	chatter.name = $zopim.livechat.getName();
	chatter.email = $zopim.livechat.getEmail();
	chatter.phone = $zopim.livechat.getPhone();

	if(typeof(chatter.name) != "string"){
		chatter.name = "undefined";
	}

	if(typeof(chatter.email) != "string"){
		chatter.email = "undefined";
	}

	if(typeof(chatter.phone) != "string"){
		chatter.phone = "undefined";
	}

	if(typeof(unique_id) != "string" ){
		console.log("ERROR: no unique ID, exiting track");
	}else{
		chatter.unique_id = unique_id;
	}

	return chatter;
}

site_scroll = false; // has on scroll fired the first time yet?
$(document).on( 'scroll', function(){ // for scroll tracking
	if(site_scroll == false){
		site_scroll = true;
		track('scroll_past_fold',{
			page_width: $(document).width(),
			page_height: $(document).height()
		});
	}
});

function track( name, properties, callback){
	dump("TRACK TRACK TRACK");
	dump(name);
	dump(properties);
	dump("callback = " + typeof(callback) );

	// validate tracking event, properties and callback
	// add default properties currentURI and referrer
	var event = initalizeTrackingTag(name, properties, callback);

	postEventToDeployd(event);
	postEventToGoogleAnalytics(event);
	postEventToMixpanel(event);

	if(typeof(callback) == "function"){
		callback();
	}

	return true;
}

function supports_html5_storage() {
  try {
    return 'localStorage' in window && window['localStorage'] !== null;
  } catch (e) {
    return false;
  }
}

function getUniqueId(){
	unique_id = $("#unique_id").text();
	dump("unique_id on page = " + unique_id );
	dump("localstorage = " + localStorage['unique_id']);
	if(supports_html5_storage() && ( localStorage['unique_id'] != unique_id )  ){
		dump("tracking session");
		localStorage['unique_id'] = unique_id;
		track('session_start', {page_title: $('title').text() } );
	}
	dump("localStorage[unique_id] = " + localStorage['unique_id']);
	return unique_id;
}

function setMixpanelUniqueID(unique_id){
	if(typeof(mixpanel) != "undefined" && config.mixpanel == true){
		dump("identifying on mixpanel");
		mixpanel.identify(unique_id);
	}
}


function trackPinterestShare(){
	var props = getViewProperties();
	track('pinterest_share', props);
}

function postGoogleAnaltyicsTransaction(totalRevenue){
	// docs: https://developers.google.com/analytics/devguides/collection/analyticsjs/ecommerce
	debugger;
	if(typeof(_gaq) != "undefined" && config.googleAnaltyics == true){
		_gaq('require', 'ecommerce', 'ecommerce.js');
		var rand = Math.floor((Math.random()*10000000)+1);
		var transactionData = {
		  'id': rand,  // Transaction ID. Required.
		  'revenue': totalRevenue,               // Grand Total.
		}
		_gaq('ecommerce:addTransaction', transactionData);
		_gaq('ecommerce:send');
	}
	// _gaq('ecommerce:addItem', {
	//   'id': '1234',                     // Transaction ID. Required.
	//   'name': 'Fluffy Pink Bunnies',    // Product name. Required.
	//   'sku': 'DD23444',                 // SKU/code.
	//   'category': 'Party Toys',         // Category or variation.
	//   'price': '11.99',                 // Unit price.
	//   'quantity': '1'                   // Quantity.
	// });
}

function postEventToGoogleAnalytics(event){
	// https://developers.google.com/analytics/devguides/collection/analyticsjs/field-reference
	if( typeof(_gaq) == "function" && config.googleAnaltyics == true){

		if( typeof(event) != "object" || typeof(event.properties) != "object" ){
			return false;
		}

		var name = event.name;
		var properties = event.properties;
		var category = (properties.category != undefined) ? properties.category : 'undefined';
		var label = (properties.label != undefined) ? properties.label : 'undefined';
		var value = (properties.value != undefined) ? properties.value : 0;

		dump("sending event to google analytics: ");
		dump("category: " + category);
		dump("event: " + name);
		dump("label: " + label);
		dump("value: " + value);

		_gaq('send', 'event', category, name, label, value);

		if(category == "transaction"){
			postGoogleAnaltyicsTransaction(	properties.cart_total );
			
			if(typeof(mixpanel) == "object" && config.mixpanel == true){
				mixpanel.people.track_charge(properties.cart_total);
			}
		}
		
	} else {
		dump("ERROR NO GA");
	}
	
	// OLD WAY for ga.js, now using analytics.js
		// if(typeof(_gaq) != "undefined"){ 
	// 	// setup google analytics
	// 	var category = properties.category;
	// 	var label = (properties.label != undefined) ? properties.label : 'undefined';
	// 	var value = (properties.value != undefined) ? properties.value : '';

	// 	if(value != undefined && value != ''){
	// 		_gaq.push(['_trackEvent', category, event, label, value]);
	// 	} else {
	// 		_gaq.push(['_trackEvent', category, event, label]);
	// 	}
	//
}

function initalizeTrackingTag(name, properties, callback){
	if( typeof(name) != "string" ){
		dump("ERROR: event.name not a valid string, tracking aborted");
		return false;
	}
	if( typeof(properties) != "object"){
		dump("ERROR: event.properties not valid object, tracking aborted");
		return false;
	}
	if( typeof(unique_id) != "string" ) {
		unique_id = getUniqueId();
		if( typeof(unique_id) != "string" ) {
			dump("ERROR: unique_id not valid object, tracking aborted");
			unique_id = "undefined";
			return false;
		}
	} else{
		properties.user = unique_id;
	}

	// add default properties currentURI and referrer
	if(window.location.pathname != "/" || window.location.pathname.match( /^\/m[\/#]/ ) ){
		properties.currentURI = window.location.href;
	}

	if(document.referrer){
		properties.referrer = document.referrer;
	}

	if( typeof(properties.page_title) != "string" ){
		properties.page_title = $('title').text();
	}

	var event = {};
	event.name = name;
	event.properties = properties;
	event.callback = callback;

	return event;
}

function postEventToMixpanel(event){
	// https://mixpanel.com/docs/people-analytics/javascript

	if( ( typeof(event) != "object" ) || ( typeof(event.properties) != "object" ) ){
		return false;
	}

	if(typeof(mixpanel) != "undefined" && config.mixpanel == true){
		//track
		mixpanel.track(event.name, event.properties);
		//add people
		if(event.name == "login_success" || event.name == "signup_success"){
			// mixpanel.people.set({
			// 	"$email": "jsmith@example.com",
			// 	"$last_login": new Date(),
			// });
		    // "$created": "2011-03-16 16:53:54",
		    // "$last_login": new Date(),         // properties can be dates...
			// mixpanel.name_tag(user.name);
			// mixpanel.people.identify(user.name);
			// mixpanel.people.set({
			//		name: user.name,
			//		gender: properties.gender,
			//		email: properties.email,
		}
		
		if( typeof(event.properties.people) != "object" ){
			return false;
		}

		if(typeof(event.properties.people) == "object" ){
			dump("tracking people in mixpanel");
			var people = {};
			people.$name = event.properties.people.name;
			people.$email = event.properties.people.email;
			people.$phone = event.properties.people.phone;
			people.uniqueID = unique_id;
			
			dump(people);
			
			mixpanel.people.set( people );
		}
	}
}

function postEventToDeployd(event){
	if( typeof(dpd) == "undefined"){
		dump("ERROR: NO DEPLOYD");
		return false;
	}

	dpd.tracks.post({
		"event" : event.name,
		"properties" : event.properties,
		"user" : unique_id
	}, function(results, err){
		if(!err){
			dump("dpd post success: " + JSON.stringify(results) );
		} else{
			dump("dpd post fail: " + JSON.stringify(err) );
		}
	});

	if(typeof(event.properties.people) == "object" ){
		//http://cdn.frogo.tv/blog/images/2014-04-02_0332.png?height=410&width=477
		event.properties.people.uniqueID = unique_id;
		dpd.people.post( event.properties.people );
		delete(event.properties.people.uniqueID);
	}
}


function dump(str){
	if(config.dump != true){ return false };
	console.log(str);
}


function unwrapStringOrNumber(obj) {
    return (obj instanceof Number || obj instanceof String 
            ? obj.valueOf() 
            : obj);
}
function areEquivalent(a, b) {
    a = unwrapStringOrNumber(a);
    b = unwrapStringOrNumber(b);
    if (a === b) return true; //e.g. a and b both null
    if (a === null || b === null || typeof (a) !== typeof (b)) return false;
    if (a instanceof Date) 
        return b instanceof Date && a.valueOf() === b.valueOf();
    if (typeof (a) !== "object") 
        return a == b; //for boolean, number, string, xml

    var newA = (a.areEquivalent_Eq_91_2_34 === undefined),
        newB = (b.areEquivalent_Eq_91_2_34 === undefined);
    try {
        if (newA) a.areEquivalent_Eq_91_2_34 = [];
        else if (a.areEquivalent_Eq_91_2_34.some(
            function (other) { return other === b; })) return true;
        if (newB) b.areEquivalent_Eq_91_2_34 = [];
        else if (b.areEquivalent_Eq_91_2_34.some(
            function (other) { return other === a; })) return true;
        a.areEquivalent_Eq_91_2_34.push(b);
        b.areEquivalent_Eq_91_2_34.push(a);

        var tmp = {};
        for (var prop in a) 
            if(prop != "areEquivalent_Eq_91_2_34") 
                tmp[prop] = null;
        for (var prop in b) 
            if (prop != "areEquivalent_Eq_91_2_34") 
                tmp[prop] = null;

        for (var prop in tmp) 
            if (!areEquivalent(a[prop], b[prop]))
                return false;
        return true;
    } finally {
        if (newA) delete a.areEquivalent_Eq_91_2_34;
        if (newB) delete b.areEquivalent_Eq_91_2_34;
    }
}