package devtodev import ( "context" "fmt" "devtodev-sdk/event" ) // Reporter wraps Client with shared report/package fields and per-event helpers. // Each event helper sends exactly one report with one package. type Reporter struct { Client *Client DeviceID string UserID string PreviousDeviceID string PreviousUserID string DevtodevID string Package Package } // NewReporter creates a Reporter with a client and device ID. func NewReporter(client *Client, deviceID string) *Reporter { return &Reporter{ Client: client, DeviceID: deviceID, } } // Report sends a single event using the current reporter context. func (r *Reporter) Report(ctx context.Context, event Event) (*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") } pkg := r.Package pkg.Events = []Event{event} payload := Payload{ Reports: []Report{ { DeviceID: r.DeviceID, UserID: r.UserID, PreviousDeviceID: r.PreviousDeviceID, PreviousUserID: r.PreviousUserID, DevtodevID: r.DevtodevID, Packages: []Package{pkg}, }, }, } return r.Client.SendWithResponse(ctx, payload) } // DeviceInfo (code "di"). func (r *Reporter) DeviceInfo(ctx context.Context, timestamp int64, fields map[string]interface{}) (*Response, error) { e, err := event.DeviceInfo(timestamp, fields) if err != nil { return nil, err } return r.Report(ctx, Event(e)) } // SessionStart (code "ss"). func (r *Reporter) SessionStart(ctx context.Context, timestamp int64, level int, fields map[string]interface{}) (*Response, error) { e, err := event.SessionStart(timestamp, level, fields) if err != nil { return nil, err } return r.Report(ctx, Event(e)) } // UserEngagement (code "ue"). func (r *Reporter) UserEngagement(ctx context.Context, timestamp int64, level int, length int, fields map[string]interface{}) (*Response, error) { e, err := event.UserEngagement(timestamp, level, length, fields) if err != nil { return nil, err } return r.Report(ctx, Event(e)) } // TrackingStatus (GDPR) (code "ts"). func (r *Reporter) TrackingStatus(ctx context.Context, timestamp int64, trackingAllowed bool, fields map[string]interface{}) (*Response, error) { e, err := event.TrackingStatus(timestamp, trackingAllowed, fields) if err != nil { return nil, err } return r.Report(ctx, Event(e)) } // Alive (code "al"). func (r *Reporter) Alive(ctx context.Context, timestamp int64, fields map[string]interface{}) (*Response, error) { e, err := event.Alive(timestamp, fields) if err != nil { return nil, err } return r.Report(ctx, Event(e)) } // People (user properties) (code "pl"). func (r *Reporter) People(ctx context.Context, timestamp int64, level int, properties map[string]interface{}, fields map[string]interface{}) (*Response, error) { e, err := event.People(timestamp, level, properties, fields) if err != nil { return nil, err } return r.Report(ctx, Event(e)) } // CustomEvent (code "ce"). func (r *Reporter) CustomEvent(ctx context.Context, timestamp int64, level int, name string, parameters map[string]interface{}, fields map[string]interface{}) (*Response, error) { e, err := event.CustomEvent(timestamp, level, name, parameters, fields) if err != nil { return nil, err } return r.Report(ctx, Event(e)) } // RealPayment (code "rp"). func (r *Reporter) RealPayment(ctx context.Context, timestamp int64, level int, productID, orderID string, price float64, currencyCode string, fields map[string]interface{}) (*Response, error) { e, err := event.RealPayment(timestamp, level, productID, orderID, price, currencyCode, fields) if err != nil { return nil, err } return r.Report(ctx, Event(e)) } // Onboarding (tutorial) (code "tr"). func (r *Reporter) Onboarding(ctx context.Context, timestamp int64, level int, step int, fields map[string]interface{}) (*Response, error) { e, err := event.Onboarding(timestamp, level, step, fields) if err != nil { return nil, err } return r.Report(ctx, Event(e)) } // VirtualCurrencyPayment (code "vp"). func (r *Reporter) VirtualCurrencyPayment(ctx context.Context, timestamp int64, level int, purchaseAmount int, purchasePrice map[string]float64, purchaseType, purchaseID string, fields map[string]interface{}) (*Response, error) { e, err := event.VirtualCurrencyPayment(timestamp, level, purchaseAmount, purchasePrice, purchaseType, purchaseID, fields) if err != nil { return nil, err } return r.Report(ctx, Event(e)) } // CurrencyAccrual (code "ca"). At least one of bought or earned must be provided. func (r *Reporter) CurrencyAccrual(ctx context.Context, timestamp int64, level int, bought, earned map[string]map[string]float64, fields map[string]interface{}) (*Response, error) { e, err := event.CurrencyAccrual(timestamp, level, bought, earned, fields) if err != nil { return nil, err } return r.Report(ctx, Event(e)) } // CurrentBalance (code "cb"). func (r *Reporter) CurrentBalance(ctx context.Context, timestamp int64, level int, balance map[string]float64, fields map[string]interface{}) (*Response, error) { e, err := event.CurrentBalance(timestamp, level, balance, fields) if err != nil { return nil, err } return r.Report(ctx, Event(e)) } // LevelUp (code "lu"). func (r *Reporter) LevelUp(ctx context.Context, timestamp int64, level int, balance, spent, earned, bought map[string]float64, fields map[string]interface{}) (*Response, error) { e, err := event.LevelUp(timestamp, level, balance, spent, earned, bought, fields) if err != nil { return nil, err } return r.Report(ctx, Event(e)) } // ProgressionEvent (code "pe"). "parameters" is required and should include success and duration. func (r *Reporter) ProgressionEvent(ctx context.Context, timestamp int64, level int, name string, parameters map[string]interface{}, fields map[string]interface{}) (*Response, error) { e, err := event.ProgressionEvent(timestamp, level, name, parameters, fields) if err != nil { return nil, err } return r.Report(ctx, Event(e)) } // Referral (code "rf"). func (r *Reporter) Referral(ctx context.Context, timestamp int64, fields map[string]interface{}) (*Response, error) { e, err := event.Referral(timestamp, fields) if err != nil { return nil, err } return r.Report(ctx, Event(e)) } // AdImpression (code "adrv"). func (r *Reporter) AdImpression(ctx context.Context, timestamp int64, adNetwork string, revenue float64, fields map[string]interface{}) (*Response, error) { e, err := event.AdImpression(timestamp, adNetwork, revenue, fields) if err != nil { return nil, err } return r.Report(ctx, Event(e)) } // SocialConnect (code "sc"). func (r *Reporter) SocialConnect(ctx context.Context, timestamp int64, level int, socialNetwork string, fields map[string]interface{}) (*Response, error) { e, err := event.SocialConnect(timestamp, level, socialNetwork, fields) if err != nil { return nil, err } return r.Report(ctx, Event(e)) } // SocialPost (code "sp"). func (r *Reporter) SocialPost(ctx context.Context, timestamp int64, level int, socialNetwork, postReason string, fields map[string]interface{}) (*Response, error) { e, err := event.SocialPost(timestamp, level, socialNetwork, postReason, fields) if err != nil { return nil, err } return r.Report(ctx, Event(e)) }