UNPKG

mixpanel

Version:

A simple server-side API for mixpanel

332 lines (267 loc) 10.7 kB
const {merge_modifiers, ProfileHelpers} = require('./profile_helpers'); class MixpanelPeople extends ProfileHelpers() { constructor(mp_instance) { super(); this.mixpanel = mp_instance; this.endpoint = '/engage'; } /** people.set_once(distinct_id, prop, to, modifiers, callback) --- The same as people.set but in the words of mixpanel: mixpanel.people.set_once " This method allows you to set a user attribute, only if it is not currently set. It can be called multiple times safely, so is perfect for storing things like the first date you saw a user, or the referrer that brought them to your website for the first time. " */ set_once(distinct_id, prop, to, modifiers, callback) { const identifiers = {$distinct_id: distinct_id}; this._set(prop, to, modifiers, callback, {identifiers, set_once: true}); } /** people.set(distinct_id, prop, to, modifiers, callback) --- set properties on an user record in engage usage: mixpanel.people.set('bob', 'gender', 'm'); mixpanel.people.set('joe', { 'company': 'acme', 'plan': 'premium' }); */ set(distinct_id, prop, to, modifiers, callback) { const identifiers = {$distinct_id: distinct_id}; this._set(prop, to, modifiers, callback, {identifiers}); } /** people.increment(distinct_id, prop, by, modifiers, callback) --- increment/decrement properties on an user record in engage usage: mixpanel.people.increment('bob', 'page_views', 1); // or, for convenience, if you're just incrementing a counter by 1, you can // simply do mixpanel.people.increment('bob', 'page_views'); // to decrement a counter, pass a negative number mixpanel.people.increment('bob', 'credits_left', -1); // like mixpanel.people.set(), you can increment multiple properties at once: mixpanel.people.increment('bob', { counter1: 1, counter2: 3, counter3: -2 }); */ increment(distinct_id, prop, by, modifiers, callback) { // TODO extract to ProfileHelpers var $add = {}; if (typeof(prop) === 'object') { if (typeof(by) === 'object') { callback = modifiers; modifiers = by; } else { callback = by; } for (const [key, val] of Object.entries(prop)) { if (isNaN(parseFloat(val))) { if (this.mixpanel.config.debug) { this.mixpanel.config.logger.error( "Invalid increment value passed to mixpanel.people.increment - must be a number", {key, value: val} ); } } else { $add[key] = val; } }; } else { if (typeof(by) === 'number' || !by) { by = by || 1; $add[prop] = by; if (typeof(modifiers) === 'function') { callback = modifiers; } } else if (typeof(by) === 'function') { callback = by; $add[prop] = 1; } else { callback = modifiers; modifiers = (typeof(by) === 'object') ? by : {}; $add[prop] = 1; } } var data = { '$add': $add, '$token': this.mixpanel.token, '$distinct_id': distinct_id }; data = merge_modifiers(data, modifiers); if (this.mixpanel.config.debug) { this.mixpanel.config.logger.debug("Sending the following data to Mixpanel (Engage)", { data }); } this.mixpanel.send_request({ method: "GET", endpoint: "/engage", data: data }, callback); } /** people.append(distinct_id, prop, value, modifiers, callback) --- Append a value to a list-valued people analytics property. usage: // append a value to a list, creating it if needed mixpanel.people.append('bob', 'pages_visited', 'homepage'); // like mixpanel.people.set(), you can append multiple properties at once: mixpanel.people.append('bob', { list1: 'bob', list2: 123 }); */ append(distinct_id, prop, value, modifiers, callback) { // TODO extract to ProfileHelpers var $append = {}; if (typeof(prop) === 'object') { if (typeof(value) === 'object') { callback = modifiers; modifiers = value; } else { callback = value; } Object.keys(prop).forEach(function(key) { $append[key] = prop[key]; }); } else { $append[prop] = value; if (typeof(modifiers) === 'function') { callback = modifiers; } } var data = { '$append': $append, '$token': this.mixpanel.token, '$distinct_id': distinct_id }; data = merge_modifiers(data, modifiers); if (this.mixpanel.config.debug) { this.mixpanel.config.logger.debug("Sending the following data to Mixpanel (Engage)", { data }); } this.mixpanel.send_request({ method: "GET", endpoint: "/engage", data: data }, callback); } /** people.track_charge(distinct_id, amount, properties, modifiers, callback) --- Record that you have charged the current user a certain amount of money. usage: // charge a user $29.99 mixpanel.people.track_charge('bob', 29.99); // charge a user $19 on the 1st of february mixpanel.people.track_charge('bob', 19, { '$time': new Date('feb 1 2012') }); */ track_charge(distinct_id, amount, properties, modifiers, callback) { if (typeof(properties) === 'function' || !properties) { callback = properties || undefined; properties = {}; } else { if (typeof(modifiers) === 'function' || !modifiers) { callback = modifiers || undefined; if (properties.$ignore_time || properties.hasOwnProperty("$ip")) { modifiers = {}; Object.keys(properties).forEach(function(key) { modifiers[key] = properties[key]; delete properties[key]; }); } } } if (typeof(amount) !== 'number') { amount = parseFloat(amount); if (isNaN(amount)) { this.mixpanel.config.logger.error("Invalid value passed to mixpanel.people.track_charge - must be a number"); return; } } properties.$amount = amount; if (properties.hasOwnProperty('$time')) { var time = properties.$time; if (Object.prototype.toString.call(time) === '[object Date]') { properties.$time = time.toISOString(); } } var data = { '$append': { '$transactions': properties }, '$token': this.mixpanel.token, '$distinct_id': distinct_id }; data = merge_modifiers(data, modifiers); if (this.mixpanel.config.debug) { this.mixpanel.config.logger.debug("Sending the following data to Mixpanel (Engage)", { data }); } this.mixpanel.send_request({ method: "GET", endpoint: "/engage", data: data }, callback); } /** people.clear_charges(distinct_id, modifiers, callback) --- Clear all the current user's transactions. usage: mixpanel.people.clear_charges('bob'); */ clear_charges(distinct_id, modifiers, callback) { var data = { '$set': { '$transactions': [] }, '$token': this.mixpanel.token, '$distinct_id': distinct_id }; if (typeof(modifiers) === 'function') { callback = modifiers; } data = merge_modifiers(data, modifiers); if (this.mixpanel.config.debug) { this.mixpanel.config.logger.debug("Clearing this user's charges", { '$distinct_id': distinct_id }); } this.mixpanel.send_request({ method: "GET", endpoint: "/engage", data: data }, callback); } /** people.delete_user(distinct_id, modifiers, callback) --- delete an user record in engage usage: mixpanel.people.delete_user('bob'); */ delete_user(distinct_id, modifiers, callback) { const identifiers = {$distinct_id: distinct_id}; this._delete_profile({identifiers, modifiers, callback}); } /** people.remove(distinct_id, data, modifiers, callback) --- remove a value from a list-valued user profile property. usage: mixpanel.people.remove('bob', {'browsers': 'firefox'}); mixpanel.people.remove('bob', {'browsers': 'chrome', 'os': 'linux'}); */ remove(distinct_id, data, modifiers, callback) { const identifiers = {'$distinct_id': distinct_id}; this._remove({identifiers, data, modifiers, callback}) } /** people.union(distinct_id, data, modifiers, callback) --- merge value(s) into a list-valued people analytics property. usage: mixpanel.people.union('bob', {'browsers': 'firefox'}); mixpanel.people.union('bob', {'browsers': ['chrome'], os: ['linux']}); */ union(distinct_id, data, modifiers, callback) { const identifiers = {$distinct_id: distinct_id}; this._union({identifiers, data, modifiers, callback}); } /** people.unset(distinct_id, prop, modifiers, callback) --- delete a property on an user record in engage usage: mixpanel.people.unset('bob', 'page_views'); mixpanel.people.unset('bob', ['page_views', 'last_login']); */ unset(distinct_id, prop, modifiers, callback) { const identifiers = {$distinct_id: distinct_id}; this._unset({identifiers, prop, modifiers, callback}); } }; exports.MixpanelPeople = MixpanelPeople;