satellite/analytics: Added track calls for user behavioral events (#5009)

satellite/analytics: Added Access Grant page analytics events
This commit is contained in:
prerna-parashar 2022-08-08 11:17:35 -07:00 committed by GitHub
parent 731fecd96f
commit e8b716f97b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 87 additions and 7 deletions

View File

@ -49,6 +49,17 @@ const (
eventBucketCreated = "Bucket Created"
eventBucketDeleted = "Bucket Deleted"
eventProjectLimitError = "Project Limit Error"
eventAPIAccessCreated = "API Access Created"
eventUploadFileClicked = "Upload File Clicked"
eventUploadFolderClicked = "Upload Folder Clicked"
eventStorjTokenAdded = "Storj Token Added"
eventCreateKeysClicked = "Create Keys Clicked"
eventDownloadTxtClicked = "Download txt clicked"
eventEncryptMyAccessClicked = "Encrypt My Access Clicked"
eventCopyToClipboardClicked = "Copy to Clipboard Clicked"
eventCreateAccessGrantClicked = "Create Access Grant Clicked"
eventCreateS3CredentialsClicked = "Create S3 Credentials Clicked"
eventKeysForCLIClicked = "Keys for CLI Clicked"
)
var (
@ -93,7 +104,9 @@ func NewService(log *zap.Logger, config Config, satelliteName string) *Service {
eventModalAddCard, eventModalAddTokens, eventSearchBuckets, eventNavigateProjects, eventManageProjectsClicked,
eventCreateNewClicked, eventViewDocsClicked, eventViewForumClicked, eventViewSupportClicked, eventCreateAnAccessGrantClicked,
eventUploadUsingCliClicked, eventUploadInWebClicked, eventNewProjectClicked, eventLogoutClicked, eventProfileUpdated,
eventPasswordChanged, eventMfaEnabled, eventBucketCreated, eventBucketDeleted} {
eventPasswordChanged, eventMfaEnabled, eventBucketCreated, eventBucketDeleted, eventAccessGrantCreated, eventAPIAccessCreated,
eventUploadFileClicked, eventUploadFolderClicked, eventCreateKeysClicked, eventDownloadTxtClicked, eventEncryptMyAccessClicked,
eventCopyToClipboardClicked, eventCreateAccessGrantClicked, eventCreateS3CredentialsClicked, eventKeysForCLIClicked} {
service.clientEvents[name] = true
}
@ -425,3 +438,20 @@ func (service *Service) TrackProjectLimitError(userID uuid.UUID, email string) {
})
}
// TrackStorjTokenAdded sends an "Storj Token Added" event to Segment.
func (service *Service) TrackStorjTokenAdded(userID uuid.UUID, email string) {
if !service.config.Enabled {
return
}
props := segment.NewProperties()
props.Set("email", email)
service.enqueueMessage(segment.Track{
UserId: userID.String(),
Event: service.satelliteName + " " + eventStorjTokenAdded,
Properties: props,
})
}

View File

@ -528,7 +528,13 @@ func (payment Payments) TokenDeposit(ctx context.Context, amount int64) (_ *paym
tx, err := payment.service.accounts.StorjTokens().Deposit(ctx, user.ID, amount)
return tx, Error.Wrap(err)
if err != nil {
return nil, Error.Wrap(err)
}
payment.service.analytics.TrackStorjTokenAdded(user.ID, user.Email)
return tx, nil
}
// checkOutstandingInvoice returns if the payment account has any unpaid/outstanding invoices or/and invoice items.

View File

