mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-11-25 03:20:23 +01:00
remove matomo and route to segment (#9646)
This commit is contained in:
parent
379950d53f
commit
7d50357684
@ -1,14 +0,0 @@
|
||||
import { getBackgroundMetaMetricState } from '../../../ui/app/selectors'
|
||||
import { sendMetaMetricsEvent } from '../../../ui/app/helpers/utils/metametrics.util'
|
||||
|
||||
export default function backgroundMetaMetricsEvent (metaMaskState, version, eventData) {
|
||||
const stateEventData = getBackgroundMetaMetricState({ metamask: metaMaskState })
|
||||
if (stateEventData.participateInMetaMetrics) {
|
||||
sendMetaMetricsEvent({
|
||||
...stateEventData,
|
||||
...eventData,
|
||||
version,
|
||||
currentPath: '/background',
|
||||
})
|
||||
}
|
||||
}
|
@ -25,6 +25,7 @@ import {
|
||||
PhishingController,
|
||||
} from '@metamask/controllers'
|
||||
import { getTrackMetaMetricsEvent } from '../../shared/modules/metametrics'
|
||||
import { getBackgroundMetaMetricState } from '../../ui/app/selectors'
|
||||
import ComposableObservableStore from './lib/ComposableObservableStore'
|
||||
import AccountTracker from './lib/account-tracker'
|
||||
import createLoggerMiddleware from './lib/createLoggerMiddleware'
|
||||
@ -56,8 +57,6 @@ import getRestrictedMethods from './controllers/permissions/restrictedMethods'
|
||||
import nodeify from './lib/nodeify'
|
||||
import accountImporter from './account-import-strategies'
|
||||
import seedPhraseVerifier from './lib/seed-phrase-verifier'
|
||||
|
||||
import backgroundMetaMetricsEvent from './lib/background-metametrics'
|
||||
import { ENVIRONMENT_TYPE_BACKGROUND } from './lib/enums'
|
||||
|
||||
export default class MetamaskController extends EventEmitter {
|
||||
@ -1893,19 +1892,18 @@ export default class MetamaskController extends EventEmitter {
|
||||
}
|
||||
|
||||
const metamaskState = await this.getState()
|
||||
const version = this.platform.getVersion()
|
||||
backgroundMetaMetricsEvent(
|
||||
metamaskState,
|
||||
version,
|
||||
{
|
||||
customVariables,
|
||||
eventOpts: {
|
||||
action,
|
||||
category: 'Background',
|
||||
name,
|
||||
},
|
||||
const additionalProperties = getBackgroundMetaMetricState(metamaskState)
|
||||
|
||||
this.trackMetaMetricsEvent({
|
||||
event: name,
|
||||
category: 'Background',
|
||||
matomoEvent: true,
|
||||
properties: {
|
||||
action,
|
||||
...additionalProperties,
|
||||
...customVariables,
|
||||
},
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -18,6 +18,7 @@ const { makeStringTransform } = require('browserify-transform-tools')
|
||||
const conf = require('rc')('metamask', {
|
||||
INFURA_PROJECT_ID: process.env.INFURA_PROJECT_ID,
|
||||
SEGMENT_WRITE_KEY: process.env.SEGMENT_WRITE_KEY,
|
||||
SEGMENT_LEGACY_WRITE_KEY: process.env.SEGMENT_LEGACY_WRITE_KEY,
|
||||
})
|
||||
|
||||
const packageJSON = require('../../package.json')
|
||||
@ -324,6 +325,7 @@ function createScriptTasks ({ browserPlatforms, livereload }) {
|
||||
// inflating event volume.
|
||||
const SEGMENT_PROD_WRITE_KEY = opts.testing ? undefined : process.env.SEGMENT_PROD_WRITE_KEY
|
||||
const SEGMENT_DEV_WRITE_KEY = opts.testing ? undefined : conf.SEGMENT_WRITE_KEY
|
||||
const SEGMENT_LEGACY_WRITE_KEY = opts.testing ? undefined : conf.SEGMENT_LEGACY_WRITE_KEY
|
||||
|
||||
// Inject variables into bundle
|
||||
bundler.transform(envify({
|
||||
@ -343,6 +345,7 @@ function createScriptTasks ({ browserPlatforms, livereload }) {
|
||||
: conf.INFURA_PROJECT_ID
|
||||
),
|
||||
SEGMENT_WRITE_KEY: environment === 'production' ? SEGMENT_PROD_WRITE_KEY : SEGMENT_DEV_WRITE_KEY,
|
||||
SEGMENT_LEGACY_WRITE_KEY: environment === 'production' ? process.env.SEGMENT_LEGACY_WRITE_KEY : SEGMENT_LEGACY_WRITE_KEY,
|
||||
}), {
|
||||
global: true,
|
||||
})
|
||||
|
@ -1,72 +0,0 @@
|
||||
## Creating Metrics Events
|
||||
|
||||
The `metricsEvent` method is made available to all components via context. This is done in `metamask-extension/ui/app/helpers/higher-order-components/metametrics/metametrics.provider.js`. As such, it can be called in all components by first adding it to the context proptypes:
|
||||
|
||||
```
|
||||
static contextTypes = {
|
||||
t: PropTypes.func,
|
||||
metricsEvent: PropTypes.func,
|
||||
}
|
||||
```
|
||||
|
||||
and then accessing it on `this.context`.
|
||||
|
||||
Below is an example of a metrics event call:
|
||||
|
||||
```
|
||||
this.context.metricsEvent({
|
||||
eventOpts: {
|
||||
category: 'Navigation',
|
||||
action: 'Main Menu',
|
||||
name: 'Switched Account',
|
||||
},
|
||||
})
|
||||
```
|
||||
|
||||
### Base Schema
|
||||
|
||||
Every `metricsEvent` call is passed an object that must have an `eventOpts` property. This property is an object that itself must have three properties:
|
||||
- category: categorizes events according to the schema we have set up in our matomo.org instance
|
||||
- action: usually describes the page on which the event takes place, or sometimes a significant subsections of a page
|
||||
- name: a very specific descriptor of the event
|
||||
|
||||
### Implicit properties
|
||||
|
||||
All metrics events send the following data when called:
|
||||
- network
|
||||
- environmentType
|
||||
- activeCurrency
|
||||
- accountType
|
||||
- numberOfTokens
|
||||
- numberOfAccounts
|
||||
- version
|
||||
|
||||
These are added to the metrics event via the metametrics provider.
|
||||
|
||||
### Custom Variables
|
||||
|
||||
Metrics events can include custom variables. These are included within the `customVariables` property that is a first-level property within first param passed to `metricsEvent`.
|
||||
|
||||
For example:
|
||||
```
|
||||
this.context.metricsEvent({
|
||||
eventOpts: {
|
||||
category: 'Settings',
|
||||
action: 'Custom RPC',
|
||||
name: 'Error',
|
||||
},
|
||||
customVariables: {
|
||||
networkId: newRpc,
|
||||
chainId,
|
||||
},
|
||||
})
|
||||
```
|
||||
|
||||
Custom variables can have custom property names and values can be strings or numbers.
|
||||
|
||||
**To include a custom variable, there are a set of necessary steps you must take.**
|
||||
|
||||
1. First you must declare a constant equal to the desired name of the custom variable property in `metamask-extension/ui/app/helpers/utils/metametrics.util.js` under `//Custom Variable Declarations`
|
||||
1. Then you must add that name to the `customVariableNameIdMap` declaration
|
||||
1. The id must be between 1 and 5
|
||||
1. There can be no more than 5 custom variables assigned ids on a given url
|
@ -198,6 +198,7 @@
|
||||
"@storybook/storybook-deployer": "^2.8.6",
|
||||
"@testing-library/react": "^10.4.8",
|
||||
"@testing-library/react-hooks": "^3.2.1",
|
||||
"@types/react": "^16.9.53",
|
||||
"addons-linter": "1.14.0",
|
||||
"babel-loader": "^8.0.6",
|
||||
"babelify": "^10.0.0",
|
||||
|
@ -57,6 +57,10 @@ export const segment = process.env.SEGMENT_WRITE_KEY
|
||||
? new Analytics(process.env.SEGMENT_WRITE_KEY, { flushAt })
|
||||
: segmentNoop
|
||||
|
||||
export const segmentLegacy = process.env.SEGMENT_LEGACY_WRITE_KEY
|
||||
? new Analytics(process.env.SEGMENT_LEGACY_WRITE_KEY, { flushAt })
|
||||
: segmentNoop
|
||||
|
||||
/**
|
||||
* We attach context to every meta metrics event that help to qualify our analytics.
|
||||
* This type has all optional values because it represents a returned object from a
|
||||
@ -111,6 +115,12 @@ export const segment = process.env.SEGMENT_WRITE_KEY
|
||||
* @property {string} [currency] - ISO 4127 format currency for events with revenue, defaults to US dollars
|
||||
* @property {number} [value] - Abstract "value" that this event has for MetaMask.
|
||||
* @property {boolean} [excludeMetaMetricsId] - whether to exclude the user's metametrics id for anonymity
|
||||
* @property {string} [metaMetricsId] - an override for the metaMetricsId in the event one is created as part
|
||||
* of an asynchronous workflow, such as awaiting the result of the metametrics opt-in function that generates the
|
||||
* user's metametrics id.
|
||||
* @property {boolean} [matomoEvent] - is this event a holdover from matomo that needs further migration?
|
||||
* when true, sends the data to a special segment source that marks the event data as not conforming to our
|
||||
* ideal schema
|
||||
* @property {MetaMetricsDynamicContext} [eventContext] - additional context to attach to event
|
||||
*/
|
||||
|
||||
@ -137,7 +147,9 @@ export function getTrackMetaMetricsEvent (
|
||||
revenue,
|
||||
currency,
|
||||
value,
|
||||
metaMetricsId: metaMetricsIdOverride,
|
||||
excludeMetaMetricsId: excludeId,
|
||||
matomoEvent = false,
|
||||
eventContext = {},
|
||||
}) {
|
||||
if (!event || !category) {
|
||||
@ -199,8 +211,20 @@ export function getTrackMetaMetricsEvent (
|
||||
context,
|
||||
}
|
||||
|
||||
// If we are tracking sensitive data we will always use the anonymousId property
|
||||
// as well as our METAMETRICS_ANONYMOUS_ID. This prevents us from associating potentially
|
||||
// identifiable information with a specific id. During the opt in flow we will track all
|
||||
// events, but do so with the anonymous id. The one exception to that rule is after the
|
||||
// user opts in to MetaMetrics. When that happens we receive back the user's new MetaMetrics
|
||||
// id before it is fully persisted to state. To avoid a race condition we explicitly pass the
|
||||
// new id to the track method. In that case we will track the opt in event to the user's id.
|
||||
// In all other cases we use the metaMetricsId from state.
|
||||
if (excludeMetaMetricsId) {
|
||||
trackOptions.anonymousId = METAMETRICS_ANONYMOUS_ID
|
||||
} else if (isOptIn && metaMetricsIdOverride) {
|
||||
trackOptions.userId = metaMetricsIdOverride
|
||||
} else if (isOptIn) {
|
||||
trackOptions.anonymousId = METAMETRICS_ANONYMOUS_ID
|
||||
} else {
|
||||
trackOptions.userId = metaMetricsId
|
||||
}
|
||||
@ -210,12 +234,18 @@ export function getTrackMetaMetricsEvent (
|
||||
// If flushAt is greater than one the callback won't be triggered until after a number
|
||||
// of events have been queued equal to the flushAt value OR flushInterval passes. The
|
||||
// default flushInterval is ten seconds
|
||||
segment.track(trackOptions, (err) => {
|
||||
const callback = (err) => {
|
||||
if (err) {
|
||||
return reject(err)
|
||||
}
|
||||
return resolve()
|
||||
})
|
||||
}
|
||||
|
||||
if (matomoEvent === true) {
|
||||
segmentLegacy.track(trackOptions, callback)
|
||||
} else {
|
||||
segment.track(trackOptions, callback)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { Component, createContext, useEffect, useCallback, useState } from 'react'
|
||||
import React, { Component, createContext, useEffect, useCallback, useState, useMemo } from 'react'
|
||||
import { useSelector } from 'react-redux'
|
||||
import PropTypes from 'prop-types'
|
||||
import { useHistory } from 'react-router-dom'
|
||||
@ -9,16 +9,15 @@ import {
|
||||
getAccountType,
|
||||
getNumberOfAccounts,
|
||||
getNumberOfTokens,
|
||||
getCurrentChainId,
|
||||
} from '../selectors/selectors'
|
||||
import { getSendToken } from '../selectors/send'
|
||||
import {
|
||||
txDataSelector,
|
||||
} from '../selectors/confirm-transaction'
|
||||
import { getEnvironmentType } from '../../../app/scripts/lib/util'
|
||||
import {
|
||||
sendMetaMetricsEvent,
|
||||
} from '../helpers/utils/metametrics.util'
|
||||
import { sendCountIsTrackable } from '../../../shared/modules/metametrics'
|
||||
import { getTrackMetaMetricsEvent } from '../../../shared/modules/metametrics'
|
||||
import { getCurrentLocale } from '../ducks/metamask/metamask'
|
||||
|
||||
export const MetaMetricsContext = createContext(() => {
|
||||
captureException(
|
||||
@ -30,6 +29,8 @@ export function MetaMetricsProvider ({ children }) {
|
||||
const txData = useSelector(txDataSelector) || {}
|
||||
const network = useSelector(getCurrentNetworkId)
|
||||
const environmentType = getEnvironmentType()
|
||||
const chainId = useSelector(getCurrentChainId)
|
||||
const locale = useSelector(getCurrentLocale)
|
||||
const activeCurrency = useSelector(getSendToken)?.symbol
|
||||
const accountType = useSelector(getAccountType)
|
||||
const confirmTransactionOrigin = txData.origin
|
||||
@ -44,7 +45,7 @@ export function MetaMetricsProvider ({ children }) {
|
||||
previousPath: '',
|
||||
}))
|
||||
|
||||
const { previousPath, currentPath } = state
|
||||
const { currentPath } = state
|
||||
|
||||
useEffect(() => {
|
||||
const unlisten = history.listen(() => setState((prevState) => ({
|
||||
@ -55,45 +56,63 @@ export function MetaMetricsProvider ({ children }) {
|
||||
return unlisten
|
||||
}, [history])
|
||||
|
||||
/**
|
||||
* track a metametrics event
|
||||
*
|
||||
* @param {import('../../../shared/modules/metametrics').MetaMetricsEventPayload} - payload for event
|
||||
* @returns undefined
|
||||
*/
|
||||
const trackEvent = useMemo(() => {
|
||||
const referrer = confirmTransactionOrigin ? { url: confirmTransactionOrigin } : undefined
|
||||
const page = {
|
||||
path: currentPath,
|
||||
}
|
||||
return getTrackMetaMetricsEvent(global.platform.getVersion(), () => ({
|
||||
context: {
|
||||
referrer,
|
||||
page,
|
||||
},
|
||||
environmentType,
|
||||
locale: locale.replace('_', '-'),
|
||||
network,
|
||||
chainId,
|
||||
participateInMetaMetrics,
|
||||
metaMetricsId,
|
||||
metaMetricsSendCount,
|
||||
}))
|
||||
}, [network, chainId, locale, environmentType, participateInMetaMetrics, currentPath, confirmTransactionOrigin, metaMetricsId, metaMetricsSendCount])
|
||||
|
||||
const metricsEvent = useCallback((config = {}, overrides = {}) => {
|
||||
const { eventOpts = {} } = config
|
||||
const { name = '' } = eventOpts
|
||||
const { currentPath: overrideCurrentPath = '' } = overrides
|
||||
const isSendFlow = Boolean(name.match(/^send|^confirm/u) || overrideCurrentPath.match(/send|confirm/u))
|
||||
|
||||
if (participateInMetaMetrics || config.isOptIn) {
|
||||
return sendMetaMetricsEvent({
|
||||
network,
|
||||
environmentType,
|
||||
activeCurrency,
|
||||
accountType,
|
||||
confirmTransactionOrigin,
|
||||
metaMetricsId,
|
||||
numberOfTokens,
|
||||
numberOfAccounts,
|
||||
version: global.platform.getVersion(),
|
||||
...config,
|
||||
previousPath,
|
||||
currentPath,
|
||||
excludeMetaMetricsId: isSendFlow && !sendCountIsTrackable(metaMetricsSendCount + 1),
|
||||
...overrides,
|
||||
})
|
||||
}
|
||||
|
||||
return undefined
|
||||
return trackEvent({
|
||||
event: eventOpts.name,
|
||||
category: eventOpts.category,
|
||||
isOptIn: config.isOptIn,
|
||||
excludeMetaMetricsId: eventOpts.excludeMetaMetricsId ?? overrides.excludeMetaMetricsId ?? false,
|
||||
metaMetricsId: config.metaMetricsId,
|
||||
matomoEvent: true,
|
||||
properties: {
|
||||
action: eventOpts.action,
|
||||
number_of_tokens: numberOfTokens,
|
||||
number_of_accounts: numberOfAccounts,
|
||||
active_currency: activeCurrency,
|
||||
account_type: accountType,
|
||||
is_new_visit: config.is_new_visit,
|
||||
// the properties coming from this key will not match our standards for
|
||||
// snake_case on properties, and they may be redundant and/or not in the
|
||||
// proper location (origin not as a referrer, for example). This is a temporary
|
||||
// solution to not lose data, and the entire event system will be reworked in
|
||||
// forthcoming PRs to deprecate the old Matomo events in favor of the new schema.
|
||||
...config.customVariables,
|
||||
},
|
||||
})
|
||||
}, [
|
||||
network,
|
||||
environmentType,
|
||||
activeCurrency,
|
||||
accountType,
|
||||
confirmTransactionOrigin,
|
||||
participateInMetaMetrics,
|
||||
previousPath,
|
||||
metaMetricsId,
|
||||
activeCurrency,
|
||||
numberOfTokens,
|
||||
numberOfAccounts,
|
||||
currentPath,
|
||||
metaMetricsSendCount,
|
||||
trackEvent,
|
||||
])
|
||||
|
||||
return (
|
||||
|
@ -1,216 +0,0 @@
|
||||
/* eslint camelcase: 0 */
|
||||
|
||||
import ethUtil from 'ethereumjs-util'
|
||||
|
||||
const inDevelopment = process.env.METAMASK_DEBUG || process.env.IN_TEST
|
||||
|
||||
let projectId = process.env.METAMETRICS_PROJECT_ID
|
||||
if (!projectId) {
|
||||
projectId = inDevelopment ? 1 : 2
|
||||
}
|
||||
|
||||
const METAMETRICS_BASE_URL = 'https://chromeextensionmm.innocraft.cloud/piwik.php'
|
||||
const METAMETRICS_REQUIRED_PARAMS = `?idsite=${projectId}&rec=1&apiv=1`
|
||||
const METAMETRICS_BASE_FULL = METAMETRICS_BASE_URL + METAMETRICS_REQUIRED_PARAMS
|
||||
|
||||
const METAMETRICS_TRACKING_URL = inDevelopment
|
||||
? 'http://www.metamask.io/metametrics'
|
||||
: 'http://www.metamask.io/metametrics-prod'
|
||||
|
||||
/** ***************Custom variables*************** **/
|
||||
// Custom variable declarations
|
||||
const METAMETRICS_CUSTOM_GAS_LIMIT_CHANGE = 'gasLimitChange'
|
||||
const METAMETRICS_CUSTOM_GAS_PRICE_CHANGE = 'gasPriceChange'
|
||||
const METAMETRICS_CUSTOM_FUNCTION_TYPE = 'functionType'
|
||||
const METAMETRICS_CUSTOM_RECIPIENT_KNOWN = 'recipientKnown'
|
||||
const METAMETRICS_REQUEST_ORIGIN = 'origin'
|
||||
const METAMETRICS_CUSTOM_FROM_NETWORK = 'fromNetwork'
|
||||
const METAMETRICS_CUSTOM_TO_NETWORK = 'toNetwork'
|
||||
const METAMETRICS_CUSTOM_ERROR_FIELD = 'errorField'
|
||||
const METAMETRICS_CUSTOM_ERROR_MESSAGE = 'errorMessage'
|
||||
const METAMETRICS_CUSTOM_RPC_NETWORK_ID = 'networkId'
|
||||
const METAMETRICS_CUSTOM_RPC_CHAIN_ID = 'chainId'
|
||||
const METAMETRICS_CUSTOM_GAS_CHANGED = 'gasChanged'
|
||||
const METAMETRICS_CUSTOM_ASSET_SELECTED = 'assetSelected'
|
||||
|
||||
const customVariableNameIdMap = {
|
||||
[METAMETRICS_CUSTOM_FUNCTION_TYPE]: 1,
|
||||
[METAMETRICS_CUSTOM_RECIPIENT_KNOWN]: 2,
|
||||
[METAMETRICS_REQUEST_ORIGIN]: 3,
|
||||
[METAMETRICS_CUSTOM_GAS_LIMIT_CHANGE]: 4,
|
||||
[METAMETRICS_CUSTOM_GAS_PRICE_CHANGE]: 5,
|
||||
|
||||
[METAMETRICS_CUSTOM_FROM_NETWORK]: 1,
|
||||
[METAMETRICS_CUSTOM_TO_NETWORK]: 2,
|
||||
|
||||
[METAMETRICS_CUSTOM_RPC_NETWORK_ID]: 1,
|
||||
[METAMETRICS_CUSTOM_RPC_CHAIN_ID]: 2,
|
||||
|
||||
[METAMETRICS_CUSTOM_ERROR_FIELD]: 3,
|
||||
[METAMETRICS_CUSTOM_ERROR_MESSAGE]: 4,
|
||||
|
||||
[METAMETRICS_CUSTOM_GAS_CHANGED]: 1,
|
||||
[METAMETRICS_CUSTOM_ASSET_SELECTED]: 2,
|
||||
}
|
||||
|
||||
/** ********************************************************** **/
|
||||
|
||||
const METAMETRICS_CUSTOM_NETWORK = 'network'
|
||||
const METAMETRICS_CUSTOM_ENVIRONMENT_TYPE = 'environmentType'
|
||||
const METAMETRICS_CUSTOM_ACTIVE_CURRENCY = 'activeCurrency'
|
||||
const METAMETRICS_CUSTOM_ACCOUNT_TYPE = 'accountType'
|
||||
const METAMETRICS_CUSTOM_NUMBER_OF_ACCOUNTS = 'numberOfAccounts'
|
||||
const METAMETRICS_CUSTOM_NUMBER_OF_TOKENS = 'numberOfTokens'
|
||||
const METAMETRICS_CUSTOM_VERSION = 'version'
|
||||
|
||||
const customDimensionsNameIdMap = {
|
||||
[METAMETRICS_CUSTOM_NETWORK]: 5,
|
||||
[METAMETRICS_CUSTOM_ENVIRONMENT_TYPE]: 6,
|
||||
[METAMETRICS_CUSTOM_ACTIVE_CURRENCY]: 7,
|
||||
[METAMETRICS_CUSTOM_ACCOUNT_TYPE]: 8,
|
||||
[METAMETRICS_CUSTOM_NUMBER_OF_ACCOUNTS]: 9,
|
||||
[METAMETRICS_CUSTOM_NUMBER_OF_TOKENS]: 10,
|
||||
[METAMETRICS_CUSTOM_VERSION]: 11,
|
||||
}
|
||||
|
||||
function composeUrlRefParamAddition (previousPath, confirmTransactionOrigin) {
|
||||
const externalOrigin = confirmTransactionOrigin && confirmTransactionOrigin !== 'metamask'
|
||||
return `&urlref=${externalOrigin ? 'EXTERNAL' : encodeURIComponent(`${METAMETRICS_TRACKING_URL}${previousPath}`)}`
|
||||
}
|
||||
|
||||
// composes query params of the form &dimension[0-999]=[value]
|
||||
function composeCustomDimensionParamAddition (customDimensions) {
|
||||
const customDimensionParamStrings = Object.keys(customDimensions).reduce((acc, name) => {
|
||||
return [...acc, `dimension${customDimensionsNameIdMap[name]}=${customDimensions[name]}`]
|
||||
}, [])
|
||||
return `&${customDimensionParamStrings.join('&')}`
|
||||
}
|
||||
|
||||
// composes query params in form: &cvar={[id]:[[name],[value]]}
|
||||
// Example: &cvar={"1":["OS","iphone 5.0"],"2":["Matomo Mobile Version","1.6.2"],"3":["Locale","en::en"],"4":["Num Accounts","2"]}
|
||||
function composeCustomVarParamAddition (customVariables) {
|
||||
const customVariableIdValuePairs = Object.keys(customVariables).reduce((acc, name) => {
|
||||
return {
|
||||
[customVariableNameIdMap[name]]: [name, customVariables[name]],
|
||||
...acc,
|
||||
}
|
||||
}, {})
|
||||
return `&cvar=${encodeURIComponent(JSON.stringify(customVariableIdValuePairs))}`
|
||||
}
|
||||
|
||||
function composeParamAddition (paramValue, paramName) {
|
||||
return paramValue !== 0 && !paramValue
|
||||
? ''
|
||||
: `&${paramName}=${paramValue}`
|
||||
}
|
||||
|
||||
/**
|
||||
* @name composeUrl
|
||||
* @param {Object} config - configuration object for composing the metametrics url
|
||||
* @property {object} config.eventOpts Object containing event category, action and name descriptors
|
||||
* @property {object} config.customVariables Object containing custom properties with values relevant to a specific event
|
||||
* @property {object} config.pageOpts Objects containing information about a page/route the event is dispatched from
|
||||
* @property {number} config.network The selected network of the user when the event occurs
|
||||
* @property {string} config.environmentType The "environment" the user is using the app from: 'popup', 'notification' or 'fullscreen'
|
||||
* @property {string} config.activeCurrency The current the user has select as their primary currency at the time of the event
|
||||
* @property {string} config.accountType The account type being used at the time of the event: 'hardware', 'imported' or 'default'
|
||||
* @property {number} config.numberOfTokens The number of tokens that the user has added at the time of the event
|
||||
* @property {number} config.numberOfAccounts The number of accounts the user has added at the time of the event
|
||||
* @property {string} config.version The current version of the MetaMask extension
|
||||
* @property {string} config.previousPath The pathname of the URL the user was on prior to the URL they are on at the time of the event
|
||||
* @property {string} config.currentPath The pathname of the URL the user is on at the time of the event
|
||||
* @property {string} config.metaMetricsId A random id assigned to a user at the time of opting in to metametrics. A hexadecimal number
|
||||
* @property {string} config.confirmTransactionOrigin The origin on a transaction
|
||||
* @property {boolean} config.excludeMetaMetricsId Whether or not the tracked event data should be associated with a metametrics id
|
||||
* @property {boolean} config.isNewVisit Whether or not the event should be tracked as a new visit/user sessions
|
||||
* @returns {string} - Returns a url to be passed to fetch to make the appropriate request to matomo.
|
||||
* Example: https://chromeextensionmm.innocraft.cloud/piwik.php?idsite=1&rec=1&apiv=1&e_c=Navigation&e_a=Home&e_n=Clicked%20Send:%20Eth&urlref=http%3A%2F%2Fwww.metamask.io%2Fmetametrics%2Fhome.html%23send&dimension5=3&dimension6=fullscreen&dimension7=ETH&dimension8=default&dimension9=0&dimension10=3&url=http%3A%2F%2Fwww.metamask.io%2Fmetametrics%2Fhome.html%23&_id=49c10aff19795e9a&rand=7906028754863992&pv_id=53acad&uid=49c1
|
||||
*/
|
||||
function composeUrl (config) {
|
||||
const {
|
||||
eventOpts = {},
|
||||
customVariables = '',
|
||||
pageOpts = '',
|
||||
network,
|
||||
environmentType,
|
||||
activeCurrency,
|
||||
accountType,
|
||||
numberOfTokens,
|
||||
numberOfAccounts,
|
||||
version,
|
||||
previousPath = '',
|
||||
currentPath,
|
||||
metaMetricsId,
|
||||
confirmTransactionOrigin,
|
||||
excludeMetaMetricsId,
|
||||
isNewVisit,
|
||||
} = config
|
||||
const base = METAMETRICS_BASE_FULL
|
||||
|
||||
const e_c = composeParamAddition(eventOpts.category, 'e_c')
|
||||
const e_a = composeParamAddition(eventOpts.action, 'e_a')
|
||||
const e_n = composeParamAddition(eventOpts.name, 'e_n')
|
||||
const new_visit = isNewVisit ? `&new_visit=1` : ''
|
||||
|
||||
const cvar = (customVariables && composeCustomVarParamAddition(customVariables)) || ''
|
||||
|
||||
const action_name = ''
|
||||
|
||||
const urlref = previousPath && composeUrlRefParamAddition(previousPath, confirmTransactionOrigin)
|
||||
|
||||
const dimensions = pageOpts.hideDimensions
|
||||
? ''
|
||||
: (
|
||||
composeCustomDimensionParamAddition({
|
||||
network,
|
||||
environmentType,
|
||||
activeCurrency,
|
||||
accountType,
|
||||
version,
|
||||
numberOfTokens: (customVariables && customVariables.numberOfTokens) || numberOfTokens,
|
||||
numberOfAccounts: (customVariables && customVariables.numberOfAccounts) || numberOfAccounts,
|
||||
})
|
||||
)
|
||||
const url = currentPath ? `&url=${encodeURIComponent(`${METAMETRICS_TRACKING_URL}${currentPath}`)}` : ''
|
||||
const _id = metaMetricsId && !excludeMetaMetricsId ? `&_id=${metaMetricsId.slice(2, 18)}` : ''
|
||||
const rand = `&rand=${String(Math.random()).slice(2)}`
|
||||
const pv_id = currentPath ? `&pv_id=${ethUtil.bufferToHex(ethUtil.sha3(currentPath)).slice(2, 8)}` : ''
|
||||
|
||||
let uid = ''
|
||||
if (excludeMetaMetricsId) {
|
||||
uid = '&uid=0000000000000000'
|
||||
} else if (metaMetricsId) {
|
||||
uid = `&uid=${metaMetricsId.slice(2, 18)}`
|
||||
}
|
||||
|
||||
return [base, e_c, e_a, e_n, cvar, action_name, urlref, dimensions, url, _id, rand, pv_id, uid, new_visit].join('')
|
||||
}
|
||||
|
||||
export function sendMetaMetricsEvent (config) {
|
||||
return window.fetch(composeUrl(config), {
|
||||
'headers': {},
|
||||
'method': 'GET',
|
||||
})
|
||||
}
|
||||
|
||||
export function verifyUserPermission (config, props) {
|
||||
const {
|
||||
eventOpts = {},
|
||||
} = config
|
||||
const { userPermissionPreferences } = props
|
||||
const {
|
||||
allowAll,
|
||||
allowNone,
|
||||
allowSendMetrics,
|
||||
} = userPermissionPreferences
|
||||
|
||||
if (allowNone) {
|
||||
return false
|
||||
} else if (allowAll) {
|
||||
return true
|
||||
} else if (allowSendMetrics && eventOpts.name === 'send') {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
@ -101,12 +101,6 @@ export default class Routes extends Component {
|
||||
this.props.history.listen((locationObj, action) => {
|
||||
if (action === 'PUSH') {
|
||||
pageChanged(locationObj.pathname)
|
||||
this.context.metricsEvent({}, {
|
||||
currentPath: locationObj.pathname,
|
||||
pageOpts: {
|
||||
hideDimensions: true,
|
||||
},
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
18
yarn.lock
18
yarn.lock
@ -3063,6 +3063,11 @@
|
||||
resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.1.1.tgz#be148756d5480a84cde100324c03a86ae5739fb5"
|
||||
integrity sha512-2zs+O+UkDsJ1Vcp667pd3f8xearMdopz/z54i99wtRDI5KLmngk7vlrYZD0ZjKHaROR03EznlBbVY9PfAEyJIQ==
|
||||
|
||||
"@types/prop-types@*":
|
||||
version "15.7.3"
|
||||
resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.3.tgz#2ab0d5da2e5815f94b0b9d4b95d1e5f243ab2ca7"
|
||||
integrity sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw==
|
||||
|
||||
"@types/q@^1.5.1":
|
||||
version "1.5.2"
|
||||
resolved "https://registry.yarnpkg.com/@types/q/-/q-1.5.2.tgz#690a1475b84f2a884fd07cd797c00f5f31356ea8"
|
||||
@ -3118,6 +3123,14 @@
|
||||
dependencies:
|
||||
csstype "^2.2.0"
|
||||
|
||||
"@types/react@^16.9.53":
|
||||
version "16.9.53"
|
||||
resolved "https://registry.yarnpkg.com/@types/react/-/react-16.9.53.tgz#40cd4f8b8d6b9528aedd1fff8fcffe7a112a3d23"
|
||||
integrity sha512-4nW60Sd4L7+WMXH1D6jCdVftuW7j4Za6zdp6tJ33Rqv0nk1ZAmQKML9ZLD4H0dehA3FZxXR/GM8gXplf82oNGw==
|
||||
dependencies:
|
||||
"@types/prop-types" "*"
|
||||
csstype "^3.0.2"
|
||||
|
||||
"@types/redux@^3.6.0":
|
||||
version "3.6.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/redux/-/redux-3.6.0.tgz#f1ebe1e5411518072e4fdfca5c76e16e74c1399a"
|
||||
@ -8145,6 +8158,11 @@ csstype@^2.5.7:
|
||||
resolved "https://registry.yarnpkg.com/csstype/-/csstype-2.6.5.tgz#1cd1dff742ebf4d7c991470ae71e12bb6751e034"
|
||||
integrity sha512-JsTaiksRsel5n7XwqPAfB0l3TFKdpjW/kgAELf9vrb5adGA7UCPLajKK5s3nFrcFm3Rkyp/Qkgl73ENc1UY3cA==
|
||||
|
||||
csstype@^3.0.2:
|
||||
version "3.0.3"
|
||||
resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.0.3.tgz#2b410bbeba38ba9633353aff34b05d9755d065f8"
|
||||
integrity sha512-jPl+wbWPOWJ7SXsWyqGRk3lGecbar0Cb0OvZF/r/ZU011R4YqiRehgkQ9p4eQfo9DSDLqLL3wHwfxeJiuIsNag==
|
||||
|
||||
currency-formatter@^1.4.2:
|
||||
version "1.4.2"
|
||||
resolved "https://registry.yarnpkg.com/currency-formatter/-/currency-formatter-1.4.2.tgz#9da20b3706f7a42daf73b356b09a2a2b76ff3870"
|
||||
|
Loading…
Reference in New Issue
Block a user