Skip to content

Commit

Permalink
Updating analytics to use build server (#3729)
Browse files Browse the repository at this point in the history
* Updating analytics to use build server

- allows for server side analytics submission to whatever service we plan to use

* Revert to const (artifact left over from some testing)

* Send the changeList object in total
  • Loading branch information
blckmn authored Jan 4, 2024
1 parent 072d16c commit 66d175b
Show file tree
Hide file tree
Showing 8 changed files with 96 additions and 221 deletions.
1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,6 @@
"short-unique-id": "^4.4.4",
"switchery-latest": "^0.8.2",
"three": "~0.97.0",
"universal-ga": "^1.2.0",
"vite-plugin-pwa": "^0.17.4",
"vue": "^2.7.10"
},
Expand Down
185 changes: 32 additions & 153 deletions src/js/Analytics.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import ShortUniqueId from 'short-unique-id';
import googleAnalytics from 'universal-ga';
import BuildApi from './BuildApi';
import { set as setConfig, get as getConfig } from './ConfigStorage';
import GUI from './gui';
import CONFIGURATOR from './data_storage';
Expand All @@ -8,43 +8,38 @@ import $ from 'jquery';
let tracking = null;
export { tracking };

export function createAnalytics(ga, settings) {
tracking = new Analytics(ga, settings);
export function createAnalytics(settings) {
tracking = new Analytics(settings);
}

function getBuildType() {
return GUI.Mode;
}

function setupAnalytics(result) {
const uid = new ShortUniqueId();

let userId;
if (result.userId) {
userId = result.userId;
} else {
const uid = new ShortUniqueId();
userId = uid.randomUUID(13);

setConfig({ 'userId': userId });
}

const optOut = !!result.analyticsOptOut;
const checkForDebugVersions = !!result.checkForConfiguratorUnstableVersions;

const debugMode = typeof process === "object" && process.versions['nw-flavor'] === 'sdk';

const settings = {
trackingId: 'UA-123002063-1',
sessionId: uid.randomUUID(16),
userId: userId,
appName: CONFIGURATOR.productName,
appVersion: CONFIGURATOR.version,
gitRevision: CONFIGURATOR.gitRevision,
os: GUI.operating_system,
checkForDebugVersions: checkForDebugVersions,
optOut: optOut,
// debugMode: debugMode, // enable when debugging GA
buildType: getBuildType(),
buildType: GUI.Mode,
};
createAnalytics(googleAnalytics, settings);

createAnalytics(settings);
window.tracking = tracking;

function logException(exception) {
Expand Down Expand Up @@ -74,179 +69,63 @@ export function checkSetupAnalytics(callback) {

class Analytics {

constructor (ga, settings) {
// trackingId, userId, appName, appVersion, gitRevision, os, checkForDebugVersions, optOut, debugMode, buildType
this._trackingId = settings.trackingId;
constructor (settings) {

this.setOptOut(settings.optOut);

this._googleAnalytics = ga;

this._googleAnalytics.initialize(this._trackingId, {
storage: 'none',
clientId: settings.userId,
debug: !!settings.debugMode,
});

// Make it work for the Chrome App:
this._googleAnalytics.set('forceSSL', true);
this._googleAnalytics.set('transport', 'xhr');

// Make it work for NW.js:
this._googleAnalytics.set('checkProtocolTask', null);

this._googleAnalytics.set('appName', settings.appName);
this._googleAnalytics.set('appVersion', settings.debugMode ? `${settings.appVersion}-debug` : settings.appVersion);
this._settings = settings;
this._api = new BuildApi();

this.EVENT_CATEGORIES = {
APPLICATION: 'Application',
FLIGHT_CONTROLLER: 'FlightController',
FLASHING: 'Flashing',
};

this.DATA = {
BOARD_TYPE: 'boardType',
API_VERSION: 'apiVersion',
FIRMWARE_TYPE: 'firmwareType',
FIRMWARE_VERSION: 'firmwareVersion',
FIRMWARE_NAME: 'firmwareName',
FIRMWARE_SOURCE: 'firmwareSource',
FIRMWARE_CHANNEL: 'firmwareChannel',
FIRMWARE_ERASE_ALL: 'firmwareEraseAll',
FIRMWARE_SIZE: 'firmwareSize',
MCU_ID: 'mcuId',
LOGGING_STATUS: 'loggingStatus',
LOG_SIZE: 'logSize',
TARGET_NAME: 'targetName',
BOARD_NAME: 'boardName',
MANUFACTURER_ID: 'manufacturerId',
MCU_TYPE: 'mcuType',
};

this.DIMENSIONS = {
CONFIGURATOR_OS: 1,
BOARD_TYPE: 2,
FIRMWARE_TYPE: 3,
FIRMWARE_VERSION: 4,
API_VERSION: 5,
FIRMWARE_NAME: 6,
FIRMWARE_SOURCE: 7,
FIRMWARE_ERASE_ALL: 8,
CONFIGURATOR_EXPERT_MODE: 9,
FIRMWARE_CHANNEL: 10,
LOGGING_STATUS: 11,
MCU_ID: 12,
CONFIGURATOR_CHANGESET_ID: 13,
CONFIGURATOR_USE_DEBUG_VERSIONS: 14,
TARGET_NAME: 15,
BOARD_NAME: 16,
MANUFACTURER_ID: 17,
MCU_TYPE: 18,
CONFIGURATOR_BUILD_TYPE: 19,
};

this.METRICS = {
FIRMWARE_SIZE: 1,
LOG_SIZE: 2,
};

this.setDimension(this.DIMENSIONS.CONFIGURATOR_OS, settings.os);
this.setDimension(this.DIMENSIONS.CONFIGURATOR_CHANGESET_ID, settings.gitRevision);
this.setDimension(this.DIMENSIONS.CONFIGURATOR_USE_DEBUG_VERSIONS, settings.checkForDebugVersions);
this.setDimension(this.DIMENSIONS.CONFIGURATOR_BUILD_TYPE, settings.buildType);

this.resetFlightControllerData();
this.resetFirmwareData();
this.sendSettings();
}

setDimension(dimension, value) {
const dimensionName = `dimension${dimension}`;
this._googleAnalytics.custom(dimensionName, value);
send(name, properties) {
if (this._optOut) {
return;
}

this._api.sendAnalytics(name, {
sessionId: this._settings.sessionId,
userId: this._settings.userId,
[name]: properties,
});
}

setMetric(metric, value) {
const metricName = `metric${metric}`;
this._googleAnalytics.custom(metricName, value);
sendSettings() {
this.send('settings', this._settings);
}

sendEvent(category, action, options) {
this._googleAnalytics.event(category, action, options);
this.send('event', { category: category, action: action, options: options });
}

sendChangeEvents(category, changeList) {
for (const actionName in changeList) {
if (changeList.hasOwnProperty(actionName)) {
const actionValue = changeList[actionName];
if (actionValue !== undefined) {
this.sendEvent(category, actionName, { eventLabel: actionValue });
}
}
}
this.sendEvent(category, 'Change', { changes: changeList });
}

sendSaveAndChangeEvents(category, changeList, tabName) {
this.sendEvent(category, 'Save', {
eventLabel: tabName,
eventValue: Object.keys(changeList).length,
});
this.sendChangeEvents(category, changeList);
this.sendEvent(category, 'Save', { tab: tabName, changes: changeList });
}

sendAppView(viewName) {
this._googleAnalytics.screenview(viewName);
this.send('view', viewName);
}

sendTiming(category, timing, value) {
this._googleAnalytics.timing(category, timing, value);
this.send('timing', { category: category, timing: timing, value: value });
}

sendException(message) {
this._googleAnalytics.exception(message);
this.send('exception', message);
}

setOptOut(optOut) {
window[`ga-disable-${this._trackingId}`] = !!optOut;
}

_rebuildFlightControllerEvent() {
this.setDimension(this.DIMENSIONS.BOARD_TYPE, this._flightControllerData[this.DATA.BOARD_TYPE]);
this.setDimension(this.DIMENSIONS.FIRMWARE_TYPE, this._flightControllerData[this.DATA.FIRMWARE_TYPE]);
this.setDimension(this.DIMENSIONS.FIRMWARE_VERSION, this._flightControllerData[this.DATA.FIRMWARE_VERSION]);
this.setDimension(this.DIMENSIONS.API_VERSION, this._flightControllerData[this.DATA.API_VERSION]);
this.setDimension(this.DIMENSIONS.LOGGING_STATUS, this._flightControllerData[this.DATA.LOGGING_STATUS]);
this.setDimension(this.DIMENSIONS.MCU_ID, this._flightControllerData[this.DATA.MCU_ID]);
this.setMetric(this.METRICS.LOG_SIZE, this._flightControllerData[this.DATA.LOG_SIZE]);
this.setDimension(this.DIMENSIONS.TARGET_NAME, this._flightControllerData[this.DATA.TARGET_NAME]);
this.setDimension(this.DIMENSIONS.BOARD_NAME, this._flightControllerData[this.DATA.BOARD_NAME]);
this.setDimension(this.DIMENSIONS.MANUFACTURER_ID, this._flightControllerData[this.DATA.MANUFACTURER_ID]);
this.setDimension(this.DIMENSIONS.MCU_TYPE, this._flightControllerData[this.DATA.MCU_TYPE]);
}

setFlightControllerData(property, value) {
this._flightControllerData[property] = value;
this._rebuildFlightControllerEvent();
}

resetFlightControllerData() {
this._flightControllerData = {};
this._rebuildFlightControllerEvent();
}

_rebuildFirmwareEvent() {
this.setDimension(this.DIMENSIONS.FIRMWARE_NAME, this._firmwareData[this.DATA.FIRMWARE_NAME]);
this.setDimension(this.DIMENSIONS.FIRMWARE_SOURCE, this._firmwareData[this.DATA.FIRMWARE_SOURCE]);
this.setDimension(this.DIMENSIONS.FIRMWARE_ERASE_ALL, this._firmwareData[this.DATA.FIRMWARE_ERASE_ALL]);
this.setDimension(this.DIMENSIONS.FIRMWARE_CHANNEL, this._firmwareData[this.DATA.FIRMWARE_CHANNEL]);
this.setMetric(this.METRICS.FIRMWARE_SIZE, this._firmwareData[this.DATA.FIRMWARE_SIZE]);
}

setFirmwareData(property, value) {
this._firmwareData[property] = value;
this._rebuildFirmwareEvent();
}

resetFirmwareData() {
this._firmwareData = {};
this._rebuildFirmwareEvent();
this._optOut = !!optOut;
}
}
11 changes: 11 additions & 0 deletions src/js/BuildApi.js
Original file line number Diff line number Diff line change
Expand Up @@ -176,4 +176,15 @@ export default class BuildApi {
const url = `${this._url}/api/configurator/sponsors/${mode}/${page}`;
this.load(url, onSuccess, onFailure);
}

sendAnalytics(type, parcel) {
const url = `${this._url}/analytics/${type}`;
$.ajax({
url: url,
type: "POST",
data: JSON.stringify(parcel),
contentType: "application/json",
dataType: "json",
});
}
}
2 changes: 1 addition & 1 deletion src/js/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -570,7 +570,7 @@ function startProcess() {
const checked = expertModeCheckbox.is(':checked');

checkSetupAnalytics(function (analyticsService) {
analyticsService.setDimension(analyticsService.DIMENSIONS.CONFIGURATOR_EXPERT_MODE, checked ? 'On' : 'Off');
analyticsService.sendEvent(analyticsService.EVENT_CATEGORIES.APPLICATION, 'ExpertMode', { status: checked ? 'On' : 'Off' });
});

if (FC.FEATURE_CONFIG && FC.FEATURE_CONFIG.features !== 0) {
Expand Down
Loading

0 comments on commit 66d175b

Please sign in to comment.