diff options
Diffstat (limited to 'browser/components/pocket/content/pktTelemetry.jsm')
-rw-r--r-- | browser/components/pocket/content/pktTelemetry.jsm | 125 |
1 files changed, 125 insertions, 0 deletions
diff --git a/browser/components/pocket/content/pktTelemetry.jsm b/browser/components/pocket/content/pktTelemetry.jsm new file mode 100644 index 0000000000..1c14ff821e --- /dev/null +++ b/browser/components/pocket/content/pktTelemetry.jsm @@ -0,0 +1,125 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +"use strict"; + +var EXPORTED_SYMBOLS = ["pktTelemetry"]; + +const { XPCOMUtils } = ChromeUtils.importESModule( + "resource://gre/modules/XPCOMUtils.sys.mjs" +); +const lazy = {}; +ChromeUtils.defineModuleGetter( + lazy, + "PingCentre", + "resource:///modules/PingCentre.jsm" +); +ChromeUtils.defineModuleGetter( + lazy, + "pktApi", + "chrome://pocket/content/pktApi.jsm" +); +ChromeUtils.defineESModuleGetters(lazy, { + TelemetryEnvironment: "resource://gre/modules/TelemetryEnvironment.sys.mjs", +}); + +// List of namespaces for the structured ingestion system. +// They are defined in https://github.com/mozilla-services/mozilla-pipeline-schemas +const STRUCTURED_INGESTION_NAMESPACE_AS = "activity-stream"; +const STRUCTURED_INGESTION_ENDPOINT_PREF = + "browser.newtabpage.activity-stream.telemetry.structuredIngestion.endpoint"; +// This is the topic for telemetry pings, used inside PingCentre. +const POCKET_TELEMETRY_TOPIC = "pocket"; +const PREF_IMPRESSION_ID = "browser.newtabpage.activity-stream.impressionId"; + +XPCOMUtils.defineLazyGetter(lazy, "pingCentre", () => { + return new lazy.PingCentre({ topic: POCKET_TELEMETRY_TOPIC }); +}); + +var pktTelemetry = { + get structuredIngestionEndpointBase() { + if (!this._structuredIngestionEndpointBase) { + this._structuredIngestionEndpointBase = Services.prefs.getStringPref( + STRUCTURED_INGESTION_ENDPOINT_PREF, + "" + ); + } + return this._structuredIngestionEndpointBase; + }, + + get impressionId() { + if (!this._impressionId) { + this._impressionId = this.getOrCreateImpressionId(); + } + return this._impressionId; + }, + + // Sets or gets the impression id that's use for Pocket impressions. + // The impression id cannot be tied to a client id. + // This is the same impression id used in newtab pocket impressions. + getOrCreateImpressionId() { + let impressionId = Services.prefs.getStringPref(PREF_IMPRESSION_ID, ""); + + if (!impressionId) { + impressionId = String(Services.uuid.generateUUID()); + Services.prefs.setStringPref(PREF_IMPRESSION_ID, impressionId); + } + return impressionId; + }, + + /** + * createPingPayload - Create a ping for an impression stats + * + * @param {ob} data The data object to be included in the ping. + * @return {obj} A telemetry ping + */ + createPingPayload(data) { + // experiments, locale, version, and release_channel are provided by pingCentre. + // model and events is provided in the data param. + return { + ...data, + impression_id: this.impressionId, + pocket_logged_in_status: lazy.pktApi.isUserLoggedIn(), + profile_creation_date: this._profileCreationDate(), + }; + }, + + _profileCreationDate() { + return ( + lazy.TelemetryEnvironment.currentEnvironment.profile.resetDate || + lazy.TelemetryEnvironment.currentEnvironment.profile.creationDate + ); + }, + + _generateUUID() { + return String(Services.uuid.generateUUID()); + }, + + /** + * Generates an endpoint for Structured Ingestion telemetry pipeline. Note that + * Structured Ingestion requires a different endpoint for each ping. See more + * details about endpoint schema at: + * https://github.com/mozilla/gcp-ingestion/blob/master/docs/edge.md#postput-request + */ + _generateStructuredIngestionEndpoint() { + const uuid = this._generateUUID(); + // Structured Ingestion does not support the UUID generated by gUUIDGenerator, + // because it contains leading and trailing braces. Need to trim them first. + const docID = uuid.slice(1, -1); + const extension = `${STRUCTURED_INGESTION_NAMESPACE_AS}/pocket-button/1/${docID}`; + return `${this.structuredIngestionEndpointBase}/${extension}`; + }, + + /** + * sendStructuredIngestionEvent - Sent a ping for an impression stats + * + * @param {ob} eventObject The data object to be included in the ping. + */ + sendStructuredIngestionEvent(eventObject) { + lazy.pingCentre.sendStructuredIngestionPing( + eventObject, + this._generateStructuredIngestionEndpoint() + ); + }, +}; |