(core) Record new user sign-ups

Summary:
Adds Google Tag Manager snippet to all login pages, and a new user
preference, recordSignUpEvent, that's set to true on first sign-in. The
client now checks for this preference, and if true, dynamically loads
Google Tag Manager to record a sign-up event. Afterwards, it removes
the preference.

Test Plan: Tested manually.

Reviewers: dsagal

Reviewed By: dsagal

Subscribers: dsagal

Differential Revision: https://phab.getgrist.com/D3319
This commit is contained in:
George Gevoian
2022-03-11 12:35:29 -08:00
parent eff78ae2e1
commit ad1b4f3cff
7 changed files with 84 additions and 31 deletions

View File

@@ -1,4 +1,5 @@
import {get as getBrowserGlobals} from 'app/client/lib/browserGlobals';
import {error} from 'app/client/lib/log';
import {reportError, setErrorNotifier} from 'app/client/models/errors';
import {urlState} from 'app/client/models/gristUrlState';
import {Notifier} from 'app/client/models/NotifyModel';
@@ -8,8 +9,10 @@ import {GristLoadConfig} from 'app/common/gristUrls';
import {FullUser} from 'app/common/LoginSessionAPI';
import {LocalPlugin} from 'app/common/plugin';
import {UserPrefs} from 'app/common/Prefs';
import {getTagManagerScript} from 'app/common/tagManager';
import {getGristConfig} from 'app/common/urlUtils';
import {getOrgName, Organization, OrgError, UserAPI, UserAPIImpl} from 'app/common/UserAPI';
import {getUserPrefsObs} from 'app/client/models/UserPrefs';
import {getUserPrefObs, getUserPrefsObs} from 'app/client/models/UserPrefs';
import {bundleChanges, Computed, Disposable, Observable, subscribe} from 'grainjs';
export {reportError} from 'app/client/models/errors';
@@ -195,6 +198,35 @@ export class AppModelImpl extends Disposable implements AppModel {
public readonly orgError?: OrgError,
) {
super();
this._recordSignUpIfIsNewUser();
}
/**
* If the current user is a new user, record a sign-up event via Google Tag Manager.
*/
private _recordSignUpIfIsNewUser() {
const isNewUser = this.userPrefsObs.get().recordSignUpEvent;
if (!isNewUser) { return; }
// If Google Tag Manager isn't configured, don't record anything.
const {tagManagerId} = getGristConfig();
if (!tagManagerId) { return; }
let dataLayer = (window as any).dataLayer;
if (!dataLayer) {
// Load the Google Tag Manager script into the document.
const script = document.createElement('script');
script.innerHTML = getTagManagerScript(tagManagerId);
document.head.appendChild(script);
dataLayer = (window as any).dataLayer;
if (!dataLayer) {
error(`_recordSignUpIfIsNewUser() failed to load Google Tag Manager`);
}
}
// Send the sign-up event, and remove the recordSignUpEvent flag from preferences.
dataLayer.push({event: 'new-sign-up'});
getUserPrefObs(this.userPrefsObs, 'recordSignUpEvent').set(undefined);
}
}

View File

@@ -170,8 +170,11 @@ export class UrlStateImpl {
const welcomeReload = Boolean(prevState.welcome) !== Boolean(newState.welcome);
// Reload when link keys change, which changes what the user can access
const linkKeysReload = !isEqual(prevState.params?.linkParameters, newState.params?.linkParameters);
// Reload when moving to/from the Grist sign-up page.
const signupReload = [prevState.login, newState.login].includes('signup')
&& prevState.login !== newState.login;
return Boolean(orgReload || accountReload || billingReload || gristConfig.errPage
|| docReload || welcomeReload || linkKeysReload);
|| docReload || welcomeReload || linkKeysReload || signupReload);
}
/**