diff --git a/src/ONYXKEYS.ts b/src/ONYXKEYS.ts index 45c2d152542d..c17c911d18b3 100755 --- a/src/ONYXKEYS.ts +++ b/src/ONYXKEYS.ts @@ -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', @@ -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; diff --git a/src/libs/actions/Session/index.ts b/src/libs/actions/Session/index.ts index cef66487a438..aa83d14a1675 100644 --- a/src/libs/actions/Session/index.ts +++ b/src/libs/actions/Session/index.ts @@ -66,7 +66,7 @@ Onyx.connect({ }); Onyx.connect({ - key: ONYXKEYS.SESSION, + key: ONYXKEYS.USER_METADATA, callback: Fullstory.consentAndIdentify, }); diff --git a/src/libs/fullstory/index.native.ts b/src/libs/fullstory/index.native.ts index 548598bf60bc..67d7c7f2fe90 100644 --- a/src/libs/fullstory/index.native.ts +++ b/src/libs/fullstory/index.native.ts @@ -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 @@ -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) => { + consentAndIdentify: (value: OnyxEntry) => { 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, }); } }, diff --git a/src/libs/fullstory/index.ts b/src/libs/fullstory/index.ts index 0cb849983c80..5b60f20f9ddf 100644 --- a/src/libs/fullstory/index.ts +++ b/src/libs/fullstory/index.ts @@ -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 { @@ -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}); + } + }); }), /** @@ -46,18 +53,18 @@ 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) => { + consentAndIdentify: (value: OnyxEntry) => { 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 @@ -65,21 +72,19 @@ const FS = { }, /** - * 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, }); } }, diff --git a/src/libs/fullstory/types.ts b/src/libs/fullstory/types.ts index 386e35536d97..24878fd0fbd3 100644 --- a/src/libs/fullstory/types.ts +++ b/src/libs/fullstory/types.ts @@ -1,10 +1,5 @@ -type UserSession = { - email: string | undefined; - accountID: number | undefined; -}; - type NavigationProperties = { path: string; }; -export type {UserSession, NavigationProperties}; +export default NavigationProperties; diff --git a/src/types/onyx/UserMetadata.ts b/src/types/onyx/UserMetadata.ts new file mode 100644 index 000000000000..fc6490264087 --- /dev/null +++ b/src/types/onyx/UserMetadata.ts @@ -0,0 +1,8 @@ +type UserMetadata = { + planType?: string; + role?: string; + freeTrial?: boolean; + accountID?: number; +}; + +export default UserMetadata; diff --git a/src/types/onyx/index.ts b/src/types/onyx/index.ts index ea0870a7b8c6..84a8d5c85c40 100644 --- a/src/types/onyx/index.ts +++ b/src/types/onyx/index.ts @@ -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'; @@ -155,6 +156,7 @@ export type { TransactionViolations, User, UserLocation, + UserMetadata, UserWallet, ViolationName, WalletAdditionalDetails,