From 6fdc796095199e45cad8fdf11356dce8ababae30 Mon Sep 17 00:00:00 2001 From: schmanu Date: Tue, 24 Oct 2023 15:19:49 +0200 Subject: [PATCH 1/5] feat: track user's wallet through user properties --- src/services/analytics/TagManager.ts | 10 ++++++++++ src/services/analytics/gtm.ts | 1 + src/services/analytics/useGtm.ts | 7 +++++++ 3 files changed, 18 insertions(+) diff --git a/src/services/analytics/TagManager.ts b/src/services/analytics/TagManager.ts index 54a943cd1e..254539274e 100644 --- a/src/services/analytics/TagManager.ts +++ b/src/services/analytics/TagManager.ts @@ -102,6 +102,16 @@ const TagManager = { // Injected script will remain in memory until new session location.reload() }, + + setUserProperty: (name: string, value: string) => { + window.gtag?.('set', 'user_properties', { + [name]: value, + }) + + if (!IS_PRODUCTION) { + console.info('[GTM] -', 'set user_properties', name, '=', value) + } + }, } export default TagManager diff --git a/src/services/analytics/gtm.ts b/src/services/analytics/gtm.ts index fe77d3b26c..6f13652e7f 100644 --- a/src/services/analytics/gtm.ts +++ b/src/services/analytics/gtm.ts @@ -75,6 +75,7 @@ export const gtmInit = (): void => { export const gtmEnableCookies = TagManager.enableCookies export const gtmDisableCookies = TagManager.disableCookies +export const gtmSetUserProperty = TagManager.setUserProperty type GtmEvent = { event: EventType diff --git a/src/services/analytics/useGtm.ts b/src/services/analytics/useGtm.ts index d55ee9da60..ee64e7d854 100644 --- a/src/services/analytics/useGtm.ts +++ b/src/services/analytics/useGtm.ts @@ -13,6 +13,7 @@ import { gtmDisableCookies, gtmSetDeviceType, gtmSetSafeAddress, + gtmSetUserProperty, } from '@/services/analytics/gtm' import { useAppSelector } from '@/store' import { CookieType, selectCookies } from '@/store/cookiesSlice' @@ -23,6 +24,7 @@ import useMetaEvents from './useMetaEvents' import { useMediaQuery } from '@mui/material' import { DeviceType } from './types' import useSafeAddress from '@/hooks/useSafeAddress' +import useWallet from '@/hooks/wallets/useWallet' const useGtm = () => { const chainId = useChainId() @@ -35,6 +37,7 @@ const useGtm = () => { const isTablet = useMediaQuery(theme.breakpoints.down('md')) const deviceType = isMobile ? DeviceType.MOBILE : isTablet ? DeviceType.TABLET : DeviceType.DESKTOP const safeAddress = useSafeAddress() + const walletLabel = useWallet()?.label // Initialize GTM useEffect(() => { @@ -79,6 +82,10 @@ const useGtm = () => { gtmTrackPageview(router.pathname) }, [router.pathname]) + useEffect(() => { + gtmSetUserProperty('walletLabel', walletLabel ?? 'NONE') + }, [walletLabel]) + // Track meta events on app load useMetaEvents() } From 108adb86ff05ce5b7da7ee8d35f80fe7dea219bd Mon Sep 17 00:00:00 2001 From: schmanu Date: Tue, 24 Oct 2023 18:20:31 +0200 Subject: [PATCH 2/5] fix: add enum for user properties --- src/services/analytics/useGtm.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/services/analytics/useGtm.ts b/src/services/analytics/useGtm.ts index ee64e7d854..0be888fff7 100644 --- a/src/services/analytics/useGtm.ts +++ b/src/services/analytics/useGtm.ts @@ -26,6 +26,12 @@ import { DeviceType } from './types' import useSafeAddress from '@/hooks/useSafeAddress' import useWallet from '@/hooks/wallets/useWallet' +enum GA_USER_PROPERTIES { + WALLET_LABEL = 'walletLabel', +} + +const WALLET_LABEL_NONE = 'NONE' + const useGtm = () => { const chainId = useChainId() const cookies = useAppSelector(selectCookies) @@ -83,7 +89,7 @@ const useGtm = () => { }, [router.pathname]) useEffect(() => { - gtmSetUserProperty('walletLabel', walletLabel ?? 'NONE') + gtmSetUserProperty(GA_USER_PROPERTIES.WALLET_LABEL, walletLabel ?? WALLET_LABEL_NONE) }, [walletLabel]) // Track meta events on app load From a81a348ba9bb373eb5e1b6b5da02a93a719a2fe6 Mon Sep 17 00:00:00 2001 From: schmanu Date: Wed, 25 Oct 2023 09:34:10 +0200 Subject: [PATCH 3/5] fix: move user properties to types.ts and add test --- .../analytics/__tests__/TagManager.test.ts | 25 +++++++++++++++++++ src/services/analytics/types.ts | 6 +++++ src/services/analytics/useGtm.ts | 10 ++------ 3 files changed, 33 insertions(+), 8 deletions(-) diff --git a/src/services/analytics/__tests__/TagManager.test.ts b/src/services/analytics/__tests__/TagManager.test.ts index 621f94839d..22c1710811 100644 --- a/src/services/analytics/__tests__/TagManager.test.ts +++ b/src/services/analytics/__tests__/TagManager.test.ts @@ -1,6 +1,7 @@ import Cookies from 'js-cookie' import * as gtm from '../TagManager' +import { AnalyticsUserProperties } from '../types' const { default: TagManager } = gtm @@ -135,4 +136,28 @@ describe('TagManager', () => { expect(global.location.reload).toHaveBeenCalled() }) }) + + describe('TagManager.setUserProperty', () => { + it('should push new user properties to dataLayer', () => { + expect(window.dataLayer).toBeUndefined() + + TagManager.initialize({ + gtmId: MOCK_ID, + auth: MOCK_AUTH, + preview: MOCK_PREVIEW, + }) + + expect(window.dataLayer).toHaveLength(3) + + TagManager.setUserProperty(AnalyticsUserProperties.WALLET_LABEL, 'Safe{Wallet}') + + expect(window.dataLayer).toHaveLength(4) + + expect(Array.from(window.dataLayer?.[3])).toEqual([ + 'set', + 'user_properties', + { [AnalyticsUserProperties.WALLET_LABEL]: 'Safe{Wallet}' }, + ]) + }) + }) }) diff --git a/src/services/analytics/types.ts b/src/services/analytics/types.ts index b2df3d6c6e..b22f27b847 100644 --- a/src/services/analytics/types.ts +++ b/src/services/analytics/types.ts @@ -29,3 +29,9 @@ export enum DeviceType { MOBILE = 'mobile', TABLET = 'tablet', } + +export enum AnalyticsUserProperties { + WALLET_LABEL = 'walletLabel', +} + +export const WALLET_LABEL_NONE = 'NONE' diff --git a/src/services/analytics/useGtm.ts b/src/services/analytics/useGtm.ts index 0be888fff7..8870bbea15 100644 --- a/src/services/analytics/useGtm.ts +++ b/src/services/analytics/useGtm.ts @@ -22,16 +22,10 @@ import { useRouter } from 'next/router' import { AppRoutes } from '@/config/routes' import useMetaEvents from './useMetaEvents' import { useMediaQuery } from '@mui/material' -import { DeviceType } from './types' +import { AnalyticsUserProperties, DeviceType, WALLET_LABEL_NONE } from './types' import useSafeAddress from '@/hooks/useSafeAddress' import useWallet from '@/hooks/wallets/useWallet' -enum GA_USER_PROPERTIES { - WALLET_LABEL = 'walletLabel', -} - -const WALLET_LABEL_NONE = 'NONE' - const useGtm = () => { const chainId = useChainId() const cookies = useAppSelector(selectCookies) @@ -89,7 +83,7 @@ const useGtm = () => { }, [router.pathname]) useEffect(() => { - gtmSetUserProperty(GA_USER_PROPERTIES.WALLET_LABEL, walletLabel ?? WALLET_LABEL_NONE) + gtmSetUserProperty(AnalyticsUserProperties.WALLET_LABEL, walletLabel ?? WALLET_LABEL_NONE) }, [walletLabel]) // Track meta events on app load From ac4d76ff5e55dd80126f3a190260105f9337afb0 Mon Sep 17 00:00:00 2001 From: schmanu Date: Mon, 30 Oct 2023 09:16:42 +0100 Subject: [PATCH 4/5] fix: only set walletLabel if defined --- src/services/analytics/types.ts | 2 -- src/services/analytics/useGtm.ts | 4 +++- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/services/analytics/types.ts b/src/services/analytics/types.ts index b22f27b847..47fb97dbb6 100644 --- a/src/services/analytics/types.ts +++ b/src/services/analytics/types.ts @@ -33,5 +33,3 @@ export enum DeviceType { export enum AnalyticsUserProperties { WALLET_LABEL = 'walletLabel', } - -export const WALLET_LABEL_NONE = 'NONE' diff --git a/src/services/analytics/useGtm.ts b/src/services/analytics/useGtm.ts index 8870bbea15..8314ed0229 100644 --- a/src/services/analytics/useGtm.ts +++ b/src/services/analytics/useGtm.ts @@ -83,7 +83,9 @@ const useGtm = () => { }, [router.pathname]) useEffect(() => { - gtmSetUserProperty(AnalyticsUserProperties.WALLET_LABEL, walletLabel ?? WALLET_LABEL_NONE) + if (walletLabel) { + gtmSetUserProperty(AnalyticsUserProperties.WALLET_LABEL, walletLabel) + } }, [walletLabel]) // Track meta events on app load From 48fa5dee5bf2020ad650c1a21c19576a16ae8305 Mon Sep 17 00:00:00 2001 From: schmanu Date: Mon, 30 Oct 2023 10:11:41 +0100 Subject: [PATCH 5/5] lint: remove unused import --- src/services/analytics/useGtm.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/services/analytics/useGtm.ts b/src/services/analytics/useGtm.ts index 8314ed0229..f2fc484de3 100644 --- a/src/services/analytics/useGtm.ts +++ b/src/services/analytics/useGtm.ts @@ -22,7 +22,7 @@ import { useRouter } from 'next/router' import { AppRoutes } from '@/config/routes' import useMetaEvents from './useMetaEvents' import { useMediaQuery } from '@mui/material' -import { AnalyticsUserProperties, DeviceType, WALLET_LABEL_NONE } from './types' +import { AnalyticsUserProperties, DeviceType } from './types' import useSafeAddress from '@/hooks/useSafeAddress' import useWallet from '@/hooks/wallets/useWallet'