satellite/{web,analytics}: add segment events for passphrase modals

This change sends new passphrase created event for when passphrase is
created with the method by which it was; entered/generated

Issue: #5918

Change-Id: Ib485b6ff7a968d4c84bf124e14c14c91478f0dfb
This commit is contained in:
Wilfred Asomani 2023-06-22 11:18:21 +00:00 committed by Storj Robot
parent 7530a3a83d
commit 1b912ec167
6 changed files with 29 additions and 8 deletions

View File

@ -466,7 +466,7 @@ func (service *Service) TrackAccountVerified(userID uuid.UUID, email string) {
// TrackEvent sends an arbitrary event associated with user ID to Segment. // TrackEvent sends an arbitrary event associated with user ID to Segment.
// It is used for tracking occurrences of client-side events. // 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 { if !service.config.Enabled {
return return
} }
@ -480,6 +480,10 @@ func (service *Service) TrackEvent(eventName string, userID uuid.UUID, email str
props := segment.NewProperties() props := segment.NewProperties()
props.Set("email", email) props.Set("email", email)
for key, value := range customProps {
props.Set(key, value)
}
service.enqueueMessage(segment.Track{ service.enqueueMessage(segment.Track{
UserId: userID.String(), UserId: userID.String(),
Event: service.satelliteName + " " + eventName, Event: service.satelliteName + " " + eventName,

View File

@ -39,6 +39,7 @@ type eventTriggeredBody struct {
EventName string `json:"eventName"` EventName string `json:"eventName"`
Link string `json:"link"` Link string `json:"link"`
ErrorEventSource string `json:"errorEventSource"` ErrorEventSource string `json:"errorEventSource"`
Props map[string]string `json:"props"`
} }
type pageVisitBody struct { type pageVisitBody struct {
@ -72,7 +73,7 @@ func (a *Analytics) EventTriggered(w http.ResponseWriter, r *http.Request) {
} else if et.Link != "" { } else if et.Link != "" {
a.analytics.TrackLinkEvent(et.EventName, user.ID, user.Email, et.Link) a.analytics.TrackLinkEvent(et.EventName, user.ID, user.Email, et.Link)
} else { } 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) w.WriteHeader(http.StatusOK)
} }

View File

@ -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. * 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 eventName - name of the event
* @param props - additional properties to send with the event
*/ */
public async eventTriggered(eventName: string): Promise<void> { public async eventTriggered(eventName: string, props?: {[p:string]:string}): Promise<void> {
try { try {
const path = `${this.ROOT_PATH}/event`; const path = `${this.ROOT_PATH}/event`;
const body = { const body = {
eventName: eventName, eventName: eventName,
}; };
if (props) {
body['props'] = props;
}
const response = await this.http.post(path, JSON.stringify(body)); const response = await this.http.post(path, JSON.stringify(body));
if (response.ok) { if (response.ok) {
return; return;

View File

@ -50,7 +50,7 @@ import { ref } from 'vue';
import AccessEncryptionIcon from '../../../static/images/accessGrants/newCreateFlow/accessEncryption.svg'; import AccessEncryptionIcon from '../../../static/images/accessGrants/newCreateFlow/accessEncryption.svg';
import { AnalyticsHttpApi } from '@/api/analytics'; 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 { useAppStore } from '@/store/modules/appStore';
import { useBucketsStore } from '@/store/modules/bucketsStore'; import { useBucketsStore } from '@/store/modules/bucketsStore';
import { MODALS } from '@/utils/constants/appStatePopUps'; import { MODALS } from '@/utils/constants/appStatePopUps';
@ -78,6 +78,10 @@ function onContinue(): void {
return; return;
} }
analytics.eventTriggered(AnalyticsEvent.PASSPHRASE_CREATED, {
method: 'enter',
});
bucketsStore.setPassphrase(passphrase.value); bucketsStore.setPassphrase(passphrase.value);
bucketsStore.setPromptForPassphrase(false); bucketsStore.setPromptForPassphrase(false);

View File

@ -46,7 +46,8 @@ import { RouteConfig } from '@/types/router';
import { EdgeCredentials } from '@/types/accessGrants'; import { EdgeCredentials } from '@/types/accessGrants';
import { useAppStore } from '@/store/modules/appStore'; import { useAppStore } from '@/store/modules/appStore';
import { useBucketsStore } from '@/store/modules/bucketsStore'; 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 VModal from '@/components/common/VModal.vue';
import SelectPassphraseModeStep from '@/components/modals/createProjectPassphrase/SelectPassphraseModeStep.vue'; import SelectPassphraseModeStep from '@/components/modals/createProjectPassphrase/SelectPassphraseModeStep.vue';
@ -72,6 +73,8 @@ const notify = useNotify();
const router = useRouter(); const router = useRouter();
const route = useRoute(); const route = useRoute();
const analytics: AnalyticsHttpApi = new AnalyticsHttpApi();
const generatedPassphrase = generateMnemonic(); const generatedPassphrase = generateMnemonic();
const selectedOption = ref<CreatePassphraseOption>(CreatePassphraseOption.Generate); const selectedOption = ref<CreatePassphraseOption>(CreatePassphraseOption.Generate);
@ -136,6 +139,10 @@ async function onContinue(): Promise<void> {
return; return;
} }
analytics.eventTriggered(AnalyticsEvent.PASSPHRASE_CREATED, {
method: selectedOption.value === CreatePassphraseOption.Enter ? 'enter' : 'generate',
});
bucketsStore.setEdgeCredentials(new EdgeCredentials()); bucketsStore.setEdgeCredentials(new EdgeCredentials());
bucketsStore.setPassphrase(passphrase.value); bucketsStore.setPassphrase(passphrase.value);
bucketsStore.setPromptForPassphrase(false); bucketsStore.setPromptForPassphrase(false);

View File

@ -54,6 +54,7 @@ export enum AnalyticsEvent {
GALLERY_VIEW_CLICKED = 'Gallery View Clicked', GALLERY_VIEW_CLICKED = 'Gallery View Clicked',
PROJECT_INVITATION_ACCEPTED = 'Project Invitation Accepted', PROJECT_INVITATION_ACCEPTED = 'Project Invitation Accepted',
PROJECT_INVITATION_DECLINED = 'Project Invitation Declined', PROJECT_INVITATION_DECLINED = 'Project Invitation Declined',
PASSPHRASE_CREATED = 'Passphrase Created',
} }
export enum AnalyticsErrorEventSource { export enum AnalyticsErrorEventSource {