diff --git a/satellite/analytics/service.go b/satellite/analytics/service.go index 821999837..e7f2454c3 100644 --- a/satellite/analytics/service.go +++ b/satellite/analytics/service.go @@ -466,7 +466,7 @@ func (service *Service) TrackAccountVerified(userID uuid.UUID, email string) { // TrackEvent sends an arbitrary event associated with user ID to Segment. // It is used for tracking occurrences of client-side events. -func (service *Service) TrackEvent(eventName string, userID uuid.UUID, email string) { +func (service *Service) TrackEvent(eventName string, userID uuid.UUID, email string, customProps map[string]string) { if !service.config.Enabled { return } @@ -480,6 +480,10 @@ func (service *Service) TrackEvent(eventName string, userID uuid.UUID, email str props := segment.NewProperties() props.Set("email", email) + for key, value := range customProps { + props.Set(key, value) + } + service.enqueueMessage(segment.Track{ UserId: userID.String(), Event: service.satelliteName + " " + eventName, diff --git a/satellite/console/consoleweb/consoleapi/analytics.go b/satellite/console/consoleweb/consoleapi/analytics.go index a7759c65c..5190fd1d7 100644 --- a/satellite/console/consoleweb/consoleapi/analytics.go +++ b/satellite/console/consoleweb/consoleapi/analytics.go @@ -36,9 +36,10 @@ func NewAnalytics(log *zap.Logger, service *console.Service, a *analytics.Servic } type eventTriggeredBody struct { - EventName string `json:"eventName"` - Link string `json:"link"` - ErrorEventSource string `json:"errorEventSource"` + EventName string `json:"eventName"` + Link string `json:"link"` + ErrorEventSource string `json:"errorEventSource"` + Props map[string]string `json:"props"` } type pageVisitBody struct { @@ -72,7 +73,7 @@ func (a *Analytics) EventTriggered(w http.ResponseWriter, r *http.Request) { } else if et.Link != "" { a.analytics.TrackLinkEvent(et.EventName, user.ID, user.Email, et.Link) } else { - a.analytics.TrackEvent(et.EventName, user.ID, user.Email) + a.analytics.TrackEvent(et.EventName, user.ID, user.Email, et.Props) } w.WriteHeader(http.StatusOK) } diff --git a/web/satellite/src/api/analytics.ts b/web/satellite/src/api/analytics.ts index 69c0b90e5..3b13f08c9 100644 --- a/web/satellite/src/api/analytics.ts +++ b/web/satellite/src/api/analytics.ts @@ -17,13 +17,17 @@ export class AnalyticsHttpApi { * Does not throw any errors so that expected UI behavior is not interrupted if the API call fails. * * @param eventName - name of the event + * @param props - additional properties to send with the event */ - public async eventTriggered(eventName: string): Promise { + public async eventTriggered(eventName: string, props?: {[p:string]:string}): Promise { try { const path = `${this.ROOT_PATH}/event`; const body = { eventName: eventName, }; + if (props) { + body['props'] = props; + } const response = await this.http.post(path, JSON.stringify(body)); if (response.ok) { return; diff --git a/web/satellite/src/components/modals/EnterPassphraseModal.vue b/web/satellite/src/components/modals/EnterPassphraseModal.vue index e67dc22f8..e54531aad 100644 --- a/web/satellite/src/components/modals/EnterPassphraseModal.vue +++ b/web/satellite/src/components/modals/EnterPassphraseModal.vue @@ -50,7 +50,7 @@ import { ref } from 'vue'; import AccessEncryptionIcon from '../../../static/images/accessGrants/newCreateFlow/accessEncryption.svg'; import { AnalyticsHttpApi } from '@/api/analytics'; -import { AnalyticsErrorEventSource } from '@/utils/constants/analyticsEventNames'; +import { AnalyticsErrorEventSource, AnalyticsEvent } from '@/utils/constants/analyticsEventNames'; import { useAppStore } from '@/store/modules/appStore'; import { useBucketsStore } from '@/store/modules/bucketsStore'; import { MODALS } from '@/utils/constants/appStatePopUps'; @@ -78,6 +78,10 @@ function onContinue(): void { return; } + analytics.eventTriggered(AnalyticsEvent.PASSPHRASE_CREATED, { + method: 'enter', + }); + bucketsStore.setPassphrase(passphrase.value); bucketsStore.setPromptForPassphrase(false); diff --git a/web/satellite/src/components/modals/createProjectPassphrase/CreateProjectPassphraseModal.vue b/web/satellite/src/components/modals/createProjectPassphrase/CreateProjectPassphraseModal.vue index a8b745dcf..8b610c994 100644 --- a/web/satellite/src/components/modals/createProjectPassphrase/CreateProjectPassphraseModal.vue +++ b/web/satellite/src/components/modals/createProjectPassphrase/CreateProjectPassphraseModal.vue @@ -46,7 +46,8 @@ import { RouteConfig } from '@/types/router'; import { EdgeCredentials } from '@/types/accessGrants'; import { useAppStore } from '@/store/modules/appStore'; import { useBucketsStore } from '@/store/modules/bucketsStore'; -import { AnalyticsErrorEventSource } from '@/utils/constants/analyticsEventNames'; +import { AnalyticsErrorEventSource, AnalyticsEvent } from '@/utils/constants/analyticsEventNames'; +import { AnalyticsHttpApi } from '@/api/analytics'; import VModal from '@/components/common/VModal.vue'; import SelectPassphraseModeStep from '@/components/modals/createProjectPassphrase/SelectPassphraseModeStep.vue'; @@ -72,6 +73,8 @@ const notify = useNotify(); const router = useRouter(); const route = useRoute(); +const analytics: AnalyticsHttpApi = new AnalyticsHttpApi(); + const generatedPassphrase = generateMnemonic(); const selectedOption = ref(CreatePassphraseOption.Generate); @@ -136,6 +139,10 @@ async function onContinue(): Promise { return; } + analytics.eventTriggered(AnalyticsEvent.PASSPHRASE_CREATED, { + method: selectedOption.value === CreatePassphraseOption.Enter ? 'enter' : 'generate', + }); + bucketsStore.setEdgeCredentials(new EdgeCredentials()); bucketsStore.setPassphrase(passphrase.value); bucketsStore.setPromptForPassphrase(false); diff --git a/web/satellite/src/utils/constants/analyticsEventNames.ts b/web/satellite/src/utils/constants/analyticsEventNames.ts index 8aed4f661..0bf81455c 100644 --- a/web/satellite/src/utils/constants/analyticsEventNames.ts +++ b/web/satellite/src/utils/constants/analyticsEventNames.ts @@ -54,6 +54,7 @@ export enum AnalyticsEvent { GALLERY_VIEW_CLICKED = 'Gallery View Clicked', PROJECT_INVITATION_ACCEPTED = 'Project Invitation Accepted', PROJECT_INVITATION_DECLINED = 'Project Invitation Declined', + PASSPHRASE_CREATED = 'Passphrase Created', } export enum AnalyticsErrorEventSource {