Skip to content

Commit

Permalink
Merge pull request #40807 from Expensify/dsilva_changingPropertyBeing…
Browse files Browse the repository at this point in the history
…UsedByFullstory

[CP Staging] Changing properties being used by Fullstory
  • Loading branch information
mountiny authored Apr 24, 2024
2 parents e58ec49 + bdad226 commit 51372ab
Show file tree
Hide file tree
Showing 7 changed files with 62 additions and 55 deletions.
4 changes: 4 additions & 0 deletions src/ONYXKEYS.ts
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,9 @@ const ONYXKEYS = {
/** User's Expensify Wallet */
USER_WALLET: 'userWallet',

/** User's metadata that will be used to segmentation */
USER_METADATA: 'userMetadata',

/** Object containing Onfido SDK Token + applicantID */
WALLET_ONFIDO: 'walletOnfido',

Expand Down Expand Up @@ -597,6 +600,7 @@ type OnyxValuesMapping = {
[ONYXKEYS.USER_LOCATION]: OnyxTypes.UserLocation;
[ONYXKEYS.LOGIN_LIST]: OnyxTypes.LoginList;
[ONYXKEYS.SESSION]: OnyxTypes.Session;
[ONYXKEYS.USER_METADATA]: OnyxTypes.UserMetadata;
[ONYXKEYS.STASHED_SESSION]: OnyxTypes.Session;
[ONYXKEYS.BETAS]: OnyxTypes.Beta[];
[ONYXKEYS.NVP_PRIORITY_MODE]: ValueOf<typeof CONST.PRIORITY_MODE>;
Expand Down
2 changes: 1 addition & 1 deletion src/libs/actions/Session/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ Onyx.connect({
});

Onyx.connect({
key: ONYXKEYS.SESSION,
key: ONYXKEYS.USER_METADATA,
callback: Fullstory.consentAndIdentify,
});

Expand Down
33 changes: 13 additions & 20 deletions src/libs/fullstory/index.native.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import FullStory, {FSPage} from '@fullstory/react-native';
import type {OnyxEntry} from 'react-native-onyx';
import type Session from '@src/types/onyx/Session';
import type {UserSession} from './types';
import type {UserMetadata} from '@src/types/onyx';

/**
* Fullstory React-Native lib adapter
Expand All @@ -19,37 +18,31 @@ const FS = {
consent: (c: boolean) => FullStory.consent(c),

/**
* Initializes the FullStory session with the provided session information.
* Initializes the FullStory metadata with the provided metadata information.
*/
consentAndIdentify: (value: OnyxEntry<Session>) => {
consentAndIdentify: (value: OnyxEntry<UserMetadata>) => {
try {
const session: UserSession = {
email: value?.email,
accountID: value?.accountID,
};
// set consent
// We only use FullStory in production environment
FullStory.consent(true);
FS.fsIdentify(session);
FS.fsIdentify(value);
} catch (e) {
// error handler
}
},

/**
* Sets the FullStory user identity based on the provided session information.
* If the session is null or the email is 'undefined', the user identity is anonymized.
* If the session contains an email, the user identity is defined with the email and account ID.
* Sets the FullStory user identity based on the provided metadata information.
* If the metadata is null or the email is 'undefined', the user identity is anonymized.
* If the metadata contains an accountID, the user identity is defined with it.
*/
fsIdentify: (session: UserSession) => {
if (!session || session.email === 'undefined') {
// anonymize FullStory user identity session
fsIdentify: (metadata: UserMetadata | null) => {
if (!metadata?.accountID) {
// anonymize FullStory user identity metadata
FullStory.anonymize();
} else {
// define FullStory user identity
FullStory.identify(String(session.accountID), {
properties: {
accountID: session.accountID,
},
FullStory.identify(String(metadata.accountID), {
properties: metadata,
});
}
},
Expand Down
61 changes: 33 additions & 28 deletions src/libs/fullstory/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import {FullStory, init, isInitialized} from '@fullstory/browser';
import type {OnyxEntry} from 'react-native-onyx';
import type Session from '@src/types/onyx/Session';
import type {NavigationProperties, UserSession} from './types';
import CONST from '@src/CONST';
import * as Environment from '@src/libs/Environment/Environment';
import type {UserMetadata} from '@src/types/onyx';
import type NavigationProperties from './types';

// Placeholder Browser API does not support Manual Page definition
class FSPage {
Expand All @@ -27,12 +29,17 @@ const FS = {
*/
onReady: () =>
new Promise((resolve) => {
// Initialised via HEAD snippet
if (isInitialized()) {
init({orgId: ''}, resolve);
} else {
FullStory('observe', {type: 'start', callback: resolve});
}
Environment.getEnvironment().then((envName: string) => {
if (CONST.ENVIRONMENT.PRODUCTION !== envName) {
return;
}
// Initialised via HEAD snippet
if (!isInitialized()) {
init({orgId: ''}, resolve);
} else {
FullStory('observe', {type: 'start', callback: resolve});
}
});
}),

/**
Expand All @@ -46,40 +53,38 @@ const FS = {
consent: (c: boolean) => FullStory('setIdentity', {consent: c}),

/**
* Initializes the FullStory session with the provided session information.
* Initializes the FullStory metadata with the provided metadata information.
*/
consentAndIdentify: (value: OnyxEntry<Session>) => {
consentAndIdentify: (value: OnyxEntry<UserMetadata>) => {
try {
FS.onReady().then(() => {
const session: UserSession = {
email: value?.email,
accountID: value?.accountID,
};
// set consent
FS.consent(true);
FS.fsIdentify(session);
Environment.getEnvironment().then((envName: string) => {
if (CONST.ENVIRONMENT.PRODUCTION !== envName) {
return;
}
FS.onReady().then(() => {
FS.consent(true);
FS.fsIdentify(value);
});
});
} catch (e) {
// error handler
}
},

/**
* Sets the FullStory user identity based on the provided session information.
* If the session does not contain an email, the user identity is anonymized.
* If the session contains an email, the user identity is defined with the email and account ID.
* Sets the FullStory user identity based on the provided metadata information.
* If the metadata does not contain an email, the user identity is anonymized.
* If the metadata contains an accountID, the user identity is defined with it.
*/
fsIdentify: (session: UserSession) => {
if (typeof session.email === 'undefined') {
// anonymize FullStory user identity session
fsIdentify: (metadata: UserMetadata | null) => {
if (!metadata?.accountID) {
// anonymize FullStory user identity metadata
FS.anonymize();
} else {
// define FullStory user identity
FullStory('setIdentity', {
uid: String(session.accountID),
properties: {
accountID: session.accountID,
},
uid: String(metadata.accountID),
properties: metadata,
});
}
},
Expand Down
7 changes: 1 addition & 6 deletions src/libs/fullstory/types.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,5 @@
type UserSession = {
email: string | undefined;
accountID: number | undefined;
};

type NavigationProperties = {
path: string;
};

export type {UserSession, NavigationProperties};
export default NavigationProperties;
8 changes: 8 additions & 0 deletions src/types/onyx/UserMetadata.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
type UserMetadata = {
planType?: string;
role?: string;
freeTrial?: boolean;
accountID?: number;
};

export default UserMetadata;
2 changes: 2 additions & 0 deletions src/types/onyx/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ import type {TransactionViolation, ViolationName} from './TransactionViolation';
import type TransactionViolations from './TransactionViolation';
import type User from './User';
import type UserLocation from './UserLocation';
import type UserMetadata from './UserMetadata';
import type UserWallet from './UserWallet';
import type WalletAdditionalDetails from './WalletAdditionalDetails';
import type {WalletAdditionalQuestionDetails} from './WalletAdditionalDetails';
Expand Down Expand Up @@ -155,6 +156,7 @@ export type {
TransactionViolations,
User,
UserLocation,
UserMetadata,
UserWallet,
ViolationName,
WalletAdditionalDetails,
Expand Down

0 comments on commit 51372ab

Please sign in to comment.