-
Notifications
You must be signed in to change notification settings - Fork 250
/
tracking.js
195 lines (171 loc) · 5.89 KB
/
tracking.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
// @flow
import { type Disklet } from 'disklet'
import { type EdgeAccount } from 'edge-core-js/types'
import DeviceInfo from 'react-native-device-info'
import firebase from 'react-native-firebase'
import ENV from '../../env.json'
// Feel free to add new events at any time!
// This type is here so we know all the possible values:
type TrackingEvent =
| 'Activate_Wallet_Cancel'
| 'Activate_Wallet_Done'
| 'Activate_Wallet_Select'
| 'Activate_Wallet_Start'
| 'EdgeProvider_Conversion_Success'
| 'Exchange_Shift_Failed'
| 'Exchange_Shift_Quote'
| 'Exchange_Shift_Start'
| 'Exchange_Shift_Success'
| 'Signup_Wallets_Created'
| 'Start_App'
// Feel free to add new parameters at any time!
// This type is here so we know all the possible values:
type TrackingOptions = {
accountDate?: string, // Account creation date
currencyCode?: string, // Wallet currency code
dollarValue?: number, // Conversion amount, in USD
installerId?: string, // Account installerId
pluginId?: string // Plugin that provided the conversion
}
/**
* Why was this app installed on the phone?
*/
type InstallReason = {
currencyCodes?: Array<string>,
installerId?: string,
swapPluginId?: string
}
/**
* Why was this account created?
*/
type CreationReason = {
creationDate: string,
installerId?: string
}
const CREATION_REASON_FILE = 'CreationReason.json'
const UTILITY_SERVER_FILE = 'utilityServer.json'
// Install information powered by the util server:
let installReason: InstallReason = {}
// Set up the global Firebase instance at boot:
if (ENV.USE_FIREBASE && !firebase.isMock) {
firebase.analytics().setUserId(DeviceInfo.getUniqueID())
global.firebase = firebase
}
/**
* Tracks a user event, like navigating or logging in.
*/
export async function trackEvent (event: TrackingEvent, opts?: TrackingOptions = {}) {
if (global.firebase) {
const { accountDate, currencyCode, dollarValue, installerId, pluginId } = opts
const params: Object = {}
if (accountDate != null) params.adate = accountDate
if (currencyCode != null) params.currency = currencyCode
if (dollarValue != null) {
params.currency = 'USD'
params.value = Number(dollarValue.toFixed(2))
}
if (installerId != null) params.aid = installerId
if (pluginId != null) params.plugin = pluginId
global.firebase.analytics().logEvent(event, params)
// If we get passed a dollarValue, translate the event into a purchase:
if (dollarValue != null) {
params.items = event
global.firebase.analytics().logEvent('purchase', params)
global.firebase.analytics().logEvent('ecommerce_purchase', params)
}
}
}
/**
* Tracks a conversion, which involves some type of revenue.
*/
export async function trackConversion (
event: TrackingEvent,
conversionOpts: {
account: EdgeAccount,
currencyCode: string,
exchangeAmount: number,
pluginId: string,
otherParams?: TrackingOptions
}
) {
const { account, currencyCode, exchangeAmount, pluginId, otherParams = {} } = conversionOpts
// Look up the dollar value:
const dollarValue: number = await account.exchangeCache.convertCurrency(currencyCode, 'iso:USD', exchangeAmount)
const opts: TrackingOptions = { pluginId, dollarValue, ...otherParams }
// Try grabbing the affiliate ID from the account, if there is one:
const creationReason: CreationReason | void = await account.disklet
.getText(CREATION_REASON_FILE)
.then(text => JSON.parse(text))
.catch(() => {})
if (creationReason != null) {
const { installerId, creationDate } = creationReason
opts.accountDate = creationDate
opts.installerId = installerId
}
// Record the event:
return trackEvent(event, opts)
}
/**
* Call this early in the app startup to see if we were installed
* from an affiliate link or coin-specific link.
*/
export async function loadInstallReason (disklet: Disklet, isFreshInstall: boolean) {
const json = await disklet
.getText(UTILITY_SERVER_FILE)
.then(json => JSON.parse(json))
.catch(async () => {
// Nothing is on disk, so try the server:
const json = isFreshInstall ? await fetchInstallReason() : {}
await disklet.setText(UTILITY_SERVER_FILE, JSON.stringify(json))
return json
})
.catch(e => {
// If all else fails, we just don't have a reason:
console.log(e)
return {}
})
installReason = cleanInstallReason(json)
}
/**
* Sanitize raw install information, which may come from the disk or server.
*/
function cleanInstallReason (json: Object): InstallReason {
const { currencyCode, currencyCodes, installerId, swapPluginId } = json
const out: InstallReason = {}
if (typeof currencyCode === 'string') {
out.currencyCodes = [currencyCode.toUpperCase()]
}
if (Array.isArray(currencyCodes)) {
out.currencyCodes = currencyCodes.filter(code => typeof code === 'string').map(code => code.toUpperCase())
}
if (typeof installerId === 'string') out.installerId = installerId
if (typeof swapPluginId === 'string') out.swapPluginId = swapPluginId
return out
}
/**
* Grab install information from the server.
*/
async function fetchInstallReason () {
const reply = await fetch('https://util1.edge.app/ref')
if (!reply.ok) {
throw new Error(`Util server returned status code ${reply.status}`)
}
return reply.json()
}
/**
* Returns the currency code that was used to install this application,
* if any.
*/
export function getInstallCurrencies (): Array<string> | void {
return installReason.currencyCodes
}
/**
* Call this on a new account to set up affiliate information (if any).
*/
export async function saveCreationReason (account: EdgeAccount) {
const creationDate = new Date().toISOString().replace(/-\d\dT.*/, '')
const reason: CreationReason = { creationDate }
const { installerId } = installReason
if (installerId != null) reason.installerId = installerId
await account.disklet.setText(CREATION_REASON_FILE, JSON.stringify(reason))
}