@ -39,6 +39,7 @@
href="https://docs.storj.io/dcs/concepts/access/access-grants/"
target="_blank"
rel="noopener noreferrer"
@click="trackPageVisit('https://docs.storj.io/dcs/concepts/access/access-grants/')"
>
<VButton
label="Learn More"
@ -71,6 +72,7 @@
href="https://docs.storj.io/dcs/api-reference/s3-compatible-gateway"
target="_blank"
rel="noopener noreferrer"
@click="trackPageVisit('https://docs.storj.io/dcs/api-reference/s3-compatible-gateway')"
>
<VButton
label="Learn More"
@ -103,6 +105,7 @@
href="https://docs.storj.io/dcs/getting-started/quickstart-uplink-cli/generate-access-grants-and-tokens/generate-a-token/"
target="_blank"
rel="noopener noreferrer"
@click="trackPageVisit('https://docs.storj.io/dcs/getting-started/quickstart-uplink-cli/generate-access-grants-and-tokens/generate-a-token/')"
>
<VButton
label="Learn More"
@ -237,6 +240,7 @@ import { ACCESS_GRANTS_ACTIONS } from '@/store/modules/accessGrants';
import { AccessGrant, AccessGrantsOrderBy } from '@/types/accessGrants';
import { SortDirection } from '@/types/common';
import { AnalyticsHttpApi } from '@/api/analytics';
import { AnalyticsEvent } from '@/utils/constants/analyticsEventNames';
const {
FETCH,
@ -426,6 +430,7 @@ export default class AccessGrants extends Vue {
*/
public accessGrantClick(): void {
this.modalAccessType = 'access';
this.analytics.eventTriggered(AnalyticsEvent.CREATE_ACCESS_GRANT_CLICKED);
this.toggleAccessModal();
}
@ -434,6 +439,7 @@ export default class AccessGrants extends Vue {
*/
public s3Click(): void {
this.modalAccessType = 's3';
this.analytics.eventTriggered(AnalyticsEvent.CREATE_S3_CREDENTIALS_CLICKED);
this.toggleAccessModal();
}
@ -442,6 +448,7 @@ export default class AccessGrants extends Vue {
*/
public cliClick(): void {
this.modalAccessType = 'api';
this.analytics.eventTriggered(AnalyticsEvent.CREATE_KEYS_FOR_CLI_CLICKED);
this.toggleAccessModal();
}
@ -451,6 +458,13 @@ export default class AccessGrants extends Vue {
public toggleAccessModal(): void {
this.showAccessModal = !this.showAccessModal;
}
/**
* Sends "trackPageVisit" event to segment and opens link.
*/
public trackPageVisit(link: string): void {
this.analytics.pageVisit(link);
}
}
</script>
<style scoped lang="scss">

View File

@ -10,7 +10,7 @@
@mouseover="toggleTooltipHover('access','over')"
@mouseleave="toggleTooltipHover('access','leave')"
>
<span class="tooltip-text">Keys to upload, delete, and view your project's data. <a class="tooltip-link" href="https://docs.storj.io/dcs/concepts/access/access-grants" target="_blank" rel="noreferrer noopener">Learn More</a></span>
<span class="tooltip-text">Keys to upload, delete, and view your project's data. <a class="tooltip-link" href="https://docs.storj.io/dcs/concepts/access/access-grants" target="_blank" rel="noreferrer noopener" @click="trackPageVisit('https://docs.storj.io/dcs/concepts/access/access-grants')">Learn More</a></span>
</div>
<div
v-if="tooltipHover === 's3'"
@ -18,7 +18,7 @@
@mouseover="toggleTooltipHover('s3','over')"
@mouseleave="toggleTooltipHover('s3','leave')"
>
<span class="tooltip-text">Generates access key, secret key, and endpoint to use in your S3-supporting application. <a class="tooltip-link" href="https://docs.storj.io/dcs/api-reference/s3-compatible-gateway" target="_blank" rel="noreferrer noopener">Learn More</a></span>
<span class="tooltip-text">Generates access key, secret key, and endpoint to use in your S3-supporting application. <a class="tooltip-link" href="https://docs.storj.io/dcs/api-reference/s3-compatible-gateway" target="_blank" rel="noreferrer noopener" @click="trackPageVisit('https://docs.storj.io/dcs/api-reference/s3-compatible-gateway')">Learn More</a></span>
</div>
<div
v-if="tooltipHover === 'api'"
@ -26,7 +26,7 @@
@mouseover="toggleTooltipHover('api','over')"
@mouseleave="toggleTooltipHover('api','leave')"
>
<span class="tooltip-text">Creates access grant to run in the command line. <a class="tooltip-link" href="https://docs.storj.io/dcs/getting-started/quickstart-uplink-cli/generate-access-grants-and-tokens/generate-a-token/" target="_blank" rel="noreferrer noopener">Learn More</a></span>
<span class="tooltip-text">Creates access grant to run in the command line. <a class="tooltip-link" href="https://docs.storj.io/dcs/getting-started/quickstart-uplink-cli/generate-access-grants-and-tokens/generate-a-token/" target="_blank" rel="noreferrer noopener" @click="trackPageVisit('https://docs.storj.io/dcs/getting-started/quickstart-uplink-cli/generate-access-grants-and-tokens/generate-a-token/')">Learn More</a></span>
</div>
<!-- ********* Create Form Modal ********* -->
<form v-if="accessGrantStep === 'create'">
@ -697,6 +697,12 @@ export default class CreateAccessModal extends Vue {
private restrictedKey = '';
public satelliteAddress: string = MetaUtils.getMetaContent('satellite-nodeurl');
/**
* Sends "trackPageVisit" event to segment and opens link.
*/
public trackPageVisit(link: string): void {
this.analytics.pageVisit(link);
}
/**
* Checks which type was selected and retrieves buckets on mount.
@ -809,15 +815,20 @@ export default class CreateAccessModal extends Vue {
await this.$store.dispatch(ACCESS_GRANTS_ACTIONS.GET_GATEWAY_CREDENTIALS, {accessGrant: this.access});
await this.$notify.success('Gateway credentials were generated successfully');
await this.analytics.eventTriggered(AnalyticsEvent.GATEWAY_CREDENTIALS_CREATED);
this.areKeysVisible = true;
} catch (error) {
await this.$notify.error(error.message);
}
} else if (this.checkedType === 'api') {
await this.analytics.eventTriggered(AnalyticsEvent.API_ACCESS_CREATED);
} else if (this.checkedType === 'access') {
await this.analytics.eventTriggered(AnalyticsEvent.ACCESS_GRANT_CREATED);
}
this.analytics.eventTriggered(AnalyticsEvent.CREATE_KEYS_CLICKED);
this.accessGrantStep = 'grantCreated';
}
@ -827,6 +838,7 @@ export default class CreateAccessModal extends Vue {
public downloadPassphrase(): void {
this.isPassphraseDownloaded = true;
Download.file(this.passphrase, `passphrase-${this.currentDate}.txt`)
this.analytics.eventTriggered(AnalyticsEvent.DOWNLOAD_TXT_CLICKED);
}
/**
@ -839,6 +851,7 @@ export default class CreateAccessModal extends Vue {
api: [`satellite address: ${this.satelliteAddress}\nrestricted key: ${this.restrictedKey}`]
}
this.areCredentialsDownloaded = true;
this.analytics.eventTriggered(AnalyticsEvent.DOWNLOAD_TXT_CLICKED);
Download.file(credentialMap[this.checkedType], `${this.checkedType}-credentials-${this.currentDate}.txt`)
}
@ -860,6 +873,7 @@ export default class CreateAccessModal extends Vue {
} else if (this.checkedType !== "api") {
this.accessGrantStep = 'encrypt';
}
this.analytics.eventTriggered(AnalyticsEvent.ENCRYPT_MY_ACCESS_CLICKED);
}
public onCopyClick(item): void {
@ -870,12 +884,14 @@ export default class CreateAccessModal extends Vue {
public onCopyPassphraseClick(): void {
this.$copyText(this.passphrase);
this.isPassphraseCopied = true;
this.$notify.success(`Passphrase was copied successfully`);
this.analytics.eventTriggered(AnalyticsEvent.COPY_TO_CLIPBOARD_CLICKED);
this.$notify.success(`Passphrase was copied successfully`);
}
public onCopyAccessGrantClick(): void {
this.$copyText(this.restrictedKey);
this.isAccessGrantCopied = true;
this.analytics.eventTriggered(AnalyticsEvent.COPY_TO_CLIPBOARD_CLICKED);
this.$notify.success(`Access Grant was copied successfully`);
}

View File

@ -741,6 +741,7 @@ export default class FileBrowser extends Vue {
* Open the operating system's file system for file upload.
*/
public async buttonFileUpload(): Promise<void> {
this.analytics.eventTriggered(AnalyticsEvent.UPLOAD_FILE_CLICKED);
const fileInputElement = this.$refs.fileInput as HTMLInputElement;
fileInputElement.click();
this.closeUploadDropdown();
@ -750,6 +751,7 @@ export default class FileBrowser extends Vue {
* Open the operating system's file system for folder upload.
*/
public async buttonFolderUpload(): Promise<void> {
this.analytics.eventTriggered(AnalyticsEvent.UPLOAD_FOLDER_CLICKED);
const folderInputElement = this.$refs.folderInput as HTMLInputElement;
folderInputElement.click();
this.closeUploadDropdown();

View File

@ -30,4 +30,16 @@ export enum AnalyticsEvent {
MFA_ENABLED = 'MFA Enabled',
BUCKET_CREATED = 'Bucket Created',
BUCKET_DELETED = 'Bucket Deleted',
ACCESS_GRANT_CREATED = 'Access Grant Created',
API_ACCESS_CREATED = 'API Access Created',
UPLOAD_FILE_CLICKED = 'Upload File Clicked',
UPLOAD_FOLDER_CLICKED = 'Upload Folder Clicked',
CREATE_KEYS_CLICKED = 'Create Keys Clicked',
DOWNLOAD_TXT_CLICKED = 'Download txt clicked',
ENCRYPT_MY_ACCESS_CLICKED = 'Encrypt My Access Clicked',
COPY_TO_CLIPBOARD_CLICKED = 'Copy to Clipboard Clicked',
CREATE_ACCESS_GRANT_CLICKED = 'Create Access Grant Clicked',
CREATE_S3_CREDENTIALS_CLICKED = 'Create S3 Credentials Clicked',
CREATE_KEYS_FOR_CLI_CLICKED = 'Create Keys For CLI Clicked',
}