Skip to content

Instantly share code, notes, and snippets.

@fotoflo
Created April 16, 2014 21:26
Show Gist options
  • Save fotoflo/10934777 to your computer and use it in GitHub Desktop.
Save fotoflo/10934777 to your computer and use it in GitHub Desktop.
//
// 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": "[email protected]",
// "$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;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment