summaryrefslogtreecommitdiffstats
path: root/browser/components/pocket/content/pktTelemetry.jsm
diff options
context:
space:
mode:
Diffstat (limited to 'browser/components/pocket/content/pktTelemetry.jsm')
-rw-r--r--browser/components/pocket/content/pktTelemetry.jsm125
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()
+ );
+ },
+};