UNPKG

ask-cli-x

Version:

Alexa Skills Kit (ASK) Command Line Interfaces

164 lines (163 loc) 5.26 kB
"use strict"; const uuid = require("uuid/v4"); const axios = require("axios"); const AppConfig = require("../../model/app-config"); const profileHelper = require("../../utils/profile-helper"); const { METRICS } = require("../../utils/constants"); const pck = require("../../../package.json"); const MetricActionResult = { SUCCESS: "Success", FAILURE: "Failure", }; class MetricAction { /** * @constructor * @param {string} name - The action name. * @param {string} type - The action type. */ constructor(name, type) { this.endTime = null; this.failureMessage = ""; this.name = name; this.result = null; this.startTime = new Date(); this.type = type; this.id = uuid(); this._ended = false; } /** * Closes action * @param {Error|string} [error=null] error - Error object or string indicating error. */ end(error = null) { if (this._ended) return; // if Error object extract error message, // otherwise error message string or null was passed as a parameter const errorMessage = error && error instanceof Error ? error.message : error; this.result = errorMessage ? MetricActionResult.FAILURE : MetricActionResult.SUCCESS; this.failureMessage = errorMessage || ""; this.endTime = new Date(); this._ended = true; } /** * Implementation of custom toJSON method to modify serialization with JSON.stringify */ toJSON() { return { end_time: this.endTime, failure_message: this.failureMessage, name: this.name, result: this.result, start_time: this.startTime, type: this.type, id: this.id, }; } } class MetricClient { /** * @constructor */ constructor() { this.httpClient = axios.create({ timeout: 3000, headers: { "Content-Type": "text/plain" }, }); this.serverUrl = METRICS.ENDPOINT; this.postRetries = 3; this.enabled = this._isEnabled(); this.data = { version: pck.version, machineId: this._getMachineId(), timeStarted: new Date(), newUser: false, timeUploaded: null, clientId: pck.name, actions: [], }; } /** * Starts action * @param {string} name - The action name * @param {string} type - The action type * @return {MetricAction} */ startAction(name, type) { const action = new MetricAction(name, type); this.data.actions.push(action); return action; } /** * Returns current data store in the metric client * @return {{version: string, machineId: string, timeStarted: Date, * newUser: boolean, timeUploaded: Date|null, clientId: string, actions: MetricAction[]}} */ getData() { return this.data; } /** * Sends data to the metric server * @param {Error|string} [error=null] error - Error object or string indicating error. * @returns {Promise<{success: boolean}>} */ sendData(error = null) { if (!this.enabled) { this.data.actions = []; return new Promise((resolve) => resolve({ success: true })); } this.data.actions.forEach((action) => action.end(error)); return this._upload() .then(() => { this.data.actions = []; return { success: true }; }) .catch(() => ({ success: false })); } /** * Implementation of custom toJSON method to modify serialization with JSON.stringify */ toJSON() { return { version: this.data.version, machine_id: this.data.machineId, time_started: this.data.timeStarted, new_user: this.data.newUser, time_uploaded: this.data.timeUploaded, client_id: this.data.clientId, actions: this.data.actions, }; } _upload() { this.data.timeUploaded = new Date(); const payload = JSON.stringify({ payload: this }); const postPromise = () => this.httpClient.post(this.serverUrl, payload); return this._retry(this.postRetries, postPromise); } _retry(retries, fn) { return fn().catch((err) => (retries > 1 ? this._retry(retries - 1, fn) : Promise.reject(err))); } _isEnabled() { if (profileHelper.isEnvProfile()) return true; if (process.env.ASK_SHARE_USAGE === "false") return false; if (!AppConfig.configFileExists()) return false; new AppConfig(); return AppConfig.getInstance().getShareUsage(); } _getMachineId() { if (!this.enabled) return; if (profileHelper.isEnvProfile()) return "all_environmental"; const appConfig = AppConfig.getInstance(); if (!appConfig.getMachineId()) { appConfig.setMachineId(uuid()); appConfig.write(); } return appConfig.getMachineId(); } } module.exports = { MetricClient, MetricActionResult };