Last active
February 13, 2017 10:22
-
-
Save gmccullough/7738182 to your computer and use it in GitHub Desktop.
This is a little CommonJS library I put together for adding Mixpanel tracking to an iOS and Android Appcelerator Titanium app I built. YMMV. I'm sharing it since I hadn't seen anything similar, and Mixpanel rocks. There are no native dependencies. All Mixpanel API calls are made by using the HTTP specification (https://mixpanel.com/docs/api-docu…
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// The currentUser lib stores a model representing the logged in user, and other login state information | |
var currentUser = require('currentUser'); | |
// Logger is a Ti.API.info() wrapper with a bit more flexibility | |
var logger = require('logger'); | |
var messageQueue = []; // put this into local storage at some point to retain recent offline events before crashes | |
var messageInTransit = null; | |
var token = Ti.App.Properties.getString('mixpanel.token'); | |
var systemProperties = { | |
mobile_osname: Ti.Platform.osname, | |
mobile_ostype: Ti.Platform.ostype, | |
mobile_osversion: Ti.Platform.version, | |
mobile_device_mfg: Ti.Platform.manufacturer, | |
mobile_device_model: Ti.Platform.model, | |
mobile_locale: Ti.Platform.locale | |
}; | |
var uuid = Ti.Platform.createUUID(); | |
exports.track = function(event, properties) { | |
logger.info('mixpanel track ' + event); | |
properties = properties || {}; | |
properties = _.extend(properties, systemProperties); | |
properties.time = (new Date()).getTime(); | |
properties.token = token; | |
properties.distinct_id = currentUser.isLoggedIn ? currentUser.user.get('email') : uuid; | |
event = "(App) " + event; | |
messageQueue.push({ | |
payload: { | |
event: event, | |
properties: properties | |
}, | |
type: 'event' | |
}); | |
sendNextMessage(); | |
}; | |
exports.alias = function() { | |
if(currentUser.isLoggedIn) { | |
logger.info('mixpanel alias'); | |
messageQueue.push({ | |
payload: { | |
event: '$create_alias', | |
properties: { | |
"alias": currentUser.user.get('email'), | |
"distinct_id": uuid, | |
"time": (new Date()).getTime(), | |
"token": token | |
} | |
}, | |
type: 'event' | |
}); | |
sendNextMessage(); | |
} | |
}; | |
exports.people = { | |
set: function(properties) { | |
properties = properties || {}; | |
logger.info('mixpanel people.set ' + properties); | |
if(!currentUser.isLoggedIn) { | |
console.log('mixpanel people.set skipped - user not logged in'); | |
return false; | |
} | |
properties = _.extend(properties, systemProperties); | |
properties = _.extend(properties, { | |
'$first_name': currentUser.user.get('first_name'), | |
'$last_name': currentUser.user.get('last_name'), | |
'$username': currentUser.user.get('username'), | |
'$email': currentUser.user.get('email'), | |
}); | |
var payload = { | |
'$set': properties, | |
'$token': token, | |
'$distinct_id': currentUser.user.get('email') | |
}; | |
messageQueue.push({ | |
payload: payload, | |
type: 'people.set' | |
}); | |
sendNextMessage(); | |
} | |
}; | |
function sendMessage(message) { | |
var url = ''; | |
if(message.type == 'event') { | |
url = "http://api.mixpanel.com/track/?data=" + Titanium.Utils.base64encode(JSON.stringify(message.payload)) + "&ip=1"; | |
} else if(message.type == 'people.set') { | |
url = "http://api.mixpanel.com/engage/?data=" + Titanium.Utils.base64encode(JSON.stringify(message.payload)); | |
} | |
xhr = Titanium.Network.createHTTPClient({ | |
onload : function(e) { | |
messageInTransit = false; | |
messageQueue.shift(); | |
sendNextMessage(); | |
}, | |
onerror: function(e){ | |
messageInTransit = false; | |
logger.info('Failed mixpanel event with status ' + this.status + ' and error : ' + JSON.stringify(e)); | |
setTimeout(function() { | |
sendNextMessage(); | |
}, 2000); // wait a couple of seconds before we try this again | |
}, | |
timeout: config.imageUploadTimeout | |
}); | |
xhr.open('POST', url); | |
xhr.send(); | |
} | |
function sendNextMessage() { | |
if(!Ti.Network.online) { | |
setTimeout(sendNextMessage, 10000); | |
return false; | |
} | |
if(messageInTransit) | |
return false; | |
if(messageQueue.length > 0) { | |
messageInTransit = messageQueue[0]; // FIFO | |
sendMessage(messageInTransit); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This is great. I think switching to the "Batch" type of request, every 20 seconds or so, and it would be perfect.