UNPKG

ember-metrics

Version:

Send data to multiple analytics integrations without re-implementing new API

151 lines (125 loc) 4.5 kB
import { assert } from '@ember/debug'; import removeFromDOM from 'ember-metrics/-private/utils/remove-from-dom'; import { compact } from 'ember-metrics/-private/utils/object-transforms'; import BaseAdapter from './base'; export default class Segment extends BaseAdapter { toStringExtension() { return 'Segment'; } install() { const config = { ...this.config }; const segmentKey = config.key; const proxyDomain = config.proxyDomain || 'https://cdn.segment.com'; assert( `[ember-metrics] You must pass a valid \`key\` to the ${this.toString()} adapter`, segmentKey ); // start of segment loading snippet, taken here: // https://segment.com/docs/connections/sources/catalog/libraries/website/javascript/quickstart/#step-2-copy-the-segment-snippet // Create a queue, but don't obliterate an existing one! let analytics = (window.analytics = window.analytics || []); // If the real analytics.js is already on the page return. if (analytics.initialize) return; // If the snippet was invoked already show an error. if (analytics.invoked) { if (window.console && console.error) { console.error('Segment snippet included twice.'); } return; } // Invoked flag, to make sure the snippet // is never invoked twice. analytics.invoked = true; // A list of the methods in Analytics.js to stub. analytics.methods = [ 'trackSubmit', 'trackClick', 'trackLink', 'trackForm', 'pageview', 'identify', 'reset', 'group', 'track', 'ready', 'alias', 'debug', 'page', 'once', 'off', 'on', 'addSourceMiddleware', 'addIntegrationMiddleware', 'setAnonymousId', 'addDestinationMiddleware', ]; // Define a factory to create stubs. These are placeholders // for methods in Analytics.js so that you never have to wait // for it to load to actually record data. The `method` is // stored as the first argument, so we can replay the data. analytics.factory = function (method) { return function () { let args = Array.prototype.slice.call(arguments); args.unshift(method); analytics.push(args); return analytics; }; }; // For each of our methods, generate a queueing stub. for (let i = 0; i < analytics.methods.length; i++) { const key = analytics.methods[i]; analytics[key] = analytics.factory(key); } // Define a method to load Analytics.js from our CDN, // and that will be sure to only ever load it once. analytics.load = function (key, options) { // Create an async script element based on your key. const script = document.createElement('script'); script.type = 'text/javascript'; script.async = true; script.src = `${proxyDomain}/analytics.js/v1/${key}/analytics.min.js`; // Insert our script next to the first script element. const first = document.getElementsByTagName('script')[0]; first.parentNode.insertBefore(script, first); analytics._loadOptions = options; }; analytics._writeKey = segmentKey; // Add a version to keep track of what's in the wild. analytics.SNIPPET_VERSION = '4.15.2'; // Load Analytics.js with your key, which will automatically // load the tools you've enabled for your account. Boosh! analytics.load(segmentKey); // end of segment loading snippet } alias(options = {}) { const compactedOptions = compact(options); const { alias, original } = compactedOptions; if (original) { window.analytics.alias(alias, original); } else { window.analytics.alias(alias); } } identify(options = {}) { const compactedOptions = compact(options); const { distinctId } = compactedOptions; delete compactedOptions.distinctId; window.analytics.identify(distinctId, compactedOptions); } trackEvent(options = {}) { const compactedOptions = compact(options); const { event } = compactedOptions; delete compactedOptions.event; window.analytics.track(event, compactedOptions); } trackPage(options = {}) { const compactedOptions = compact(options); const { page } = compactedOptions; delete compactedOptions.page; window.analytics.page(page, compactedOptions); } uninstall() { removeFromDOM('script[src*="segment.com"]'); delete window.analytics; } }