owtlab-tracking
Version:
A simple Tracking system
216 lines (185 loc) • 5.59 kB
JavaScript
import 'promise-polyfill/src/polyfill';
import Owtlab from './index';
import { version } from '../package.json';
import each from 'keen-core/lib/utils/each';
import extend from 'keen-core/lib/utils/extend';
import { getExtendedEventBody } from './extend-events';
import nodeRequestRetry from './utils/nodeRequestRetry';
import isUnique from './utils/unique';
// ------------------------------
// .recordEvent
// ------------------------------
export function recordEvent(
eventCollectionOrConfigObject,
eventBody,
callback,
) {
let eventCollection = eventCollectionOrConfigObject;
let unique;
let configObject;
const clientConfig = this.config;
if (
typeof eventCollectionOrConfigObject === 'object' &&
eventCollectionOrConfigObject
) {
// slowly but surely we migrate to one object with all args
configObject = eventCollectionOrConfigObject;
eventCollection =
eventCollectionOrConfigObject.collection ||
eventCollectionOrConfigObject.event_collection;
eventBody = eventCollectionOrConfigObject.event;
callback = eventCollectionOrConfigObject.callback;
unique = eventCollectionOrConfigObject.unique;
}
const data = {};
const extendedEventBody = {};
if (!checkValidation.call(this, callback)) {
return;
}
if (!eventCollection || typeof eventCollection !== 'string') {
handleValidationError.call(
this,
'Collection name must be a string.',
callback,
);
return;
}
extend(data, eventBody);
// ------------------------------
// Run extendEvent(s) transforms
// ------------------------------
getExtendedEventBody(extendedEventBody, this.extensions.events);
getExtendedEventBody(
extendedEventBody,
this.extensions.collections[eventCollection],
);
getExtendedEventBody(extendedEventBody, [data]);
if (unique) {
return isUnique(configObject, extendedEventBody).then((isUniqueResult) => {
if (!isUniqueResult) {
return Promise.resolve({
created: false,
message: '[NOT_UNIQUE] This event has already been recorded',
});
}
return recordEvent.call(this, {
...eventCollectionOrConfigObject,
unique: undefined,
});
});
}
this.emit('recordEvent', eventCollection, extendedEventBody);
if (!Owtlab.enabled) {
handleValidationError.call(this, 'Owtlab.enabled is set to false.', callback);
return false;
}
return sendEventData.call(
this,
encodeURIComponent(eventCollection),
extendedEventBody,
callback,
);
}
// ------------------------------
// .recordEvents
// ------------------------------
export function recordEvents(eventsHash, callback) {
const self = this;
const extendedEventsHash = {};
if (!checkValidation.call(this, callback)) {
return;
}
if (arguments.length > 2) {
handleValidationError.call(
this,
'Incorrect arguments provided to #recordEvents method',
callback,
);
return;
}
// ------------------------------
// Run extendEvent(s) transforms
// ------------------------------
each(eventsHash, (eventList, eventCollection) => {
// Find or create collection on new hash
extendedEventsHash[eventCollection] =
extendedEventsHash[eventCollection] || [];
// Loop over each eventBody in the existing hash
each(eventList, (eventBody, index) => {
// Create a new data object
const extendedEventBody = {};
// Process "events" transform pipeline
getExtendedEventBody(extendedEventBody, self.extensions.events);
// Process "collection" transform pipeline
getExtendedEventBody(
extendedEventBody,
self.extensions.collections[eventCollection],
);
// Blend existing eventBody data into the result
getExtendedEventBody(extendedEventBody, [eventBody]);
// Push extendedEventBody into new hash
extendedEventsHash[eventCollection].push(extendedEventBody);
});
});
this.emit('recordEvents', extendedEventsHash);
if (!Owtlab.enabled) {
handleValidationError.call(this, 'Owtlab.enabled is set to false.', callback);
return false;
}
return sendEventData.call(this, undefined, extendedEventsHash, callback);
}
// ------------------------------
// Validation
// ------------------------------
function checkValidation(callback) {
if (!this.client_id()) {
handleValidationError.call(
this,
'Owtlab.Client is missing a client_id property.',
callback,
);
return false;
}
if (!this.client_secret()) {
handleValidationError.call(
this,
'Owtlab.Client is missing a client_secret property.',
callback,
);
return false;
}
return true;
}
function handleValidationError(message, cb) {
const err = `Event(s) not recorded: ${message}`;
this.emit('error', err);
if (cb) {
cb.call(this, err, null);
}
}
function sendEventData(path, eventData, callback) {
const data = JSON.stringify(eventData);
const urlPath = this.url('events', path).replace(
`${this.config.protocol}://${this.config.host}`,
'',
);
const config = {
host: this.config.host,
path: urlPath,
method: 'POST',
headers: {
Authorization: this.client_secret(),
'Content-Type': 'application/json',
'Content-Length': Buffer.byteLength(data),
'keen-sdk': `javascript-${version}`,
},
...this.config.nodeRequestConfig,
};
return nodeRequestRetry({
retry: this.config.retry,
protocol: this.config.protocol,
config,
data,
callback,
});
}