UNPKG

rocketmetrics

Version:

Javascript package for RocketMetrics. RocketMetrics is a simplest and fastest way to track the performance of your acquisition channels, and track the AARRR metrics (acquisition, activation, retention, revenue, referral) of each of your channels. Get star

152 lines (137 loc) 4.71 kB
const fetch = require("node-fetch"); const { v4: uuidv4 } = require('uuid'); module.exports = function() { const settings = { apiKey: null, url: { prod: "https://bb0qo8s3l4.execute-api.eu-central-1.amazonaws.com/prod/publish", test: "https://dke5j9qag1.execute-api.eu-central-1.amazonaws.com/prod/publish" }, metrics: {}, domain: null, defaultFunnelId: null, testEnv: false }; const requiredFields = { configure: ["apiKey", "metrics", "domain"], newLead: ["funnelId"], newUser: ["userId"], newValue: ["metricName"], newUsage: [] } const isBrowser = function() { return typeof document !== "undefined"; } const getQueryVariable = function (variable) { const query = window.location.search.substring(1); const vars = query.split("&"); for (let i=0; i < vars.length; i++) { const pair = vars[i].split("="); if (pair[0] === variable) { return pair[1]; } } return(false); } const getCookie = function (cname) { const name = cname + "="; const decodedCookie = decodeURIComponent(document.cookie); const ca = decodedCookie.split(';'); for(let i=0; i < ca.length; i++) { let c = ca[i]; while (c.charAt(0) == ' ') { c = c.substring(1); } if (c.indexOf(name) === 0) { return c.substring(name.length, c.length); } } return false; } const hasRequiredFields = function (requiredFields, body, methodName) { const missingFields = []; requiredFields.forEach(field => { if (typeof field === "object") { if (field.or) { let missing = true; field.or.forEach(subField => { if (body[subField]) missing = false; }) if (missing) { const missingText = field.or.reduce((acc, value) => { if (acc) return `${acc} OR ${value}`; return value; }, "") missingFields.push(missingText) } } } else { if (!body || !body[field]) missingFields.push(field); } }) if (missingFields.length === 0) { return true; } throw { message: `Missing required fields for method '${methodName}'.`, missingFields } } const request = async function (body) { if (isBrowser()) { const leadId = getCookie("leadId"); if (!leadId) { if (body.eventName === 'newLead' || body.eventName === 'newUser') return; if (body.eventName === 'newValue' && !body.userId) return; if (body.eventName === 'newUsage' && !body.userId) return; } body.leadId = getCookie("leadId"); } const res = await fetch(settings.testEnv ? settings.url.test : settings.url.prod, { method: 'post', body: JSON.stringify(body), headers: { 'Content-Type': 'application/json', 'Authorization': settings.apiKey }, }) return res; } return { configure(options) { hasRequiredFields(requiredFields["configure"], options, "configure"); const { apiKey, metrics, domain, defaultFunnelId, testEnv } = options; settings.apiKey = apiKey; settings.metrics = metrics; settings.domain = domain; if (defaultFunnelId) settings.defaultFunnelId = defaultFunnelId; if (testEnv) settings.testEnv = testEnv; }, async triggerEvent(eventName, options) { if (!requiredFields[eventName]) throw new Error(`Event '${eventName}' does not exist.`) hasRequiredFields(requiredFields[eventName], options, "triggerEvent"); if (eventName === "newValue") { if (!settings.metrics[options.metricName]) throw new Error(`Metric '${options.metricName}' does not exist. Did you register it properly in the configure method?`) options.metricId = settings.metrics[options.metricName]; delete options.metricName; } const body = Object.assign(options, { eventName }); await request(body); }, async listen() { if (!isBrowser()) throw new Error('Listen method is only available on frontend environments.'); let funnelId = getQueryVariable("rm"); if (!funnelId && settings.defaultFunnelId) funnelId = settings.defaultFunnelId; if (funnelId && !getCookie("leadId")) { const leadId = uuidv4(); const expiracyDate = new Date(); expiracyDate.setFullYear(expiracyDate.getFullYear() + 10); document.cookie = `leadId=${leadId}; expires=${expiracyDate}; path=/; domain=${settings.domain}`; const options = { funnelId }; await this.triggerEvent("newLead", options); } } } }