UNPKG

mpanalytics

Version:

Wrapper around google analytics measurement protocol, works both client- and serverside.

103 lines (88 loc) 2.44 kB
import superagent from 'superagent'; import hash from './hash.js'; /** * * * @param {string} options.uris - URIs to send post events to. * @param {number} options.sampleRate - From 0 to 100, defaults to 100. * @param {boolean} options.anonymizeIp - From 0 to 100, defaults to 100. */ function Service(options) { this.options = options; if (!options.tid) throw new Error('options.tid missing'); if (!options.cid) throw new Error('options.cid missing'); this.tid = options.tid; this.cid = options.cid || 'N/A'; this.uri = options.uri || 'https://www.google-analytics.com/collect'; this.sampleRate = options.sampleRate || 100; this.anonymizeIp = options.anonymizeIp !== false; // sampling based on tid+cid (same client always sampled in/out, // even if he sends multiple hits or reloads the page) this.sampledOut = this.sampleRate !== 100 && hash.range(this.cid + this.tid, 100) + 1 > this.sampleRate; } /** * Send a hit. * * @param {string} evt.t - Type. * @param {number} evt.v - Version. */ Service.prototype.send = function (evt, cb) { if (this.sampledOut) { return; } evt.tid = this.tid; evt.cid = this.cid; evt = { ...evt, aip: this.anonymizeIp ? 1 : 0, }; superagent .post(this.uri) .set('Content-Type', 'application/x-www-form-urlencoded') .send(new URLSearchParams(evt)) .then((res) => cb(null, res.body)) .catch((err) => cb(err)); }; /** * Send a pageview. * * @param {string} hostname - F.ex.: example.com * @param {string} page - F.ex.: /home * @param {string} title - F.ex.: Home */ Service.prototype.pageview = function (options, cb) { if (!options.hostname) throw new Error('options.hostname missing'); if (!options.page) throw new Error('options.page missing'); var evt = { v: 1, t: 'pageview', dh: options.hostname, dp: options.page, dt: options.title, }; this.send(evt, cb); }; /** * Send an event. * * @param {string} category * @param {string} action * @param {string} label * @param {number} value */ Service.prototype.event = function (options, cb) { if (!options.category) throw new Error('options.category missing'); if (!options.action) throw new Error('options.action missing'); var evt = { v: 1, t: 'event', ec: options.category, ea: options.action, el: options.label, ev: options.value || 1, }; this.send(evt, cb); }; export default Service;