satellite/analytics: Added analytics for "passphrase created", "account verified" and "external_link_clicked" (#4078)
This commit is contained in:
parent
037c7799b5
commit
d2705c1143
@ -11,11 +11,14 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
eventAccountCreated = "Account Created"
|
||||
eventSignedIn = "Signed In"
|
||||
eventProjectCreated = "Project Created"
|
||||
eventAccessGrantCreated = "Access Grant Created"
|
||||
gatewayCredentialsCreated = "Credentials Created"
|
||||
eventAccountCreated = "Account Created"
|
||||
eventSignedIn = "Signed In"
|
||||
eventProjectCreated = "Project Created"
|
||||
eventAccessGrantCreated = "Access Grant Created"
|
||||
eventAccountVerified = "Account Verified"
|
||||
eventGatewayCredentialsCreated = "Credentials Created"
|
||||
eventPassphraseCreated = "Passphrase Created"
|
||||
eventExternalLinkClicked = "External Link Clicked"
|
||||
)
|
||||
|
||||
// Config is a configuration struct for analytics Service.
|
||||
@ -47,7 +50,7 @@ func NewService(log *zap.Logger, config Config, satelliteName string) *Service {
|
||||
if config.Enabled {
|
||||
service.segment = segment.New(config.SegmentWriteKey)
|
||||
}
|
||||
for _, name := range []string{gatewayCredentialsCreated} {
|
||||
for _, name := range []string{eventGatewayCredentialsCreated, eventPassphraseCreated, eventExternalLinkClicked} {
|
||||
service.clientEvents[name] = true
|
||||
}
|
||||
return service
|
||||
@ -170,6 +173,26 @@ func (service *Service) TrackAccessGrantCreated(userID uuid.UUID) {
|
||||
})
|
||||
}
|
||||
|
||||
// TrackAccountVerified sends an "Account Verified" event to Segment.
|
||||
func (service *Service) TrackAccountVerified(userID uuid.UUID, email string) {
|
||||
traits := segment.NewTraits()
|
||||
traits.SetEmail(email)
|
||||
|
||||
service.enqueueMessage(segment.Identify{
|
||||
UserId: userID.String(),
|
||||
Traits: traits,
|
||||
})
|
||||
|
||||
props := segment.NewProperties()
|
||||
props.Set("email", email)
|
||||
|
||||
service.enqueueMessage(segment.Track{
|
||||
UserId: userID.String(),
|
||||
Event: eventAccountVerified,
|
||||
Properties: props,
|
||||
})
|
||||
}
|
||||
|
||||
// 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) {
|
||||
@ -178,9 +201,28 @@ func (service *Service) TrackEvent(eventName string, userID uuid.UUID) {
|
||||
service.log.Error("Invalid client-triggered event", zap.String("eventName", eventName))
|
||||
return
|
||||
}
|
||||
|
||||
service.enqueueMessage(segment.Track{
|
||||
UserId: userID.String(),
|
||||
Event: eventName,
|
||||
})
|
||||
}
|
||||
|
||||
// TrackLinkEvent sends an arbitrary event and link associated with user ID to Segment.
|
||||
// It is used for tracking occurrences of client-side events.
|
||||
func (service *Service) TrackLinkEvent(eventName string, userID uuid.UUID, link string) {
|
||||
|
||||
// do not track if the event name is an invalid client-side event
|
||||
if !service.clientEvents[eventName] {
|
||||
service.log.Error("Invalid client-triggered event", zap.String("eventName", eventName))
|
||||
return
|
||||
}
|
||||
|
||||
props := segment.NewProperties()
|
||||
props.Set("link", link)
|
||||
|
||||
service.enqueueMessage(segment.Track{
|
||||
UserId: userID.String(),
|
||||
Event: eventName,
|
||||
Properties: props,
|
||||
})
|
||||
}
|
||||
|
@ -38,6 +38,7 @@ func NewAnalytics(log *zap.Logger, service *console.Service, a *analytics.Servic
|
||||
|
||||
type eventTriggeredBody struct {
|
||||
EventName string `json:"eventName"`
|
||||
Link string `json:"link"`
|
||||
}
|
||||
|
||||
// EventTriggered tracks the occurrence of an arbitrary event on the client.
|
||||
@ -61,7 +62,11 @@ func (a *Analytics) EventTriggered(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
a.analytics.TrackEvent(et.EventName, userID)
|
||||
if et.Link != "" {
|
||||
a.analytics.TrackLinkEvent(et.EventName, userID, et.Link)
|
||||
} else {
|
||||
a.analytics.TrackEvent(et.EventName, userID)
|
||||
}
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
|
@ -698,6 +698,8 @@ func (s *Service) ActivateAccount(ctx context.Context, activationToken string) (
|
||||
s.log.Debug(fmt.Sprintf("could not add promotional coupon for user %s", user.ID.String()), zap.Error(Error.Wrap(err)))
|
||||
}
|
||||
|
||||
s.analytics.TrackAccountVerified(user.ID, user.Email)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -29,4 +29,17 @@ export class AnalyticsHttpApi {
|
||||
|
||||
throw new Error('Can not track event');
|
||||
}
|
||||
|
||||
public async linkEventTriggered(eventName: string, link: string): Promise<void> {
|
||||
const path = `${this.ROOT_PATH}/event`;
|
||||
const body = {
|
||||
eventName: eventName,
|
||||
link: link,
|
||||
};
|
||||
const response = await this.http.post(path, JSON.stringify(body));
|
||||
if (response.ok) {
|
||||
return;
|
||||
}
|
||||
throw new Error('Can not track event');
|
||||
}
|
||||
}
|
||||
|
@ -85,6 +85,9 @@ import VButton from '@/components/common/VButton.vue';
|
||||
import BackIcon from '@/../static/images/accessGrants/back.svg';
|
||||
import WarningIcon from '@/../static/images/accessGrants/warning.svg';
|
||||
|
||||
import { AnalyticsEvent } from '@/utils/constants/analyticsEventNames';
|
||||
import { AnalyticsHttpApi } from '@/api/analytics';
|
||||
|
||||
@Component({
|
||||
components: {
|
||||
WarningIcon,
|
||||
@ -100,6 +103,7 @@ export default class GeneratePassphrase extends Vue {
|
||||
public readonly setParentPassphrase: (passphrase: string) => void;
|
||||
@Prop({ default: false })
|
||||
public readonly isLoading: boolean;
|
||||
private readonly analytics: AnalyticsHttpApi = new AnalyticsHttpApi();
|
||||
|
||||
public isGenerateState: boolean = true;
|
||||
public isCreateState: boolean = false;
|
||||
@ -130,6 +134,8 @@ export default class GeneratePassphrase extends Vue {
|
||||
return;
|
||||
}
|
||||
|
||||
this.analytics.eventTriggered(AnalyticsEvent.PASSPHRASE_CREATED);
|
||||
|
||||
this.onButtonClick();
|
||||
}
|
||||
|
||||
|
@ -12,6 +12,9 @@ import SupportIcon from '@/../static/images/header/support.svg';
|
||||
|
||||
import { RouteConfig } from '@/router';
|
||||
|
||||
import { AnalyticsEvent } from '@/utils/constants/analyticsEventNames';
|
||||
import { AnalyticsHttpApi } from '@/api/analytics';
|
||||
|
||||
@Component({
|
||||
components: {
|
||||
DocsIcon,
|
||||
@ -20,12 +23,26 @@ import { RouteConfig } from '@/router';
|
||||
},
|
||||
})
|
||||
export default class ResourcesDropdown extends Vue {
|
||||
|
||||
private readonly analytics: AnalyticsHttpApi = new AnalyticsHttpApi();
|
||||
/**
|
||||
* Indicates if current route is onboarding tour.
|
||||
*/
|
||||
public get isOnboardingTour(): boolean {
|
||||
return this.$route.path.includes(RouteConfig.OnboardingTour.path);
|
||||
}
|
||||
|
||||
public onDocsIconClick(): void {
|
||||
this.analytics.linkEventTriggered(AnalyticsEvent.EXTERNAL_LINK_CLICKED, "https://documentation.storj.io");
|
||||
}
|
||||
|
||||
public onCommunityIconClick(): void {
|
||||
this.analytics.linkEventTriggered(AnalyticsEvent.EXTERNAL_LINK_CLICKED, "https://storj.io/community/");
|
||||
}
|
||||
|
||||
public onSupportIconClick(): void {
|
||||
this.analytics.linkEventTriggered(AnalyticsEvent.EXTERNAL_LINK_CLICKED, "mailto:support@storj.io");
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
|
@ -7,6 +7,7 @@
|
||||
href="https://documentation.storj.io"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
@click="onDocsIconClick"
|
||||
>
|
||||
<DocsIcon class="resources-dropdown__item-container__image"/>
|
||||
<p class="resources-dropdown__item-container__title">Docs</p>
|
||||
@ -16,6 +17,7 @@
|
||||
href="https://storj.io/community/"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
@click="onCommunityIconClick"
|
||||
>
|
||||
<CommunityIcon class="resources-dropdown__item-container__image"/>
|
||||
<p class="resources-dropdown__item-container__title">Community</p>
|
||||
@ -25,6 +27,7 @@
|
||||
href="mailto:support@storj.io"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
@click="onSupportIconClick"
|
||||
>
|
||||
<SupportIcon class="resources-dropdown__item-container__image"/>
|
||||
<p class="resources-dropdown__item-container__title">Support</p>
|
||||
|
@ -4,4 +4,6 @@
|
||||
// Make sure these event names match up with the client-side event names in satellite/analytics/service.go
|
||||
export enum AnalyticsEvent {
|
||||
GATEWAY_CREDENTIALS_CREATED = 'Credentials Created',
|
||||
PASSPHRASE_CREATED = 'Passphrase Created',
|
||||
EXTERNAL_LINK_CLICKED = 'External Link Clicked',
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user