Skip to content

Commit

Permalink
(8.5.4) GH-2153: Future-proof metrics uninstall URL (#615)
Browse files Browse the repository at this point in the history
* Use only crucial params for uninstall type

* Move some query string construction to helper

* Group METRICS_URL_SET with other consts

* Syntax fix

Co-authored-by: Ilya Zarembsky <ilya.zarembsky@gmail.com>
Co-authored-by: Christopher Tino <4699516+christophertino@users.noreply.github.com>
  • Loading branch information
3 people committed Oct 26, 2020
1 parent f3502fc commit 86b4f20
Showing 1 changed file with 77 additions and 61 deletions.
138 changes: 77 additions & 61 deletions src/classes/Metrics.js
Expand Up @@ -27,6 +27,16 @@ const CRITICAL_METRICS = ['install', 'install_complete', 'upgrade', 'active', 'e
const CAMPAIGN_METRICS = ['install', 'active', 'uninstall'];
const { METRICS_BASE_URL, EXTENSION_VERSION, BROWSER_INFO } = globals;
const MAX_DELAYED_PINGS = 100;
// Set of conf keys used in constructing telemetry url
const METRICS_URL_SET = new Set([
'enable_human_web',
'enable_offers',
'account',
'enable_metrics',
'show_alert',
'alert_expanded',
'show_cmp'
]);

/**
* Class for handling telemetry pings.
Expand Down Expand Up @@ -190,27 +200,26 @@ class Metrics {
* @param {string} conf key being changed
*/
setUninstallUrl(key) {
if (typeof chrome.runtime.setUninstallURL === 'function') {
// Set of conf keys used in constructing telemetry url
const METRICS_URL_SET = new Set([
'enable_human_web',
'enable_offers',
'account',
'enable_metrics',
'show_alert',
'alert_expanded',
'show_cmp'
]);

if (!key || METRICS_URL_SET.has(key)) {
const metrics_url = this._buildMetricsUrl('uninstall');
if (metrics_url.length) {
chrome.runtime.setUninstallURL(metrics_url);
}
if (typeof chrome.runtime.setUninstallURL === 'function' && (!key || METRICS_URL_SET.has(key))) {
const metrics_url = this._buildMetricsUrl('uninstall');
if (metrics_url.length) {
chrome.runtime.setUninstallURL(metrics_url);
}
}
}

/**
* Helper for building query string key value pairs
*
* @private
*
* @since 8.5.4
* @param {string} query param to be included in string
* @param {string} value number value to be passed on through qeury string
* @return {string} complete query component
*/
_buildQueryPair = (query, value) => `&${query}=${encodeURIComponent(value)}`;

/**
* Build telemetry URL
*
Expand All @@ -223,87 +232,94 @@ class Metrics {
_buildMetricsUrl(type, frequency) {
const frequencyString = (type !== 'uninstall') ? `/${frequency}` : '';

let metrics_url = `${METRICS_BASE_URL}/${type}${frequencyString}?gr=-1` +
// Old parameters, old names
// Human web
`&hw=${encodeURIComponent(conf.enable_human_web ? '1' : '0')}` +
let metrics_url = `${METRICS_BASE_URL}/${type}${frequencyString}?gr=-1`;
metrics_url +=
// Crucial parameters
// Always added for uninstall URL
// Extension version
`&v=${encodeURIComponent(EXTENSION_VERSION)}` +
this._buildQueryPair('v', EXTENSION_VERSION) +
// User agent - browser
`&ua=${encodeURIComponent(BROWSER_INFO.token)}` +
this._buildQueryPair('ua', BROWSER_INFO.token) +
// Operating system
`&os=${encodeURIComponent(BROWSER_INFO.os)}` +
this._buildQueryPair('os', BROWSER_INFO.os) +
// Browser language
`&l=${encodeURIComponent(conf.language)}` +
this._buildQueryPair('l', conf.language) +
// Browser version
`&bv=${encodeURIComponent(BROWSER_INFO.version)}` +
this._buildQueryPair('bv', BROWSER_INFO.version) +
// Offers (former offers)
this._buildQueryPair('of', conf.enable_offers ? '1' : '0') +
// Date of install (former install_date)
this._buildQueryPair('id', conf.install_date) +
// Showing campaign messages (former show_cmp)
this._buildQueryPair('sc', conf.show_cmp ? '1' : '0') +
// Subscription Type
this._buildQueryPair('st', Metrics._getSubscriptionType().toString()) +

// New parameters for Ghostery 8.5.2
// Subscription Interval
this._buildQueryPair('si', Metrics._getSubscriptionInterval().toString()) +
// Product ID Parameter
this._buildQueryPair('pi', 'gbe');

if (type !== 'uninstall') {
metrics_url +=
// Old parameters, old names
// Human web
this._buildQueryPair('hw', conf.enable_human_web ? '1' : '0') +
// Old parameters, new names
// Offers (former offers)
`&of=${encodeURIComponent(conf.enable_offers ? '1' : '0')}` +
// Random number, assigned at install (former install_rand)
`&ir=${encodeURIComponent(conf.install_random_number)}` +
this._buildQueryPair('ir', conf.install_random_number) +
// Login state (former signed_in)
`&sn=${encodeURIComponent(conf.account ? '1' : '0')}` +
// Date of install (former install_date)
`&id=${encodeURIComponent(conf.install_date)}` +
this._buildQueryPair('sn', conf.account ? '1' : '0') +
// Noncritical ping (former noncritical)
`&nc=${encodeURIComponent(conf.enable_metrics ? '1' : '0')}` +
this._buildQueryPair('nc', conf.enable_metrics ? '1' : '0') +
// Purplebox state (former purplebox)
`&pb=${encodeURIComponent(conf.show_alert ? (conf.alert_expanded ? '1' : '2') : '0')}` +
// Showing campaign messages (former show_cmp)
`&sc=${encodeURIComponent(conf.show_cmp ? '1' : '0')}` +
this._buildQueryPair('pb', conf.show_alert ? (conf.alert_expanded ? '1' : '2') : '0') +

// New parameters, new names
// Extension_view - which view of the extension is the user in
`&ev=${encodeURIComponent(conf.is_expert ? (conf.is_expanded ? '3' : '2') : '1')}` +
this._buildQueryPair('ev', conf.is_expert ? (conf.is_expanded ? '3' : '2') : '1') +
// Adblocking state
`&ab=${encodeURIComponent(conf.enable_ad_block ? '1' : '0')}` +
this._buildQueryPair('ab', conf.enable_ad_block ? '1' : '0') +
// Smartblocking state
`&sm=${encodeURIComponent(conf.enable_smart_block ? '1' : '0')}` +
this._buildQueryPair('sm', conf.enable_smart_block ? '1' : '0') +
// Antitracking state
`&at=${encodeURIComponent(conf.enable_anti_tracking ? '1' : '0')}` +
this._buildQueryPair('at', conf.enable_anti_tracking ? '1' : '0') +
// The deepest setup page reached by user during setup
`&ss=${encodeURIComponent((conf.metrics.install_complete_all || type === 'install_complete') ? conf.setup_step.toString() : '-1')}` +
this._buildQueryPair('ss', (conf.metrics.install_complete_all || type === 'install_complete') ? conf.setup_step.toString() : '-1') +
// The number of times the user has gone through setup
`&sl=${encodeURIComponent(conf.setup_number.toString())}` +
this._buildQueryPair('sl', conf.setup_number.toString()) +
// Type of blocking selected during setup
`&sb=${encodeURIComponent(conf.setup_block.toString())}` +
this._buildQueryPair('sb', conf.setup_block.toString()) +
// Recency, days since last active daily ping
`&rc=${encodeURIComponent(Metrics._getRecencyActive(type, frequency).toString())}` +
this._buildQueryPair('rc', Metrics._getRecencyActive(type, frequency).toString()) +

// New parameters to Ghostery 8.3
// Subscription Type
`&st=${encodeURIComponent(Metrics._getSubscriptionType().toString())}` +
// Whether the computer ever had a Paid Subscription
`&ps=${encodeURIComponent(conf.paid_subscription ? '1' : '0')}` +
this._buildQueryPair('ps', conf.paid_subscription ? '1' : '0') +
// Active Velocity
`&va=${encodeURIComponent(Metrics._getVelocityActive(type).toString())}` +
this._buildQueryPair('va', Metrics._getVelocityActive(type).toString()) +
// Engaged Recency
`&re=${encodeURIComponent(Metrics._getRecencyEngaged(type, frequency).toString())}` +
this._buildQueryPair('re', Metrics._getRecencyEngaged(type, frequency).toString()) +
// Engaged Velocity
`&ve=${encodeURIComponent(Metrics._getVelocityEngaged(type).toString())}` +
this._buildQueryPair('ve', Metrics._getVelocityEngaged(type).toString()) +
// Theme
`&th=${encodeURIComponent(Metrics._getThemeValue().toString())}` +

// New parameters for Ghostery 8.5.2
// Subscription Interval
`&si=${encodeURIComponent(Metrics._getSubscriptionInterval().toString())}` +
// Product ID Parameter
`&pi=${encodeURIComponent('gbe')}` +
this._buildQueryPair('th', Metrics._getThemeValue().toString()) +

// New parameter for Ghostery 8.5.3
// AB tests enabled?
`&ts=${encodeURIComponent(conf.enable_abtests ? '1' : '0')}`;
this._buildQueryPair('ts', conf.enable_abtests ? '1' : '0');
}

if (CAMPAIGN_METRICS.includes(type)) {
if (CAMPAIGN_METRICS.includes(type) || type === 'uninstall') {
// only send campaign attribution when necessary
metrics_url +=
// Marketing source (Former utm_source)
`&us=${encodeURIComponent(this.utm_source)}` +
this._buildQueryPair('us', this.utm_source) +
// Marketing campaign (Former utm_campaign)
`&uc=${encodeURIComponent(this.utm_campaign)}`;
this._buildQueryPair('uc', this.utm_campaign);
}

return metrics_url;
}

Expand Down

0 comments on commit 86b4f20

Please sign in to comment.