package devtodev import ( "context" "fmt" "devtodev-sdk/event" ) // Reporter wraps Client with report-level identity fields. type Reporter struct { Client *Client DeviceID string UserID string PreviousDeviceID string PreviousUserID string DevtodevID string } // NewReporter creates a Reporter with report-level fields. func NewReporter(client *Client, deviceID string) *Reporter { return &Reporter{ Client: client, DeviceID: deviceID, } } // NewPackage creates a package bound to the reporter. func (r *Reporter) NewPackage() *DevtodevPackage { return &DevtodevPackage{ reporter: r, events: make([]Event, 0), } } // Report sends one request with one report and one or more packages. func (r *Reporter) Report(ctx context.Context, packages ...*DevtodevPackage) (*Response, error) { if r == nil { return nil, fmt.Errorf("reporter is nil") } if r.Client == nil { return nil, fmt.Errorf("client is nil") } if r.DeviceID == "" { return nil, fmt.Errorf("deviceId is required") } if len(packages) == 0 { return nil, fmt.Errorf("packages is required") } rawPackages := make([]DevtodevPackage, 0, len(packages)) for _, pkg := range packages { if pkg == nil { return nil, fmt.Errorf("package is nil") } pkg.reporter = r rawPackages = append(rawPackages, *pkg) } payload := Payload{ Reports: []Report{ { DeviceID: r.DeviceID, UserID: r.UserID, PreviousDeviceID: r.PreviousDeviceID, PreviousUserID: r.PreviousUserID, DevtodevID: r.DevtodevID, Packages: rawPackages, }, }, } return r.Client.SendWithResponse(ctx, payload) } // Report sends the package using the reporter bound by NewPackage. func (p *DevtodevPackage) Report(ctx context.Context) (*Response, error) { if p == nil { return nil, fmt.Errorf("package is nil") } if p.reporter == nil { return nil, fmt.Errorf("package reporter is nil") } return p.reporter.Report(ctx, p) } func wrapEvent(raw map[string]interface{}, err error) Event { if err != nil { return builtEvent{err: err} } return builtEvent{payload: raw} } func NewDeviceInfoEvent(timestamp int64, fields map[string]interface{}) Event { return wrapEvent(event.DeviceInfo(timestamp, fields)) } func NewSessionStartEvent(timestamp int64, level int, fields map[string]interface{}) Event { return wrapEvent(event.SessionStart(timestamp, level, fields)) } func NewUserEngagementEvent(timestamp int64, level int, length int, fields map[string]interface{}) Event { return wrapEvent(event.UserEngagement(timestamp, level, length, fields)) } func NewTrackingStatusEvent(timestamp int64, trackingAllowed bool, fields map[string]interface{}) Event { return wrapEvent(event.TrackingStatus(timestamp, trackingAllowed, fields)) } func NewAliveEvent(timestamp int64, fields map[string]interface{}) Event { return wrapEvent(event.Alive(timestamp, fields)) } func NewPeopleEvent(timestamp int64, level int, properties map[string]interface{}, fields map[string]interface{}) Event { return wrapEvent(event.People(timestamp, level, properties, fields)) } func NewCustomEvent(timestamp int64, level int, name string, parameters map[string]interface{}, fields map[string]interface{}) Event { return wrapEvent(event.CustomEvent(timestamp, level, name, parameters, fields)) } func NewRealPaymentEvent(timestamp int64, level int, productID, orderID string, price float64, currencyCode string, fields map[string]interface{}) Event { return wrapEvent(event.RealPayment(timestamp, level, productID, orderID, price, currencyCode, fields)) } func NewOnboardingEvent(timestamp int64, level int, step int, fields map[string]interface{}) Event { return wrapEvent(event.Onboarding(timestamp, level, step, fields)) } func NewVirtualCurrencyPaymentEvent(timestamp int64, level int, purchaseAmount int, purchasePrice map[string]float64, purchaseType, purchaseID string, fields map[string]interface{}) Event { return wrapEvent(event.VirtualCurrencyPayment(timestamp, level, purchaseAmount, purchasePrice, purchaseType, purchaseID, fields)) } func NewCurrencyAccrualEvent(timestamp int64, level int, bought, earned map[string]map[string]float64, fields map[string]interface{}) Event { return wrapEvent(event.CurrencyAccrual(timestamp, level, bought, earned, fields)) } func NewCurrentBalanceEvent(timestamp int64, level int, balance map[string]float64, fields map[string]interface{}) Event { return wrapEvent(event.CurrentBalance(timestamp, level, balance, fields)) } func NewLevelUpEvent(timestamp int64, level int, balance, spent, earned, bought map[string]float64, fields map[string]interface{}) Event { return wrapEvent(event.LevelUp(timestamp, level, balance, spent, earned, bought, fields)) } func NewProgressionEvent(timestamp int64, level int, name string, parameters map[string]interface{}, fields map[string]interface{}) Event { return wrapEvent(event.ProgressionEvent(timestamp, level, name, parameters, fields)) } func NewReferralEvent(timestamp int64, fields map[string]interface{}) Event { return wrapEvent(event.Referral(timestamp, fields)) } func NewAdImpressionEvent(timestamp int64, adNetwork string, revenue float64, fields map[string]interface{}) Event { return wrapEvent(event.AdImpression(timestamp, adNetwork, revenue, fields)) } func NewSocialConnectEvent(timestamp int64, level int, socialNetwork string, fields map[string]interface{}) Event { return wrapEvent(event.SocialConnect(timestamp, level, socialNetwork, fields)) } func NewSocialPostEvent(timestamp int64, level int, socialNetwork, postReason string, fields map[string]interface{}) Event { return wrapEvent(event.SocialPost(timestamp, level, socialNetwork, postReason, fields)) }