Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Segment events improvements #4653

Merged
merged 2 commits into from
Aug 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,8 @@ export const ExternalSignInModal: FC = () => {
}, [currentStep])

useEffect(() => {
authModalOpenName === 'externalLogIn' && trackPageView(stepToPageName[currentStep] ?? '')
authModalOpenName === 'externalLogIn' &&
trackPageView(stepToPageName[currentStep] ?? 'External login - unknown page')
}, [authModalOpenName, currentStep, trackPageView])

const renderStep = () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ const stepToPageName: Partial<Record<SignUpSteps, string>> = {
[SignUpSteps.SignUpSeed]: 'Signup modal - seed',
[SignUpSteps.SignUpPassword]: 'Signup modal - password',
[SignUpSteps.SignUpEmail]: 'Signup modal - email',
[SignUpSteps.Creating]: 'Signup modal - creating',
[SignUpSteps.Creating]: 'Signup modal - creating account',
[SignUpSteps.Success]: 'Signup modal - success',
}

Expand Down Expand Up @@ -308,7 +308,8 @@ export const SignUpModal = () => {
}, [isSuccess, signUpFormData.current.email, signUpFormData.current.handle, trackMembershipCreation])

useEffect(() => {
authModalOpenName === 'signUp' && trackPageView(stepToPageName[currentStep] ?? '', { isYppFlow })
authModalOpenName === 'signUp' &&
trackPageView(stepToPageName[currentStep] ?? 'Sign up - unknown page', { isYppFlow })
}, [authModalOpenName, currentStep, isYppFlow, trackPageView])

const smMatch = useMediaMatch('sm')
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { ChangeEvent, FC, MouseEvent, useCallback, useEffect, useState } from 'react'
import { useLocation } from 'react-router-dom'
import { useLocation, useSearchParams } from 'react-router-dom'
import { CSSTransition, SwitchTransition } from 'react-transition-group'
import shallow from 'zustand/shallow'

