Skip to content
This repository has been archived by the owner on Jan 17, 2023. It is now read-only.

Commit

Permalink
Fixes #5067 - add custom dimension for login type to GA (#5152)
Browse files Browse the repository at this point in the history
* WIP update of #5067, add custom dimension for login type to GA

* Update with accountId in metrics doc
  • Loading branch information
ianb authored and jaredhirsch committed Nov 9, 2018
1 parent 4ded235 commit c50e1fa
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 7 deletions.
17 changes: 14 additions & 3 deletions docs/METRICS.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,15 @@ This document is a summary of the metrics Firefox Screenshots will record, how w

Additionally, it's important to recognize that Firefox Screenshots is an add-on in a browser as well as a server-side service.

## deviceId / user ID
## accountId / deviceId / user ID

Each device that uses Screenshots (browser, profile, computer) generates a random UUID ID. We call this the deviceId. In addition a random secret is generated. The two together are used to register and authenticate with the server.
Each device that takes Screenshots (browser, profile, computer) generates a random UUID ID. We call this the deviceId. In addition a random secret is generated. The two together are used to register and authenticate with the server.

The deviceId is only registered with the screenshots.firefox.com server when the user first saves a shot. Starting Screenshots or downloading does not cause registration.

Each event is sent to the server with its deviceId. The server hashes this ID (combining it with a random server string that is rotated occasionally) before sending it to Google Analytics. This hashed ID is generally called `cid` (customer ID, a Google Analytics term).
An alternate way to authenticate with server is by successful signin to firefox account. An accountId which is a uid returned by fxa-auth-server is assigned once a user login with firefox account and its value is reset on signout from settings.

Each event is sent to the server with its accountId or deviceId. The server hashes this ID (combining it with a random server string that is rotated occasionally) before sending it to Google Analytics. This hashed ID is generally called `cid` (customer ID, a Google Analytics term).

For web page views (viewing and interacting with individual shots or My Shots) we serve up `/ga-activation.js` or `/ga-activation-hashed.js` (the latter for pages with private URLs). This file is generated *per user* and includes the `cid`, if the user is authenticated with the service.

Expand Down Expand Up @@ -83,6 +85,15 @@ Event label: exactly what control invoked the action, such as toolbar-button. T
* `selection`: anything that happens during the selection phase, that doesn't happen in the topbar
* `keyboard`: any keyboard shortcut used

#### Login status custom dimension

The `cd9` dimension holds the "login type". The values can be:

* `non-login`: visitor is not logged in
* `extension`: logged in via the extension, with no FxA login
* `extension-fxa`: logged in via the extension, With a FxA login
* `browser-fxa`: using a non-Firefox browser, with a FxA login

#### A/B tests

##### Test alternate share panel
Expand Down
5 changes: 4 additions & 1 deletion server/src/ga-activation.js
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ const gaJs = `
window.sendEvent = function (action, label, options) {
var event = "web";
var loginType = "__LOGIN_TYPE__" || null;
if (typeof label == "object") {
if (options) {
console.error("Error: got label and options");
Expand All @@ -146,14 +147,15 @@ window.sendEvent = function (action, label, options) {
options[window.abTests[testName].gaField] = window.abTests[testName].value;
}
}
options.cd9 = loginType;
console.debug("sendEvent", event + "/" + action + (label ? "/" + label : "") || "none", options || "no-options");
ga("send", "event", event, action, label, options);
};
`;

const idRegex = /^[a-zA-Z0-9_.,-]{1,1000}$/;

exports.makeGaActivationString = function(gaId, userId, abTests, hashLocation) {
exports.makeGaActivationString = function({gaId, userId, abTests, hashLocation, loginType}) {
if (gaId === "") {
// Don't enable ga if no id was provided
return stubGaJs.replace(/__ABTESTS__/g, JSON.stringify(abTests));
Expand All @@ -171,5 +173,6 @@ exports.makeGaActivationString = function(gaId, userId, abTests, hashLocation) {
let script = gaJs.replace(/__GA_ID__/g, gaId).replace(/__USER_ID__/g, userId);
script = script.replace(/__HASH_LOCATION__/g, hashLocation ? "true" : "false");
script = script.replace(/__ABTESTS__/g, JSON.stringify(abTests));
script = script.replace(/__LOGIN_TYPE__/g, loginType || "");
return script;
};
22 changes: 19 additions & 3 deletions server/src/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -328,16 +328,32 @@ app.get("/ga-activation-hashed.js", function(req, res) {

function sendGaActivation(req, res, hashPage) {
let promise;
let loginType = "non-login";
if (req.accountId) {
if (req.deviceId) {
loginType = "extension-fxa";
} else {
loginType = "browser-fxa";
}
} else if (req.deviceId) {
loginType = "extension";
}
setMonthlyCache(res, {private: true});
if (req.deviceId) {
promise = hashUserId(req.deviceId).then((uuid) => {
if (req.accountId || req.deviceId) {
promise = hashUserId(req.accountId || req.deviceId).then((uuid) => {
return uuid.toString();
});
} else {
promise = Promise.resolve("");
}
promise.then((userUuid) => {
const script = gaActivation.makeGaActivationString(config.gaId, userUuid, req.abTests, hashPage);
const script = gaActivation.makeGaActivationString({
gaId: config.gaId,
userId: userUuid,
abTests: req.abTests,
hashLocation: hashPage,
loginType,
});
jsResponse(res, script);
}).catch((e) => {
errorResponse(res, "Error creating user UUID:", e);
Expand Down

0 comments on commit c50e1fa

Please sign in to comment.