735 lines
16 KiB
Go
735 lines
16 KiB
Go
// ampli.go
|
|
//
|
|
// Ampli - A strong typed wrapper for your Analytics
|
|
//
|
|
// This file is generated by Amplitude.
|
|
// To update run 'ampli pull backend'
|
|
//
|
|
// Required dependencies: github.com/amplitude/analytics-go@latest
|
|
// Tracking Plan Version: 2
|
|
// Build: 1.0.0
|
|
// Runtime: go-ampli
|
|
//
|
|
// View Tracking Plan: https://data.eu.amplitude.com/profee/Profee%20Tips/events/main/latest
|
|
//
|
|
// Full Setup Instructions: https://data.eu.amplitude.com/profee/Profee%20Tips/implementation/main/latest/getting-started/backend
|
|
//
|
|
|
|
package ampli
|
|
|
|
import (
|
|
"log"
|
|
"sync"
|
|
|
|
"github.com/amplitude/analytics-go/amplitude"
|
|
)
|
|
|
|
type (
|
|
EventOptions = amplitude.EventOptions
|
|
ExecuteResult = amplitude.ExecuteResult
|
|
)
|
|
|
|
const (
|
|
IdentifyEventType = amplitude.IdentifyEventType
|
|
GroupIdentifyEventType = amplitude.GroupIdentifyEventType
|
|
|
|
ServerZoneUS = amplitude.ServerZoneUS
|
|
ServerZoneEU = amplitude.ServerZoneEU
|
|
)
|
|
|
|
var (
|
|
NewClientConfig = amplitude.NewConfig
|
|
NewClient = amplitude.NewClient
|
|
)
|
|
|
|
var Instance = Ampli{}
|
|
|
|
type Environment string
|
|
|
|
const (
|
|
EnvironmentProfeetips Environment = `profeetips`
|
|
)
|
|
|
|
var APIKey = map[Environment]string{
|
|
EnvironmentProfeetips: `c4e543cf70e8c83b85eb56e9a1d9b4b3`,
|
|
}
|
|
|
|
// LoadClientOptions is Client options setting to initialize Ampli client.
|
|
//
|
|
// Params:
|
|
// - APIKey: the API key of Amplitude project
|
|
// - Instance: the core SDK instance used by Ampli client
|
|
// - Configuration: the core SDK client configuration instance
|
|
type LoadClientOptions struct {
|
|
APIKey string
|
|
Instance amplitude.Client
|
|
Configuration amplitude.Config
|
|
}
|
|
|
|
// LoadOptions is options setting to initialize Ampli client.
|
|
//
|
|
// Params:
|
|
// - Environment: the environment of Amplitude Data project
|
|
// - Disabled: the flag of disabled Ampli client
|
|
// - Client: the LoadClientOptions struct
|
|
type LoadOptions struct {
|
|
Environment Environment
|
|
Disabled bool
|
|
Client LoadClientOptions
|
|
}
|
|
|
|
type baseEvent struct {
|
|
eventType string
|
|
properties map[string]any
|
|
}
|
|
|
|
type Event interface {
|
|
ToAmplitudeEvent() amplitude.Event
|
|
}
|
|
|
|
func newBaseEvent(eventType string, properties map[string]any) baseEvent {
|
|
return baseEvent{
|
|
eventType: eventType,
|
|
properties: properties,
|
|
}
|
|
}
|
|
|
|
func (event baseEvent) ToAmplitudeEvent() amplitude.Event {
|
|
return amplitude.Event{
|
|
EventType: event.eventType,
|
|
EventProperties: event.properties,
|
|
}
|
|
}
|
|
|
|
var EmailOpened = struct {
|
|
Builder func() interface {
|
|
EmailType(emailType string) EmailOpenedBuilder
|
|
}
|
|
}{
|
|
Builder: func() interface {
|
|
EmailType(emailType string) EmailOpenedBuilder
|
|
} {
|
|
return &emailOpenedBuilder{
|
|
properties: map[string]any{},
|
|
}
|
|
},
|
|
}
|
|
|
|
type EmailOpenedEvent interface {
|
|
Event
|
|
emailOpened()
|
|
}
|
|
|
|
type emailOpenedEvent struct {
|
|
baseEvent
|
|
}
|
|
|
|
func (e emailOpenedEvent) emailOpened() {
|
|
}
|
|
|
|
type EmailOpenedBuilder interface {
|
|
Build() EmailOpenedEvent
|
|
}
|
|
|
|
type emailOpenedBuilder struct {
|
|
properties map[string]any
|
|
}
|
|
|
|
func (b *emailOpenedBuilder) EmailType(emailType string) EmailOpenedBuilder {
|
|
b.properties[`emailType`] = emailType
|
|
|
|
return b
|
|
}
|
|
|
|
func (b *emailOpenedBuilder) Build() EmailOpenedEvent {
|
|
return &emailOpenedEvent{
|
|
newBaseEvent(`emailOpened`, b.properties),
|
|
}
|
|
}
|
|
|
|
var EmailSent = struct {
|
|
Builder func() interface {
|
|
Domain(domain string) interface {
|
|
EmailType(emailType string) EmailSentBuilder
|
|
}
|
|
}
|
|
}{
|
|
Builder: func() interface {
|
|
Domain(domain string) interface {
|
|
EmailType(emailType string) EmailSentBuilder
|
|
}
|
|
} {
|
|
return &emailSentBuilder{
|
|
properties: map[string]any{},
|
|
}
|
|
},
|
|
}
|
|
|
|
type EmailSentEvent interface {
|
|
Event
|
|
emailSent()
|
|
}
|
|
|
|
type emailSentEvent struct {
|
|
baseEvent
|
|
}
|
|
|
|
func (e emailSentEvent) emailSent() {
|
|
}
|
|
|
|
type EmailSentBuilder interface {
|
|
Build() EmailSentEvent
|
|
}
|
|
|
|
type emailSentBuilder struct {
|
|
properties map[string]any
|
|
}
|
|
|
|
func (b *emailSentBuilder) Domain(domain string) interface {
|
|
EmailType(emailType string) EmailSentBuilder
|
|
} {
|
|
b.properties[`domain`] = domain
|
|
|
|
return b
|
|
}
|
|
|
|
func (b *emailSentBuilder) EmailType(emailType string) EmailSentBuilder {
|
|
b.properties[`emailType`] = emailType
|
|
|
|
return b
|
|
}
|
|
|
|
func (b *emailSentBuilder) Build() EmailSentEvent {
|
|
return &emailSentEvent{
|
|
newBaseEvent(`emailSent`, b.properties),
|
|
}
|
|
}
|
|
|
|
var PaymentFailed = struct {
|
|
Builder func() interface {
|
|
Amount(amount float64) interface {
|
|
Domain(domain string) interface {
|
|
Fee(fee float64) interface {
|
|
FeeCoveredBy(feeCoveredBy string) interface {
|
|
Product(product string) interface {
|
|
ProductQty(productQty int) PaymentFailedBuilder
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}{
|
|
Builder: func() interface {
|
|
Amount(amount float64) interface {
|
|
Domain(domain string) interface {
|
|
Fee(fee float64) interface {
|
|
FeeCoveredBy(feeCoveredBy string) interface {
|
|
Product(product string) interface {
|
|
ProductQty(productQty int) PaymentFailedBuilder
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} {
|
|
return &paymentFailedBuilder{
|
|
properties: map[string]any{},
|
|
}
|
|
},
|
|
}
|
|
|
|
type PaymentFailedEvent interface {
|
|
Event
|
|
paymentFailed()
|
|
}
|
|
|
|
type paymentFailedEvent struct {
|
|
baseEvent
|
|
}
|
|
|
|
func (e paymentFailedEvent) paymentFailed() {
|
|
}
|
|
|
|
type PaymentFailedBuilder interface {
|
|
Build() PaymentFailedEvent
|
|
Comment(comment string) PaymentFailedBuilder
|
|
Source(source string) PaymentFailedBuilder
|
|
}
|
|
|
|
type paymentFailedBuilder struct {
|
|
properties map[string]any
|
|
}
|
|
|
|
func (b *paymentFailedBuilder) Amount(amount float64) interface {
|
|
Domain(domain string) interface {
|
|
Fee(fee float64) interface {
|
|
FeeCoveredBy(feeCoveredBy string) interface {
|
|
Product(product string) interface {
|
|
ProductQty(productQty int) PaymentFailedBuilder
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} {
|
|
b.properties[`amount`] = amount
|
|
|
|
return b
|
|
}
|
|
|
|
func (b *paymentFailedBuilder) Domain(domain string) interface {
|
|
Fee(fee float64) interface {
|
|
FeeCoveredBy(feeCoveredBy string) interface {
|
|
Product(product string) interface {
|
|
ProductQty(productQty int) PaymentFailedBuilder
|
|
}
|
|
}
|
|
}
|
|
} {
|
|
b.properties[`domain`] = domain
|
|
|
|
return b
|
|
}
|
|
|
|
func (b *paymentFailedBuilder) Fee(fee float64) interface {
|
|
FeeCoveredBy(feeCoveredBy string) interface {
|
|
Product(product string) interface {
|
|
ProductQty(productQty int) PaymentFailedBuilder
|
|
}
|
|
}
|
|
} {
|
|
b.properties[`fee`] = fee
|
|
|
|
return b
|
|
}
|
|
|
|
func (b *paymentFailedBuilder) FeeCoveredBy(feeCoveredBy string) interface {
|
|
Product(product string) interface {
|
|
ProductQty(productQty int) PaymentFailedBuilder
|
|
}
|
|
} {
|
|
b.properties[`feeCoveredBy`] = feeCoveredBy
|
|
|
|
return b
|
|
}
|
|
|
|
func (b *paymentFailedBuilder) Product(product string) interface {
|
|
ProductQty(productQty int) PaymentFailedBuilder
|
|
} {
|
|
b.properties[`product`] = product
|
|
|
|
return b
|
|
}
|
|
|
|
func (b *paymentFailedBuilder) ProductQty(productQty int) PaymentFailedBuilder {
|
|
b.properties[`product_qty`] = productQty
|
|
|
|
return b
|
|
}
|
|
|
|
func (b *paymentFailedBuilder) Comment(comment string) PaymentFailedBuilder {
|
|
b.properties[`comment`] = comment
|
|
|
|
return b
|
|
}
|
|
|
|
func (b *paymentFailedBuilder) Source(source string) PaymentFailedBuilder {
|
|
b.properties[`source`] = source
|
|
|
|
return b
|
|
}
|
|
|
|
func (b *paymentFailedBuilder) Build() PaymentFailedEvent {
|
|
return &paymentFailedEvent{
|
|
newBaseEvent(`paymentFailed`, b.properties),
|
|
}
|
|
}
|
|
|
|
var PaymentSuccess = struct {
|
|
Builder func() interface {
|
|
Price(price float64) interface {
|
|
ProductId(productId string) interface {
|
|
Revenue(revenue float64) interface {
|
|
RevenueType(revenueType string) interface {
|
|
Amount(amount float64) interface {
|
|
Domain(domain string) interface {
|
|
Fee(fee float64) interface {
|
|
FeeCoveredBy(feeCoveredBy string) interface {
|
|
Product(product string) interface {
|
|
ProductQty(productQty int) PaymentSuccessBuilder
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}{
|
|
Builder: func() interface {
|
|
Price(price float64) interface {
|
|
ProductId(productId string) interface {
|
|
Revenue(revenue float64) interface {
|
|
RevenueType(revenueType string) interface {
|
|
Amount(amount float64) interface {
|
|
Domain(domain string) interface {
|
|
Fee(fee float64) interface {
|
|
FeeCoveredBy(feeCoveredBy string) interface {
|
|
Product(product string) interface {
|
|
ProductQty(productQty int) PaymentSuccessBuilder
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} {
|
|
return &paymentSuccessBuilder{
|
|
properties: map[string]any{},
|
|
}
|
|
},
|
|
}
|
|
|
|
type PaymentSuccessEvent interface {
|
|
Event
|
|
paymentSuccess()
|
|
}
|
|
|
|
type paymentSuccessEvent struct {
|
|
baseEvent
|
|
}
|
|
|
|
func (e paymentSuccessEvent) paymentSuccess() {
|
|
}
|
|
|
|
type PaymentSuccessBuilder interface {
|
|
Build() PaymentSuccessEvent
|
|
Quantity(quantity int) PaymentSuccessBuilder
|
|
Comment(comment string) PaymentSuccessBuilder
|
|
}
|
|
|
|
type paymentSuccessBuilder struct {
|
|
properties map[string]any
|
|
}
|
|
|
|
func (b *paymentSuccessBuilder) Price(price float64) interface {
|
|
ProductId(productId string) interface {
|
|
Revenue(revenue float64) interface {
|
|
RevenueType(revenueType string) interface {
|
|
Amount(amount float64) interface {
|
|
Domain(domain string) interface {
|
|
Fee(fee float64) interface {
|
|
FeeCoveredBy(feeCoveredBy string) interface {
|
|
Product(product string) interface {
|
|
ProductQty(productQty int) PaymentSuccessBuilder
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} {
|
|
b.properties[`$price`] = price
|
|
|
|
return b
|
|
}
|
|
|
|
func (b *paymentSuccessBuilder) ProductId(productId string) interface {
|
|
Revenue(revenue float64) interface {
|
|
RevenueType(revenueType string) interface {
|
|
Amount(amount float64) interface {
|
|
Domain(domain string) interface {
|
|
Fee(fee float64) interface {
|
|
FeeCoveredBy(feeCoveredBy string) interface {
|
|
Product(product string) interface {
|
|
ProductQty(productQty int) PaymentSuccessBuilder
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} {
|
|
b.properties[`$productId`] = productId
|
|
|
|
return b
|
|
}
|
|
|
|
func (b *paymentSuccessBuilder) Revenue(revenue float64) interface {
|
|
RevenueType(revenueType string) interface {
|
|
Amount(amount float64) interface {
|
|
Domain(domain string) interface {
|
|
Fee(fee float64) interface {
|
|
FeeCoveredBy(feeCoveredBy string) interface {
|
|
Product(product string) interface {
|
|
ProductQty(productQty int) PaymentSuccessBuilder
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} {
|
|
b.properties[`$revenue`] = revenue
|
|
|
|
return b
|
|
}
|
|
|
|
func (b *paymentSuccessBuilder) RevenueType(revenueType string) interface {
|
|
Amount(amount float64) interface {
|
|
Domain(domain string) interface {
|
|
Fee(fee float64) interface {
|
|
FeeCoveredBy(feeCoveredBy string) interface {
|
|
Product(product string) interface {
|
|
ProductQty(productQty int) PaymentSuccessBuilder
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} {
|
|
b.properties[`$revenueType`] = revenueType
|
|
|
|
return b
|
|
}
|
|
|
|
func (b *paymentSuccessBuilder) Amount(amount float64) interface {
|
|
Domain(domain string) interface {
|
|
Fee(fee float64) interface {
|
|
FeeCoveredBy(feeCoveredBy string) interface {
|
|
Product(product string) interface {
|
|
ProductQty(productQty int) PaymentSuccessBuilder
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} {
|
|
b.properties[`amount`] = amount
|
|
|
|
return b
|
|
}
|
|
|
|
func (b *paymentSuccessBuilder) Domain(domain string) interface {
|
|
Fee(fee float64) interface {
|
|
FeeCoveredBy(feeCoveredBy string) interface {
|
|
Product(product string) interface {
|
|
ProductQty(productQty int) PaymentSuccessBuilder
|
|
}
|
|
}
|
|
}
|
|
} {
|
|
b.properties[`domain`] = domain
|
|
|
|
return b
|
|
}
|
|
|
|
func (b *paymentSuccessBuilder) Fee(fee float64) interface {
|
|
FeeCoveredBy(feeCoveredBy string) interface {
|
|
Product(product string) interface {
|
|
ProductQty(productQty int) PaymentSuccessBuilder
|
|
}
|
|
}
|
|
} {
|
|
b.properties[`fee`] = fee
|
|
|
|
return b
|
|
}
|
|
|
|
func (b *paymentSuccessBuilder) FeeCoveredBy(feeCoveredBy string) interface {
|
|
Product(product string) interface {
|
|
ProductQty(productQty int) PaymentSuccessBuilder
|
|
}
|
|
} {
|
|
b.properties[`feeCoveredBy`] = feeCoveredBy
|
|
|
|
return b
|
|
}
|
|
|
|
func (b *paymentSuccessBuilder) Product(product string) interface {
|
|
ProductQty(productQty int) PaymentSuccessBuilder
|
|
} {
|
|
b.properties[`product`] = product
|
|
|
|
return b
|
|
}
|
|
|
|
func (b *paymentSuccessBuilder) ProductQty(productQty int) PaymentSuccessBuilder {
|
|
b.properties[`product_qty`] = productQty
|
|
|
|
return b
|
|
}
|
|
|
|
func (b *paymentSuccessBuilder) Quantity(quantity int) PaymentSuccessBuilder {
|
|
b.properties[`$quantity`] = quantity
|
|
|
|
return b
|
|
}
|
|
|
|
func (b *paymentSuccessBuilder) Comment(comment string) PaymentSuccessBuilder {
|
|
b.properties[`comment`] = comment
|
|
|
|
return b
|
|
}
|
|
|
|
func (b *paymentSuccessBuilder) Build() PaymentSuccessEvent {
|
|
return &paymentSuccessEvent{
|
|
newBaseEvent(`paymentSuccess`, b.properties),
|
|
}
|
|
}
|
|
|
|
type Ampli struct {
|
|
Disabled bool
|
|
Client amplitude.Client
|
|
mutex sync.RWMutex
|
|
}
|
|
|
|
// Load initializes the Ampli wrapper.
|
|
// Call once when your application starts.
|
|
func (a *Ampli) Load(options LoadOptions) {
|
|
if a.Client != nil {
|
|
log.Print("Warn: Ampli is already initialized. Ampli.Load() should be called once at application start up.")
|
|
|
|
return
|
|
}
|
|
|
|
var apiKey string
|
|
switch {
|
|
case options.Client.APIKey != "":
|
|
apiKey = options.Client.APIKey
|
|
case options.Environment != "":
|
|
apiKey = APIKey[options.Environment]
|
|
default:
|
|
apiKey = options.Client.Configuration.APIKey
|
|
}
|
|
|
|
if apiKey == "" && options.Client.Instance == nil {
|
|
log.Print("Error: Ampli.Load() requires option.Environment, " +
|
|
"and apiKey from either options.Instance.APIKey or APIKey[options.Environment], " +
|
|
"or options.Instance.Instance")
|
|
}
|
|
|
|
clientConfig := options.Client.Configuration
|
|
|
|
if clientConfig.Plan == nil {
|
|
clientConfig.Plan = &litude.Plan{
|
|
Branch: `main`,
|
|
Source: `backend`,
|
|
Version: `2`,
|
|
VersionID: `4fa6851a-4ff0-42f1-b440-8b39f07870e4`,
|
|
}
|
|
}
|
|
|
|
if clientConfig.IngestionMetadata == nil {
|
|
clientConfig.IngestionMetadata = &litude.IngestionMetadata{
|
|
SourceName: `go-go-ampli`,
|
|
SourceVersion: `2.0.0`,
|
|
}
|
|
}
|
|
|
|
if clientConfig.ServerZone == "" {
|
|
clientConfig.ServerZone = ServerZoneEU
|
|
}
|
|
|
|
if options.Client.Instance != nil {
|
|
a.Client = options.Client.Instance
|
|
} else {
|
|
clientConfig.APIKey = apiKey
|
|
a.Client = amplitude.NewClient(clientConfig)
|
|
}
|
|
|
|
a.mutex.Lock()
|
|
a.Disabled = options.Disabled
|
|
a.mutex.Unlock()
|
|
}
|
|
|
|
// InitializedAndEnabled checks if Ampli is initialized and enabled.
|
|
func (a *Ampli) InitializedAndEnabled() bool {
|
|
if a.Client == nil {
|
|
log.Print("Error: Ampli is not yet initialized. Have you called Ampli.Load() on app start?")
|
|
|
|
return false
|
|
}
|
|
|
|
a.mutex.RLock()
|
|
defer a.mutex.RUnlock()
|
|
|
|
return !a.Disabled
|
|
}
|
|
|
|
func (a *Ampli) setUserID(userID string, eventOptions *EventOptions) {
|
|
if userID != "" {
|
|
eventOptions.UserID = userID
|
|
}
|
|
}
|
|
|
|
// Track tracks an event.
|
|
func (a *Ampli) Track(userID string, event Event, eventOptions ...EventOptions) {
|
|
if !a.InitializedAndEnabled() {
|
|
return
|
|
}
|
|
|
|
var options EventOptions
|
|
if len(eventOptions) > 0 {
|
|
options = eventOptions[0]
|
|
}
|
|
|
|
a.setUserID(userID, &options)
|
|
|
|
baseEvent := event.ToAmplitudeEvent()
|
|
baseEvent.EventOptions = options
|
|
|
|
a.Client.Track(baseEvent)
|
|
}
|
|
|
|
// Identify identifies a user and set user properties.
|
|
func (a *Ampli) Identify(userID string, eventOptions ...EventOptions) {
|
|
identify := newBaseEvent(IdentifyEventType, nil)
|
|
a.Track(userID, identify, eventOptions...)
|
|
}
|
|
|
|
// Flush flushes events waiting in buffer.
|
|
func (a *Ampli) Flush() {
|
|
if !a.InitializedAndEnabled() {
|
|
return
|
|
}
|
|
|
|
a.Client.Flush()
|
|
}
|
|
|
|
// Shutdown disables and shutdowns Ampli Instance.
|
|
func (a *Ampli) Shutdown() {
|
|
if !a.InitializedAndEnabled() {
|
|
return
|
|
}
|
|
|
|
a.mutex.Lock()
|
|
a.Disabled = true
|
|
a.mutex.Unlock()
|
|
|
|
a.Client.Shutdown()
|
|
}
|
|
|
|
func (a *Ampli) EmailOpened(userID string, event EmailOpenedEvent, eventOptions ...EventOptions) {
|
|
a.Track(userID, event, eventOptions...)
|
|
}
|
|
|
|
func (a *Ampli) EmailSent(userID string, event EmailSentEvent, eventOptions ...EventOptions) {
|
|
a.Track(userID, event, eventOptions...)
|
|
}
|
|
|
|
func (a *Ampli) PaymentFailed(userID string, event PaymentFailedEvent, eventOptions ...EventOptions) {
|
|
a.Track(userID, event, eventOptions...)
|
|
}
|
|
|
|
func (a *Ampli) PaymentSuccess(userID string, event PaymentSuccessEvent, eventOptions ...EventOptions) {
|
|
a.Track(userID, event, eventOptions...)
|
|
}
|