Expand All @@ -12,6 +12,7 @@ import { NotificationsWidget } from '@/components/_notifications/NotificationsWi
import { MemberDropdown } from '@/components/_overlays/MemberDropdown'
import { QUERY_PARAMS, absoluteRoutes } from '@/config/routes'
import { useMediaMatch } from '@/hooks/useMediaMatch'
import { useSegmentAnalytics } from '@/hooks/useSegmentAnalytics'
import { getMemberAvatar } from '@/providers/assets/assets.helpers'
import { getCorrectLoginModal } from '@/providers/auth/auth.helpers'
import { useAuth } from '@/providers/auth/auth.hooks'
Expand All @@ -35,6 +36,9 @@ import {
export const TopbarViewer: FC = () => {
const { activeMembership, isLoggedIn, membershipsLoading } = useUser()
const { isAuthenticating } = useAuth()
const [searchParams] = useSearchParams()
const [utmSource, utmCampaign] = [searchParams.get('utm_source'), searchParams.get('utm_campaign')]
const { trackClickTopBarSignInButton } = useSegmentAnalytics()
const [isMemberDropdownActive, setIsMemberDropdownActive] = useState(false)

const { urls: memberAvatarUrls, isLoadingAsset: memberAvatarLoading } = getMemberAvatar(activeMembership)
Expand Down Expand Up @@ -156,7 +160,10 @@ export const TopbarViewer: FC = () => {
icon={<SvgActionMember />}
iconPlacement="left"
size="medium"
onClick={() => setAuthModalOpenName(getCorrectLoginModal())}
onClick={() => {
trackClickTopBarSignInButton(utmSource, utmCampaign)
setAuthModalOpenName(getCorrectLoginModal())
}}
>
Sign in
</Button>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { FormField } from '@/components/_inputs/FormField'
import { TokenInput } from '@/components/_inputs/TokenInput'
import { DialogModal } from '@/components/_overlays/DialogModal'
import { atlasConfig } from '@/config'
import { useSegmentAnalytics } from '@/hooks/useSegmentAnalytics'
import { hapiBnToTokenNumber, tokenNumberToHapiBn } from '@/joystream-lib/utils'
import { useFee, useJoystream, useTokenPrice } from '@/providers/joystream'
import { useTransaction } from '@/providers/transactions/transactions.hooks'
Expand Down Expand Up @@ -55,6 +56,7 @@ export const WithdrawFundsDialog: FC<WithdrawFundsDialogProps> = ({
setValue,
formState: { errors },
} = useForm<{ amount: number | null }>()
const { trackWithdrawnFunds } = useSegmentAnalytics()
const { fetchPaymentsData } = useChannelPaymentsHistory(channelId || '')
const { convertHapiToUSD } = useTokenPrice()
const amountBn = tokenNumberToHapiBn(watch('amount') || 0)
Expand Down Expand Up @@ -93,6 +95,7 @@ export const WithdrawFundsDialog: FC<WithdrawFundsDialogProps> = ({
),
onTxSync: async () => {
fetchPaymentsData()
trackWithdrawnFunds(channelId, formatNumber(data.amount || 0))
onExitClick()
},
})
Expand Down
84 changes: 77 additions & 7 deletions packages/atlas/src/hooks/useSegmentAnalytics.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { useCallback, useRef } from 'react'

import { useSegmentAnalyticsContext } from '@/providers/segmentAnalytics/useSegmentAnalyticsContext'
import { YppRequirementsErrorCode } from '@/views/global/YppLandingView/YppAuthorizationModal/YppAuthorizationModal.types'

export type videoPlaybackParams = {
videoId: string
Expand All @@ -13,10 +14,20 @@ export type videoPlaybackParams = {
}

type PageViewParams = {
referrer?: string
referrerChannel?: string
tab?: string
utm_source?: string
utmSource?: string
isYppFlow?: boolean
} & VideoPageViewParams &
ChannelPageViewParams

type VideoPageViewParams = {
videoId?: string
category?: string
}

type ChannelPageViewParams = {
channelName?: string
}

type AllNftFilters = {
Expand All @@ -36,6 +47,14 @@ type YppOptInParams = {
utmCampaign?: string
}

type IdentifyUserParams = {
name: string
email: string
memberId: string
isYppFlow?: string
signInType?: string
}

type playbackEventType = 'playbackStarted' | 'playbackPaused' | 'playbackResumed' | 'playbackCompleted'

export const useSegmentAnalytics = () => {
Expand All @@ -44,8 +63,8 @@ export const useSegmentAnalytics = () => {
const playbackEventsQueue = useRef<{ type: playbackEventType; params: videoPlaybackParams }[]>([])

const identifyUser = useCallback(
(email = 'no data') => {
analytics.identify(email, { email })
(params: IdentifyUserParams) => {
analytics.identify(params.email, params)
},
[analytics]
)
Expand All @@ -65,8 +84,8 @@ export const useSegmentAnalytics = () => {
category,
subscribersCount,
referrerId,
utmSource,
utmCampaign,
utm_source: utmSource,
utm_campaign: utmCampaign,
})
},
[analytics]
Expand Down Expand Up @@ -159,6 +178,27 @@ export const useSegmentAnalytics = () => {
[analytics]
)

const trackClickTopBarSignInButton = useCallback(
(utmSource?: string | null, utmCampaign?: string | null) => {
analytics.track('Top Nav Sign In Clicked', { utm_source: utmSource, utm_campaign: utmCampaign })
},
[analytics]
)

const trackClickAuthModalSignInButton = useCallback(
(utmSource?: string | null, utmCampaign?: string | null) => {
analytics.track('YPP Reqs Modal - Sign In Clicked', { utm_source: utmSource, utm_campaign: utmCampaign })
},
[analytics]
)

const trackClickAuthModalSignUpButton = useCallback(
(utmSource?: string | null, utmCampaign?: string | null) => {
analytics.track('YPP Reqs Modal - Create Account Clicked', { utm_source: utmSource, utm_campaign: utmCampaign })
},
[analytics]
)

const trackCommentAdded = useCallback(
(commentBody: string, videoId: string) => {
analytics.track('Comment added', {
Expand Down Expand Up @@ -204,7 +244,11 @@ export const useSegmentAnalytics = () => {
utmSource: string | null | undefined,
utmCampaign: string | null | undefined
) => {
analytics.track('YPP Landing Sign In w Google Clicked', { referrer, utmSource, utmCampaign })
analytics.track('YPP Landing Sign In w Google Clicked', {
referrer,
utm_source: utmSource,
utm_campaign: utmCampaign,
})
},
[analytics]
)
Expand Down Expand Up @@ -259,6 +303,16 @@ export const useSegmentAnalytics = () => {
[analytics]
)

const trackWithdrawnFunds = useCallback(
(channelId?: string, amount?: string) => {
analytics.track('Channel Funds Withdrawn', {
channelId,
amount,
})
},
[analytics]
)

const trackReferralLinkGenerated = useCallback(
(channelId: string | null | undefined) => {
analytics.track('Referral link generated', {
Expand All @@ -277,6 +331,17 @@ export const useSegmentAnalytics = () => {
[analytics]
)

const trackYppReqsNotMet = useCallback(
(
errors: YppRequirementsErrorCode[],
utmSource: string | null | undefined,
utmCampaign: string | null | undefined
) => {
analytics.track('YPP Sign Up Failed - Reqs Not Met', { errors, utmSource, utmCampaign })
},
[analytics]
)

const trackLogout = useCallback(() => {
analytics.reset()
}, [analytics])
Expand Down Expand Up @@ -322,6 +387,9 @@ export const useSegmentAnalytics = () => {
trackAllNftFilterUpdated,
trackChannelCreation,
trackChannelFollow,
trackClickAuthModalSignInButton,
trackClickAuthModalSignUpButton,
trackClickTopBarSignInButton,
trackCommentAdded,
trackDislikeAdded,
trackFeaturedNFTNext,
Expand All @@ -335,12 +403,14 @@ export const useSegmentAnalytics = () => {
trackNftMint,
trackNftSale,
trackPageView,
trackYppReqsNotMet,
trackReferralLinkGenerated,
trackVideoPlaybackCompleted,
trackVideoPlaybackPaused,
trackVideoPlaybackResumed,
trackVideoPlaybackStarted,
trackVideoUpload,
trackWithdrawnFunds,
trackYppOptIn,
trackYppSignInButtonClick,
}
Expand Down
21 changes: 18 additions & 3 deletions packages/atlas/src/providers/auth/auth.provider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,12 @@ export const AuthProvider: FC<PropsWithChildren> = ({ children }) => {
if (keypair.address === data.accountData.joystreamAccount) {
setLoggedAddress(keypair.address)
setCurrentUser(data.accountData)
identifyUser(data.accountData.email)
identifyUser({
name: 'Sign in',
email: data.accountData.email,
memberId: data.accountData.membershipId,
signInType: 'password',
})
setApiActiveAccount('seed', mnemonic)
setIsAuthenticating(false)
return
Expand All @@ -84,7 +89,12 @@ export const AuthProvider: FC<PropsWithChildren> = ({ children }) => {
const res = await signInToWallet(lastUsedWalletName, true)
if (res?.find((walletAcc) => walletAcc.address === data.accountData.joystreamAccount)) {
setLoggedAddress(data.accountData.joystreamAccount)
identifyUser(data.accountData.email)
identifyUser({
name: 'Sign in',
email: data.accountData.email,
memberId: data.accountData.membershipId,
signInType: 'wallet',
})
setCurrentUser(data.accountData)
setApiActiveAccount('address', data.accountData.joystreamAccount)
}
Expand Down Expand Up @@ -191,7 +201,12 @@ export const AuthProvider: FC<PropsWithChildren> = ({ children }) => {

const res = await refetch()
setCurrentUser(res.data.accountData)
identifyUser(res.data.accountData.email)
identifyUser({
name: 'Sign in',
email: res.data.accountData.email,
memberId: res.data.accountData.membershipId,
signInType: params.type === 'external' ? 'wallet' : 'password',
})

return response.data.accountId
} catch (error) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ export type YppAuthorizationModalProps = {
const stepToPageName = {
'ypp-select-channel': 'YPP Select Channel modal',
'ypp-requirements': 'YPP Requirements modal',
'ypp-fetching-data': 'YPP Fetching Data modal',
'ypp-fetching-data': 'Fetching Channel Data From Google',
'ypp-sync-options': 'YPP Category And Referrer Modal',
'ypp-channel-already-registered': 'YPP channel already registered modal',
'ypp-speaking-to-backend': 'YPP processing modal',
Expand Down Expand Up @@ -141,7 +141,14 @@ export const YppAuthorizationModal: FC<YppAuthorizationModalProps> = ({ unSynced
const { extendedChannel } = useBasicChannel(referrerId || '', {
skip: !referrerId,
})
const { trackPageView, trackYppOptIn, identifyUser } = useSegmentAnalytics()
const {
trackPageView,
trackYppOptIn,
identifyUser,
trackYppReqsNotMet,
trackClickAuthModalSignUpButton,
trackClickAuthModalSignInButton,
} = useSegmentAnalytics()

const channel = extendedChannel?.channel

Expand Down Expand Up @@ -291,8 +298,13 @@ export const YppAuthorizationModal: FC<YppAuthorizationModalProps> = ({ unSynced
})

await refetchYppSyncedChannels()

identifyUser(ytResponseData?.email)
identifyUser({
name: 'Sign up',
memberId: memberId,
email: ytResponseData?.email || '',
isYppFlow: 'true',
signInType: 'password',
})
trackYppOptIn({
handle: ytResponseData?.channelHandle,
email: ytResponseData?.email,
Expand Down Expand Up @@ -338,6 +350,13 @@ export const YppAuthorizationModal: FC<YppAuthorizationModalProps> = ({ unSynced
}
}, [channel, detailsFormMethods, referrerId])

useEffect(() => {
if (ytRequirementsErrors?.length) {
trackPageView('YPP Reqs Not Met')
trackYppReqsNotMet(ytRequirementsErrors, utmSource, utmCampaign)
}
}, [trackPageView, trackYppReqsNotMet, utmCampaign, utmSource, ytRequirementsErrors])

const selectedChannel = useMemo(() => {
if (!unSyncedChannels || !selectedChannelId) {
return null
Expand Down Expand Up @@ -379,6 +398,7 @@ export const YppAuthorizationModal: FC<YppAuthorizationModalProps> = ({ unSynced
return {
text: 'Create account',
onClick: () => {
trackClickAuthModalSignUpButton(utmSource, utmCampaign)
setSelectedChannelId(yppUnsyncedChannels?.[0]?.id ?? '')
handleAuthorizeClick(yppUnsyncedChannels?.[0]?.id)
},
Expand Down Expand Up @@ -480,6 +500,9 @@ export const YppAuthorizationModal: FC<YppAuthorizationModalProps> = ({ unSynced
setSelectedChannelId,
handleClose,
setYppModalOpenName,
trackClickAuthModalSignUpButton,
utmSource,
utmCampaign,
handleAuthorizeClick,
handleCreateOrUpdateChannel,
])
Expand All @@ -495,6 +518,7 @@ export const YppAuthorizationModal: FC<YppAuthorizationModalProps> = ({ unSynced
return {
text: 'Sign in',
onClick: () => {
trackClickAuthModalSignInButton(utmSource, utmCampaign)
setShouldContinueYppFlowAfterLogin(true)
setYppModalOpenName(null)
setAuthModalOpenName('logIn')
Expand All @@ -519,11 +543,14 @@ export const YppAuthorizationModal: FC<YppAuthorizationModalProps> = ({ unSynced
}
}, [
isLoadingModal,
ytRequirementsErrors.length,
yppModalOpenName,
isLoggedIn,
ytRequirementsErrors.length,
isSubmitting,
handleGoBack,
trackClickAuthModalSignInButton,
utmSource,
utmCampaign,
setShouldContinueYppFlowAfterLogin,
setYppModalOpenName,
setAuthModalOpenName,
Expand Down
Loading