2021-03-23 15:52:34 +00:00
|
|
|
// Copyright (C) 2021 Storj Labs, Inc.
|
|
|
|
// See LICENSE for copying information.
|
|
|
|
|
|
|
|
package analytics
|
|
|
|
|
|
|
|
import (
|
2021-12-09 20:52:51 +00:00
|
|
|
"context"
|
2022-03-24 16:59:28 +00:00
|
|
|
"strings"
|
2021-12-09 20:52:51 +00:00
|
|
|
|
|
|
|
"github.com/zeebo/errs"
|
2021-03-23 15:52:34 +00:00
|
|
|
"go.uber.org/zap"
|
|
|
|
segment "gopkg.in/segmentio/analytics-go.v3"
|
|
|
|
|
|
|
|
"storj.io/common/uuid"
|
|
|
|
)
|
|
|
|
|
|
|
|
const (
|
2023-09-13 20:24:05 +01:00
|
|
|
eventInviteLinkClicked = "Invite Link Clicked"
|
|
|
|
eventInviteLinkSignup = "Invite Link Signup"
|
2023-01-11 15:55:41 +00:00
|
|
|
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"
|
|
|
|
eventPathSelected = "Path Selected"
|
|
|
|
eventLinkShared = "Link Shared"
|
|
|
|
eventObjectUploaded = "Object Uploaded"
|
|
|
|
eventAPIKeyGenerated = "API Key Generated"
|
|
|
|
eventCreditCardAdded = "Credit Card Added"
|
|
|
|
eventUpgradeBannerClicked = "Upgrade Banner Clicked"
|
|
|
|
eventModalAddCard = "Credit Card Added In Modal"
|
|
|
|
eventModalAddTokens = "Storj Token Added In Modal"
|
|
|
|
eventSearchBuckets = "Search Buckets"
|
|
|
|
eventNavigateProjects = "Navigate Projects"
|
|
|
|
eventManageProjectsClicked = "Manage Projects Clicked"
|
|
|
|
eventCreateNewClicked = "Create New Clicked"
|
|
|
|
eventViewDocsClicked = "View Docs Clicked"
|
|
|
|
eventViewForumClicked = "View Forum Clicked"
|
|
|
|
eventViewSupportClicked = "View Support Clicked"
|
|
|
|
eventCreateAnAccessGrantClicked = "Create an Access Grant Clicked"
|
|
|
|
eventUploadUsingCliClicked = "Upload Using CLI Clicked"
|
|
|
|
eventUploadInWebClicked = "Upload In Web Clicked"
|
|
|
|
eventNewProjectClicked = "New Project Clicked"
|
|
|
|
eventLogoutClicked = "Logout Clicked"
|
|
|
|
eventProfileUpdated = "Profile Updated"
|
|
|
|
eventPasswordChanged = "Password Changed"
|
|
|
|
eventMfaEnabled = "MFA Enabled"
|
|
|
|
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 = "Create Keys For CLI Clicked"
|
|
|
|
eventSeePaymentsClicked = "See Payments Clicked"
|
|
|
|
eventEditPaymentMethodClicked = "Edit Payment Method Clicked"
|
|
|
|
eventUsageDetailedInfoClicked = "Usage Detailed Info Clicked"
|
|
|
|
eventAddNewPaymentMethodClicked = "Add New Payment Method Clicked"
|
|
|
|
eventApplyNewCouponClicked = "Apply New Coupon Clicked"
|
|
|
|
eventCreditCardRemoved = "Credit Card Removed"
|
|
|
|
eventCouponCodeApplied = "Coupon Code Applied"
|
|
|
|
eventInvoiceDownloaded = "Invoice Downloaded"
|
|
|
|
eventCreditCardAddedFromBilling = "Credit Card Added From Billing"
|
|
|
|
eventStorjTokenAddedFromBilling = "Storj Token Added From Billing"
|
|
|
|
eventAddFundsClicked = "Add Funds Clicked"
|
|
|
|
eventProjectMembersInviteSent = "Project Members Invite Sent"
|
|
|
|
eventProjectMemberAdded = "Project Member Added"
|
|
|
|
eventProjectMemberDeleted = "Project Member Deleted"
|
|
|
|
eventError = "UI error occurred"
|
|
|
|
eventProjectNameUpdated = "Project Name Updated"
|
|
|
|
eventProjectDescriptionUpdated = "Project Description Updated"
|
|
|
|
eventProjectStorageLimitUpdated = "Project Storage Limit Updated"
|
|
|
|
eventProjectBandwidthLimitUpdated = "Project Bandwidth Limit Updated"
|
2023-02-13 17:32:39 +00:00
|
|
|
eventAccountFrozen = "Account Frozen"
|
2023-03-10 11:19:07 +00:00
|
|
|
eventAccountUnfrozen = "Account Unfrozen"
|
2023-03-23 12:04:32 +00:00
|
|
|
eventAccountUnwarned = "Account Unwarned"
|
2023-02-13 17:32:39 +00:00
|
|
|
eventAccountFreezeWarning = "Account Freeze Warning"
|
|
|
|
eventUnpaidLargeInvoice = "Large Invoice Unpaid"
|
2023-07-07 18:31:53 +01:00
|
|
|
eventUnpaidStorjscanInvoice = "Storjscan Invoice Unpaid"
|
2023-09-28 15:55:24 +01:00
|
|
|
eventPendingDeletionUnpaidInvoice = "Pending Deletion Invoice Open"
|
2023-04-19 20:48:36 +01:00
|
|
|
eventExpiredCreditNeedsRemoval = "Expired Credit Needs Removal"
|
|
|
|
eventExpiredCreditRemoved = "Expired Credit Removed"
|
2023-06-09 19:03:39 +01:00
|
|
|
eventProjectInvitationAccepted = "Project Invitation Accepted"
|
|
|
|
eventProjectInvitationDeclined = "Project Invitation Declined"
|
2023-06-23 06:14:44 +01:00
|
|
|
eventGalleryViewClicked = "Gallery View Clicked"
|
2023-06-23 05:52:31 +01:00
|
|
|
eventResendInviteClicked = "Resend Invite Clicked"
|
2023-06-20 11:50:05 +01:00
|
|
|
eventCopyInviteLinkClicked = "Copy Invite Link Clicked"
|
|
|
|
eventRemoveProjectMemberCLicked = "Remove Member Clicked"
|
2023-09-06 13:30:55 +01:00
|
|
|
eventLimitIncreaseRequested = "Limit Increase Requested"
|
2021-03-23 15:52:34 +00:00
|
|
|
)
|
|
|
|
|
2021-12-09 20:52:51 +00:00
|
|
|
var (
|
|
|
|
// Error is the default error class the analytics package.
|
|
|
|
Error = errs.Class("analytics service")
|
|
|
|
)
|
|
|
|
|
2021-03-23 15:52:34 +00:00
|
|
|
// Config is a configuration struct for analytics Service.
|
|
|
|
type Config struct {
|
|
|
|
SegmentWriteKey string `help:"segment write key" default:""`
|
2021-03-27 22:43:22 +00:00
|
|
|
Enabled bool `help:"enable analytics reporting" default:"false"`
|
2021-12-09 20:52:51 +00:00
|
|
|
HubSpot HubSpotConfig
|
2021-03-23 15:52:34 +00:00
|
|
|
}
|
|
|
|
|
2023-04-19 01:02:47 +01:00
|
|
|
// FreezeTracker is an interface for account freeze event tracking methods.
|
|
|
|
type FreezeTracker interface {
|
|
|
|
// TrackAccountFrozen sends an account frozen event to Segment.
|
|
|
|
TrackAccountFrozen(userID uuid.UUID, email string)
|
|
|
|
|
|
|
|
// TrackAccountUnfrozen sends an account unfrozen event to Segment.
|
|
|
|
TrackAccountUnfrozen(userID uuid.UUID, email string)
|
|
|
|
|
|
|
|
// TrackAccountUnwarned sends an account unwarned event to Segment.
|
|
|
|
TrackAccountUnwarned(userID uuid.UUID, email string)
|
|
|
|
|
|
|
|
// TrackAccountFreezeWarning sends an account freeze warning event to Segment.
|
|
|
|
TrackAccountFreezeWarning(userID uuid.UUID, email string)
|
|
|
|
|
|
|
|
// TrackLargeUnpaidInvoice sends an event to Segment indicating that a user has not paid a large invoice.
|
|
|
|
TrackLargeUnpaidInvoice(invID string, userID uuid.UUID, email string)
|
2023-07-07 18:31:53 +01:00
|
|
|
|
2023-09-28 15:55:24 +01:00
|
|
|
// TrackViolationFrozenUnpaidInvoice sends an event to Segment indicating that a user has not paid an invoice
|
|
|
|
// and has been frozen due to violating ToS.
|
|
|
|
TrackViolationFrozenUnpaidInvoice(invID string, userID uuid.UUID, email string)
|
|
|
|
|
2023-07-07 18:31:53 +01:00
|
|
|
// TrackStorjscanUnpaidInvoice sends an event to Segment indicating that a user has not paid an invoice, but has storjscan transaction history.
|
|
|
|
TrackStorjscanUnpaidInvoice(invID string, userID uuid.UUID, email string)
|
2023-04-19 01:02:47 +01:00
|
|
|
}
|
|
|
|
|
2023-09-06 13:30:55 +01:00
|
|
|
// LimitRequestInfo holds data needed to request limit increase.
|
|
|
|
type LimitRequestInfo struct {
|
|
|
|
ProjectName string
|
|
|
|
LimitType string
|
|
|
|
CurrentLimit string
|
|
|
|
DesiredLimit string
|
|
|
|
}
|
|
|
|
|
2021-03-23 15:52:34 +00:00
|
|
|
// Service for sending analytics.
|
|
|
|
//
|
|
|
|
// architecture: Service
|
|
|
|
type Service struct {
|
|
|
|
log *zap.Logger
|
|
|
|
config Config
|
|
|
|
satelliteName string
|
2021-03-31 19:34:44 +01:00
|
|
|
clientEvents map[string]bool
|
2021-03-23 15:52:34 +00:00
|
|
|
|
|
|
|
segment segment.Client
|
2021-12-09 20:52:51 +00:00
|
|
|
hubspot *HubSpotEvents
|
2021-03-23 15:52:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// NewService creates new service for creating sending analytics.
|
|
|
|
func NewService(log *zap.Logger, config Config, satelliteName string) *Service {
|
2021-03-27 22:43:22 +00:00
|
|
|
service := &Service{
|
2021-03-23 15:52:34 +00:00
|
|
|
log: log,
|
|
|
|
config: config,
|
|
|
|
satelliteName: satelliteName,
|
2021-03-31 19:34:44 +01:00
|
|
|
clientEvents: make(map[string]bool),
|
2021-12-09 20:52:51 +00:00
|
|
|
hubspot: NewHubSpotEvents(log.Named("hubspotclient"), config.HubSpot, satelliteName),
|
2021-03-23 15:52:34 +00:00
|
|
|
}
|
2021-03-27 22:43:22 +00:00
|
|
|
if config.Enabled {
|
|
|
|
service.segment = segment.New(config.SegmentWriteKey)
|
|
|
|
}
|
2022-02-24 20:38:29 +00:00
|
|
|
for _, name := range []string{eventGatewayCredentialsCreated, eventPassphraseCreated, eventExternalLinkClicked,
|
2022-05-10 18:01:27 +01:00
|
|
|
eventPathSelected, eventLinkShared, eventObjectUploaded, eventAPIKeyGenerated, eventUpgradeBannerClicked,
|
2022-05-18 20:49:10 +01:00
|
|
|
eventModalAddCard, eventModalAddTokens, eventSearchBuckets, eventNavigateProjects, eventManageProjectsClicked,
|
|
|
|
eventCreateNewClicked, eventViewDocsClicked, eventViewForumClicked, eventViewSupportClicked, eventCreateAnAccessGrantClicked,
|
2022-06-17 20:57:10 +01:00
|
|
|
eventUploadUsingCliClicked, eventUploadInWebClicked, eventNewProjectClicked, eventLogoutClicked, eventProfileUpdated,
|
2022-08-08 19:17:35 +01:00
|
|
|
eventPasswordChanged, eventMfaEnabled, eventBucketCreated, eventBucketDeleted, eventAccessGrantCreated, eventAPIAccessCreated,
|
|
|
|
eventUploadFileClicked, eventUploadFolderClicked, eventCreateKeysClicked, eventDownloadTxtClicked, eventEncryptMyAccessClicked,
|
2022-09-29 07:20:24 +01:00
|
|
|
eventCopyToClipboardClicked, eventCreateAccessGrantClicked, eventCreateS3CredentialsClicked, eventKeysForCLIClicked,
|
|
|
|
eventSeePaymentsClicked, eventEditPaymentMethodClicked, eventUsageDetailedInfoClicked, eventAddNewPaymentMethodClicked,
|
|
|
|
eventApplyNewCouponClicked, eventCreditCardRemoved, eventCouponCodeApplied, eventInvoiceDownloaded, eventCreditCardAddedFromBilling,
|
2023-01-11 15:55:41 +00:00
|
|
|
eventStorjTokenAddedFromBilling, eventAddFundsClicked, eventProjectMembersInviteSent, eventError, eventProjectNameUpdated, eventProjectDescriptionUpdated,
|
2023-06-23 06:14:44 +01:00
|
|
|
eventProjectStorageLimitUpdated, eventProjectBandwidthLimitUpdated, eventProjectInvitationAccepted, eventProjectInvitationDeclined,
|
2023-06-20 11:50:05 +01:00
|
|
|
eventGalleryViewClicked, eventResendInviteClicked, eventRemoveProjectMemberCLicked, eventCopyInviteLinkClicked} {
|
2021-03-31 19:34:44 +01:00
|
|
|
service.clientEvents[name] = true
|
|
|
|
}
|
2021-12-09 20:52:51 +00:00
|
|
|
|
2021-03-27 22:43:22 +00:00
|
|
|
return service
|
2021-03-23 15:52:34 +00:00
|
|
|
}
|
|
|
|
|
2021-12-09 20:52:51 +00:00
|
|
|
// Run runs the service and use the context in new requests.
|
|
|
|
func (service *Service) Run(ctx context.Context) error {
|
|
|
|
if !service.config.Enabled {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
return service.hubspot.Run(ctx)
|
|
|
|
}
|
|
|
|
|
2021-03-23 15:52:34 +00:00
|
|
|
// Close closes the Segment client.
|
|
|
|
func (service *Service) Close() error {
|
2021-03-27 22:43:22 +00:00
|
|
|
if !service.config.Enabled {
|
|
|
|
return nil
|
|
|
|
}
|
2021-03-23 15:52:34 +00:00
|
|
|
return service.segment.Close()
|
|
|
|
}
|
|
|
|
|
|
|
|
// UserType is a type for distinguishing personal vs. professional users.
|
|
|
|
type UserType string
|
|
|
|
|
|
|
|
const (
|
|
|
|
// Professional defines a "professional" user type.
|
|
|
|
Professional UserType = "Professional"
|
|
|
|
// Personal defines a "personal" user type.
|
|
|
|
Personal UserType = "Personal"
|
|
|
|
)
|
|
|
|
|
|
|
|
// TrackCreateUserFields contains input data for tracking a create user event.
|
|
|
|
type TrackCreateUserFields struct {
|
2021-04-27 19:40:03 +01:00
|
|
|
ID uuid.UUID
|
|
|
|
AnonymousID string
|
|
|
|
FullName string
|
|
|
|
Email string
|
|
|
|
Type UserType
|
|
|
|
EmployeeCount string
|
|
|
|
CompanyName string
|
2023-04-03 11:17:09 +01:00
|
|
|
StorageNeeds string
|
2021-04-27 19:40:03 +01:00
|
|
|
JobTitle string
|
|
|
|
HaveSalesContact bool
|
2021-11-30 19:42:01 +00:00
|
|
|
OriginHeader string
|
|
|
|
Referrer string
|
2022-03-29 20:36:06 +01:00
|
|
|
HubspotUTK string
|
2022-07-29 22:27:24 +01:00
|
|
|
UserAgent string
|
2023-11-02 22:50:45 +00:00
|
|
|
SignupCaptcha *float64
|
2021-03-23 15:52:34 +00:00
|
|
|
}
|
|
|
|
|
2021-03-27 22:43:22 +00:00
|
|
|
func (service *Service) enqueueMessage(message segment.Message) {
|
|
|
|
err := service.segment.Enqueue(message)
|
|
|
|
if err != nil {
|
|
|
|
service.log.Error("Error enqueueing message", zap.Error(err))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-03-23 15:52:34 +00:00
|
|
|
// TrackCreateUser sends an "Account Created" event to Segment.
|
|
|
|
func (service *Service) TrackCreateUser(fields TrackCreateUserFields) {
|
2021-12-09 20:52:51 +00:00
|
|
|
if !service.config.Enabled {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2022-03-24 16:59:28 +00:00
|
|
|
fullName := fields.FullName
|
|
|
|
names := strings.SplitN(fullName, " ", 2)
|
|
|
|
|
|
|
|
var firstName string
|
|
|
|
var lastName string
|
|
|
|
|
|
|
|
if len(names) > 1 {
|
|
|
|
firstName = names[0]
|
|
|
|
lastName = names[1]
|
|
|
|
} else {
|
|
|
|
firstName = fullName
|
|
|
|
}
|
|
|
|
|
2021-03-23 15:52:34 +00:00
|
|
|
traits := segment.NewTraits()
|
2022-03-24 16:59:28 +00:00
|
|
|
traits.SetFirstName(firstName)
|
|
|
|
traits.SetLastName(lastName)
|
2021-03-23 15:52:34 +00:00
|
|
|
traits.SetEmail(fields.Email)
|
2022-03-24 16:59:28 +00:00
|
|
|
traits.Set("origin_header", fields.OriginHeader)
|
|
|
|
traits.Set("signup_referrer", fields.Referrer)
|
|
|
|
traits.Set("account_created", true)
|
2022-07-11 18:37:14 +01:00
|
|
|
if fields.Type == Professional {
|
|
|
|
traits.Set("have_sales_contact", fields.HaveSalesContact)
|
|
|
|
}
|
2022-07-29 22:27:24 +01:00
|
|
|
if len(fields.UserAgent) > 0 {
|
|
|
|
traits.Set("signup_partner", fields.UserAgent)
|
|
|
|
}
|
2021-03-23 15:52:34 +00:00
|
|
|
|
2021-03-27 22:43:22 +00:00
|
|
|
service.enqueueMessage(segment.Identify{
|
2021-04-08 22:04:44 +01:00
|
|
|
UserId: fields.ID.String(),
|
|
|
|
AnonymousId: fields.AnonymousID,
|
|
|
|
Traits: traits,
|
2021-03-23 15:52:34 +00:00
|
|
|
})
|
|
|
|
|
|
|
|
props := segment.NewProperties()
|
|
|
|
props.Set("email", fields.Email)
|
|
|
|
props.Set("name", fields.FullName)
|
|
|
|
props.Set("satellite_selected", service.satelliteName)
|
|
|
|
props.Set("account_type", fields.Type)
|
2021-11-30 19:42:01 +00:00
|
|
|
props.Set("origin_header", fields.OriginHeader)
|
|
|
|
props.Set("signup_referrer", fields.Referrer)
|
|
|
|
props.Set("account_created", true)
|
2023-11-02 22:50:45 +00:00
|
|
|
if fields.SignupCaptcha != nil {
|
|
|
|
props.Set("signup_captcha", &fields.SignupCaptcha)
|
|
|
|
}
|
2021-03-23 15:52:34 +00:00
|
|
|
|
|
|
|
if fields.Type == Professional {
|
|
|
|
props.Set("company_size", fields.EmployeeCount)
|
|
|
|
props.Set("company_name", fields.CompanyName)
|
|
|
|
props.Set("job_title", fields.JobTitle)
|
2023-04-03 11:17:09 +01:00
|
|
|
props.Set("storage_needs", fields.StorageNeeds)
|
2021-03-23 15:52:34 +00:00
|
|
|
}
|
|
|
|
|
2021-03-27 22:43:22 +00:00
|
|
|
service.enqueueMessage(segment.Track{
|
2021-04-08 22:04:44 +01:00
|
|
|
UserId: fields.ID.String(),
|
|
|
|
AnonymousId: fields.AnonymousID,
|
2022-03-24 16:59:28 +00:00
|
|
|
Event: service.satelliteName + " " + eventAccountCreated,
|
2021-04-08 22:04:44 +01:00
|
|
|
Properties: props,
|
2021-03-23 15:52:34 +00:00
|
|
|
})
|
2021-12-09 20:52:51 +00:00
|
|
|
|
|
|
|
service.hubspot.EnqueueCreateUser(fields)
|
2021-03-23 15:52:34 +00:00
|
|
|
}
|
2021-03-31 19:34:44 +01:00
|
|
|
|
2021-04-08 18:34:23 +01:00
|
|
|
// TrackSignedIn sends an "Signed In" event to Segment.
|
|
|
|
func (service *Service) TrackSignedIn(userID uuid.UUID, email string) {
|
2021-12-09 20:52:51 +00:00
|
|
|
if !service.config.Enabled {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2021-04-08 18:34:23 +01:00
|
|
|
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(),
|
2022-03-24 16:59:28 +00:00
|
|
|
Event: service.satelliteName + " " + eventSignedIn,
|
2021-04-08 18:34:23 +01:00
|
|
|
Properties: props,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
// TrackProjectCreated sends an "Project Created" event to Segment.
|
2021-12-09 20:52:51 +00:00
|
|
|
func (service *Service) TrackProjectCreated(userID uuid.UUID, email string, projectID uuid.UUID, currentProjectCount int) {
|
|
|
|
if !service.config.Enabled {
|
|
|
|
return
|
|
|
|
}
|
2021-04-08 18:34:23 +01:00
|
|
|
|
|
|
|
props := segment.NewProperties()
|
|
|
|
props.Set("project_count", currentProjectCount)
|
|
|
|
props.Set("project_id", projectID.String())
|
2022-03-29 21:05:56 +01:00
|
|
|
props.Set("email", email)
|
2021-04-08 18:34:23 +01:00
|
|
|
|
|
|
|
service.enqueueMessage(segment.Track{
|
|
|
|
UserId: userID.String(),
|
2022-03-24 16:59:28 +00:00
|
|
|
Event: service.satelliteName + " " + eventProjectCreated,
|
2021-04-08 18:34:23 +01:00
|
|
|
Properties: props,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2023-02-13 17:32:39 +00:00
|
|
|
// TrackAccountFrozen sends an account frozen event to Segment.
|
|
|
|
func (service *Service) TrackAccountFrozen(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 + " " + eventAccountFrozen,
|
|
|
|
Properties: props,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2023-09-06 13:30:55 +01:00
|
|
|
// TrackRequestLimitIncrease sends a limit increase request to Segment.
|
|
|
|
func (service *Service) TrackRequestLimitIncrease(userID uuid.UUID, email string, info LimitRequestInfo) {
|
|
|
|
if !service.config.Enabled {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
props := segment.NewProperties()
|
|
|
|
props.Set("email", email)
|
|
|
|
props.Set("satellite", service.satelliteName)
|
2023-10-04 22:11:56 +01:00
|
|
|
if info.ProjectName != "" {
|
|
|
|
props.Set("project", info.ProjectName)
|
|
|
|
}
|
2023-09-06 13:30:55 +01:00
|
|
|
props.Set("type", info.LimitType)
|
|
|
|
props.Set("currentLimit", info.CurrentLimit)
|
|
|
|
props.Set("desiredLimit", info.DesiredLimit)
|
|
|
|
|
|
|
|
service.enqueueMessage(segment.Track{
|
|
|
|
UserId: userID.String(),
|
|
|
|
Event: service.satelliteName + " " + eventLimitIncreaseRequested,
|
|
|
|
Properties: props,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2023-03-10 11:19:07 +00:00
|
|
|
// TrackAccountUnfrozen sends an account unfrozen event to Segment.
|
|
|
|
func (service *Service) TrackAccountUnfrozen(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 + " " + eventAccountUnfrozen,
|
|
|
|
Properties: props,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2023-03-23 12:04:32 +00:00
|
|
|
// TrackAccountUnwarned sends an account unwarned event to Segment.
|
|
|
|
func (service *Service) TrackAccountUnwarned(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 + " " + eventAccountUnwarned,
|
|
|
|
Properties: props,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2023-02-13 17:32:39 +00:00
|
|
|
// TrackAccountFreezeWarning sends an account freeze warning event to Segment.
|
|
|
|
func (service *Service) TrackAccountFreezeWarning(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 + " " + eventAccountFreezeWarning,
|
|
|
|
Properties: props,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
// TrackLargeUnpaidInvoice sends an event to Segment indicating that a user has not paid a large invoice.
|
|
|
|
func (service *Service) TrackLargeUnpaidInvoice(invID string, userID uuid.UUID, email string) {
|
|
|
|
if !service.config.Enabled {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
props := segment.NewProperties()
|
|
|
|
props.Set("email", email)
|
|
|
|
props.Set("invoice", invID)
|
|
|
|
|
|
|
|
service.enqueueMessage(segment.Track{
|
|
|
|
UserId: userID.String(),
|
|
|
|
Event: service.satelliteName + " " + eventUnpaidLargeInvoice,
|
|
|
|
Properties: props,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2023-09-28 15:55:24 +01:00
|
|
|
// TrackViolationFrozenUnpaidInvoice sends an event to Segment indicating that a user has not paid a large invoice.
|
|
|
|
func (service *Service) TrackViolationFrozenUnpaidInvoice(invID string, userID uuid.UUID, email string) {
|
|
|
|
if !service.config.Enabled {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
props := segment.NewProperties()
|
|
|
|
props.Set("email", email)
|
|
|
|
props.Set("invoice", invID)
|
|
|
|
|
|
|
|
service.enqueueMessage(segment.Track{
|
|
|
|
UserId: userID.String(),
|
|
|
|
Event: service.satelliteName + " " + eventPendingDeletionUnpaidInvoice,
|
|
|
|
Properties: props,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2023-07-07 18:31:53 +01:00
|
|
|
// TrackStorjscanUnpaidInvoice sends an event to Segment indicating that a user has not paid an invoice, but has storjscan transaction history.
|
|
|
|
func (service *Service) TrackStorjscanUnpaidInvoice(invID string, userID uuid.UUID, email string) {
|
|
|
|
if !service.config.Enabled {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
props := segment.NewProperties()
|
|
|
|
props.Set("email", email)
|
|
|
|
props.Set("invoice", invID)
|
|
|
|
|
|
|
|
service.enqueueMessage(segment.Track{
|
|
|
|
UserId: userID.String(),
|
|
|
|
Event: service.satelliteName + " " + eventUnpaidStorjscanInvoice,
|
|
|
|
Properties: props,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2021-04-08 18:34:23 +01:00
|
|
|
// TrackAccessGrantCreated sends an "Access Grant Created" event to Segment.
|
2021-12-09 20:52:51 +00:00
|
|
|
func (service *Service) TrackAccessGrantCreated(userID uuid.UUID, email string) {
|
|
|
|
if !service.config.Enabled {
|
|
|
|
return
|
|
|
|
}
|
2021-04-08 18:34:23 +01:00
|
|
|
|
2022-03-29 21:05:56 +01:00
|
|
|
props := segment.NewProperties()
|
|
|
|
props.Set("email", email)
|
|
|
|
|
2021-04-08 18:34:23 +01:00
|
|
|
service.enqueueMessage(segment.Track{
|
2022-03-29 21:05:56 +01:00
|
|
|
UserId: userID.String(),
|
|
|
|
Event: service.satelliteName + " " + eventAccessGrantCreated,
|
|
|
|
Properties: props,
|
2021-04-08 18:34:23 +01:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2021-04-12 17:58:36 +01:00
|
|
|
// TrackAccountVerified sends an "Account Verified" event to Segment.
|
|
|
|
func (service *Service) TrackAccountVerified(userID uuid.UUID, email string) {
|
2021-12-09 20:52:51 +00:00
|
|
|
if !service.config.Enabled {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2021-04-12 17:58:36 +01:00
|
|
|
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(),
|
2022-03-24 16:59:28 +00:00
|
|
|
Event: service.satelliteName + " " + eventAccountVerified,
|
2021-04-12 17:58:36 +01:00
|
|
|
Properties: props,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2021-03-31 19:34:44 +01:00
|
|
|
// TrackEvent sends an arbitrary event associated with user ID to Segment.
|
|
|
|
// It is used for tracking occurrences of client-side events.
|
2023-10-13 06:39:30 +01:00
|
|
|
func (service *Service) TrackEvent(eventName string, userID uuid.UUID, email, uiType string, customProps map[string]string) {
|
2021-12-09 20:52:51 +00:00
|
|
|
if !service.config.Enabled {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2021-03-31 19:34:44 +01:00
|
|
|
// 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
|
|
|
|
}
|
2022-03-29 21:05:56 +01:00
|
|
|
|
|
|
|
props := segment.NewProperties()
|
|
|
|
props.Set("email", email)
|
2023-10-13 06:39:30 +01:00
|
|
|
props.Set("ui_type", uiType)
|
2022-03-29 21:05:56 +01:00
|
|
|
|
2023-06-22 12:18:21 +01:00
|
|
|
for key, value := range customProps {
|
|
|
|
props.Set(key, value)
|
|
|
|
}
|
|
|
|
|
2021-03-31 19:34:44 +01:00
|
|
|
service.enqueueMessage(segment.Track{
|
2022-03-29 21:05:56 +01:00
|
|
|
UserId: userID.String(),
|
|
|
|
Event: service.satelliteName + " " + eventName,
|
|
|
|
Properties: props,
|
2021-03-31 19:34:44 +01:00
|
|
|
})
|
|
|
|
}
|
2021-04-12 17:58:36 +01:00
|
|
|
|
2022-12-08 12:10:25 +00:00
|
|
|
// TrackErrorEvent sends an arbitrary error event associated with user ID to Segment.
|
|
|
|
// It is used for tracking occurrences of client-side errors.
|
2023-10-13 06:39:30 +01:00
|
|
|
func (service *Service) TrackErrorEvent(userID uuid.UUID, email, source, uiType string) {
|
2022-12-08 12:10:25 +00:00
|
|
|
if !service.config.Enabled {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
props := segment.NewProperties()
|
|
|
|
props.Set("email", email)
|
|
|
|
props.Set("source", source)
|
2023-10-13 06:39:30 +01:00
|
|
|
props.Set("ui_type", uiType)
|
2022-12-08 12:10:25 +00:00
|
|
|
|
|
|
|
service.enqueueMessage(segment.Track{
|
|
|
|
UserId: userID.String(),
|
|
|
|
Event: service.satelliteName + " " + eventError,
|
|
|
|
Properties: props,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2021-04-12 17:58:36 +01:00
|
|
|
// TrackLinkEvent sends an arbitrary event and link associated with user ID to Segment.
|
|
|
|
// It is used for tracking occurrences of client-side events.
|
2023-10-13 06:39:30 +01:00
|
|
|
func (service *Service) TrackLinkEvent(eventName string, userID uuid.UUID, email, link, uiType string) {
|
2021-12-09 20:52:51 +00:00
|
|
|
if !service.config.Enabled {
|
|
|
|
return
|
|
|
|
}
|
2021-04-12 17:58:36 +01:00
|
|
|
|
|
|
|
// 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)
|
2022-03-29 21:05:56 +01:00
|
|
|
props.Set("email", email)
|
2023-10-13 06:39:30 +01:00
|
|
|
props.Set("ui_type", uiType)
|
2021-04-12 17:58:36 +01:00
|
|
|
|
|
|
|
service.enqueueMessage(segment.Track{
|
|
|
|
UserId: userID.String(),
|
2022-03-24 16:59:28 +00:00
|
|
|
Event: service.satelliteName + " " + eventName,
|
2021-04-12 17:58:36 +01:00
|
|
|
Properties: props,
|
|
|
|
})
|
|
|
|
}
|
2022-04-28 19:12:42 +01:00
|
|
|
|
|
|
|
// TrackCreditCardAdded sends an "Credit Card Added" event to Segment.
|
|
|
|
func (service *Service) TrackCreditCardAdded(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 + " " + eventCreditCardAdded,
|
|
|
|
Properties: props,
|
|
|
|
})
|
|
|
|
}
|
2022-06-09 19:54:23 +01:00
|
|
|
|
|
|
|
// PageVisitEvent sends a page visit event associated with user ID to Segment.
|
|
|
|
// It is used for tracking occurrences of client-side events.
|
|
|
|
func (service *Service) PageVisitEvent(pageName string, userID uuid.UUID, email string) {
|
|
|
|
if !service.config.Enabled {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
props := segment.NewProperties()
|
|
|
|
props.Set("email", email)
|
|
|
|
props.Set("path", pageName)
|
|
|
|
props.Set("user_id", userID.String())
|
|
|
|
props.Set("satellite", service.satelliteName)
|
|
|
|
|
|
|
|
service.enqueueMessage(segment.Page{
|
|
|
|
UserId: userID.String(),
|
|
|
|
Name: "Page Requested",
|
|
|
|
Properties: props,
|
|
|
|
})
|
|
|
|
}
|
2022-06-17 20:57:10 +01:00
|
|
|
|
|
|
|
// TrackProjectLimitError sends an "Project Limit Error" event to Segment.
|
|
|
|
func (service *Service) TrackProjectLimitError(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 + " " + eventProjectLimitError,
|
|
|
|
Properties: props,
|
|
|
|
})
|
|
|
|
}
|
2022-08-08 19:17:35 +01:00
|
|
|
|
|
|
|
// 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,
|
|
|
|
})
|
|
|
|
}
|
2022-11-29 22:56:03 +00:00
|
|
|
|
|
|
|
// TrackProjectMemberAddition sends an "Project Member Added" event to Segment.
|
|
|
|
func (service *Service) TrackProjectMemberAddition(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 + " " + eventProjectMemberAdded,
|
|
|
|
Properties: props,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
// TrackProjectMemberDeletion sends an "Project Member Deleted" event to Segment.
|
|
|
|
func (service *Service) TrackProjectMemberDeletion(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 + " " + eventProjectMemberDeleted,
|
|
|
|
Properties: props,
|
|
|
|
})
|
|
|
|
}
|
2023-04-19 20:48:36 +01:00
|
|
|
|
|
|
|
// TrackExpiredCreditNeedsRemoval sends an "Expired Credit Needs Removal" event to Segment.
|
|
|
|
func (service *Service) TrackExpiredCreditNeedsRemoval(userID uuid.UUID, customerID, packagePlan string) {
|
|
|
|
if !service.config.Enabled {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
props := segment.NewProperties()
|
|
|
|
props.Set("customer ID", customerID)
|
|
|
|
props.Set("package plan", packagePlan)
|
|
|
|
|
|
|
|
service.enqueueMessage(segment.Track{
|
|
|
|
UserId: userID.String(),
|
|
|
|
Event: service.satelliteName + " " + eventExpiredCreditNeedsRemoval,
|
|
|
|
Properties: props,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
// TrackExpiredCreditRemoved sends an "Expired Credit Removed" event to Segment.
|
|
|
|
func (service *Service) TrackExpiredCreditRemoved(userID uuid.UUID, customerID, packagePlan string) {
|
|
|
|
if !service.config.Enabled {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
props := segment.NewProperties()
|
|
|
|
props.Set("customer ID", customerID)
|
|
|
|
props.Set("package plan", packagePlan)
|
|
|
|
|
|
|
|
service.enqueueMessage(segment.Track{
|
|
|
|
UserId: userID.String(),
|
|
|
|
Event: service.satelliteName + " " + eventExpiredCreditRemoved,
|
|
|
|
Properties: props,
|
|
|
|
})
|
|
|
|
}
|
2023-09-13 20:24:05 +01:00
|
|
|
|
|
|
|
// TrackInviteLinkSignup sends an "Invite Link Signup" event to Segment.
|
|
|
|
func (service *Service) TrackInviteLinkSignup(inviter, invitee string) {
|
|
|
|
if !service.config.Enabled {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
props := segment.NewProperties()
|
|
|
|
props.Set("inviter", inviter)
|
|
|
|
props.Set("invitee", invitee)
|
|
|
|
|
|
|
|
service.enqueueMessage(segment.Track{
|
|
|
|
Event: service.satelliteName + " " + eventInviteLinkSignup,
|
|
|
|
Properties: props,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
// TrackInviteLinkClicked sends an "Invite Link Clicked" event to Segment.
|
|
|
|
func (service *Service) TrackInviteLinkClicked(inviter, invitee string) {
|
|
|
|
if !service.config.Enabled {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
props := segment.NewProperties()
|
|
|
|
props.Set("inviter", inviter)
|
|
|
|
props.Set("invitee", invitee)
|
|
|
|
|
|
|
|
service.enqueueMessage(segment.Track{
|
|
|
|
Event: service.satelliteName + " " + eventInviteLinkClicked,
|
|
|
|
Properties: props,
|
|
|
|
})
|
|
|
|
}
|