github.com/ActiveState/cli@v0.0.0-20240508170324-6801f60cd051/internal/analytics/client/sync/reporters/ga-state.go (about) 1 package reporters 2 3 import ( 4 "strconv" 5 6 anaConsts "github.com/ActiveState/cli/internal/analytics/constants" 7 "github.com/ActiveState/cli/internal/analytics/dimensions" 8 "github.com/ActiveState/cli/internal/condition" 9 "github.com/ActiveState/cli/internal/constants" 10 "github.com/ActiveState/cli/internal/errs" 11 "github.com/ActiveState/cli/internal/logging" 12 "github.com/ActiveState/cli/internal/rtutils/ptr" 13 ga "github.com/ActiveState/go-ogle-analytics" 14 ) 15 16 type GaCLIReporter struct { 17 ga *ga.Client 18 omit map[string]struct{} 19 } 20 21 func NewGaCLIReporter(clientID string) (*GaCLIReporter, error) { 22 r := &GaCLIReporter{ 23 omit: make(map[string]struct{}), 24 } 25 26 trackingID := constants.AnalyticsTrackingID 27 28 client, err := ga.NewClient(trackingID) 29 if err != nil { 30 return nil, errs.Wrap(err, "Cannot initialize google analytics cli client") 31 } 32 33 client.ClientID(clientID) 34 r.ga = client 35 36 return r, nil 37 } 38 39 func (r *GaCLIReporter) ID() string { 40 return "GaCLIReporter" 41 } 42 43 func (r *GaCLIReporter) AddOmitCategory(category string) { 44 r.omit[category] = struct{}{} 45 } 46 47 func (r *GaCLIReporter) Event(category, action, source, label string, d *dimensions.Values) error { 48 if _, ok := r.omit[category]; ok { 49 logging.Debug("Not sending event with category: %s to Google Analytics", category) 50 return nil 51 } 52 53 r.ga.CustomDimensionMap(legacyDimensionMap(d)) 54 55 if category == anaConsts.CatRunCmd { 56 if err := r.ga.Send(ga.NewPageview()); err != nil { 57 return errs.Wrap(err, "Could not send GA Pageview") 58 } 59 } 60 event := ga.NewEvent(category, action) 61 if label != "" { 62 event.Label(label) 63 } 64 err := r.ga.Send(event) 65 if err != nil { 66 if condition.IsNetworkingError(err) { 67 logging.Debug("Cannot send Google Analytics event as the hostname appears to be blocked. Error received: %s", err.Error()) 68 return nil 69 } 70 return errs.Wrap(err, "Could not send GA Event") 71 } 72 73 return nil 74 } 75 76 func legacyDimensionMap(d *dimensions.Values) map[string]string { 77 return map[string]string{ 78 // Commented out idx 1 so it's clear why we start with 2. We used to log the hostname while dogfooding internally. 79 // "1": "hostname (deprecated)" 80 "2": ptr.From(d.Version, ""), 81 "3": ptr.From(d.ChannelName, ""), 82 "4": ptr.From(d.UserID, ""), 83 "5": ptr.From(d.OutputType, ""), 84 "6": ptr.From(d.OSName, ""), 85 "7": ptr.From(d.OSVersion, ""), 86 "8": ptr.From(d.InstallSource, ""), 87 // "9": "machineID (deprecated in favor of uniqID)" 88 "10": ptr.From(d.ProjectNameSpace, ""), 89 "11": ptr.From(d.SessionToken, ""), 90 "12": ptr.From(d.UniqID, ""), 91 "13": ptr.From(d.UpdateTag, ""), 92 "14": ptr.From(d.ProjectID, ""), 93 "16": ptr.From(d.Trigger, ""), 94 "17": ptr.From(d.InstanceID, ""), 95 "18": ptr.From(d.Headless, ""), 96 "19": ptr.From(d.CommitID, ""), 97 "20": ptr.From(d.Command, ""), 98 "21": strconv.Itoa(ptr.From(d.Sequence, -1)), 99 "22": strconv.FormatBool(ptr.From(d.CI, false)), 100 "23": strconv.FormatBool(ptr.From(d.Interactive, false)), 101 "24": ptr.From(d.TargetVersion, ""), 102 "25": ptr.From(d.Error, ""), 103 "26": ptr.From(d.Message, ""), 104 "27": strconv.FormatBool(ptr.From(d.ActiveStateCI, false)), 105 } 106 }