Live video on the AT Protocol
at natb/analytics 153 lines 4.1 kB view raw
1package analytics 2 3import ( 4 pb "stream.place/streamplace/pkg/analytics/pb" 5) 6 7// Event represents an analytics event to be ingested 8type Event struct { 9 EventID string 10 EventType string 11 DeviceID string 12 DID *string 13 SessionID string 14 TimestampMs int64 15 StreamerDID string 16 StreamID *string 17 PropertiesJSON string 18 SchemaVersion uint16 19 ClientVersion string 20 Platform string 21} 22 23// RealtimeStatsRequest requests real-time statistics 24type RealtimeStatsRequest struct { 25 StreamerDid *string 26 WindowMinutes uint32 27} 28 29// RealtimeStatsResponse contains real-time statistics 30type RealtimeStatsResponse struct { 31 Streamers []StreamerRealtimeStats `json:"streamers"` 32} 33 34// StreamerRealtimeStats contains real-time stats for a single streamer 35type StreamerRealtimeStats struct { 36 StreamerDid string `json:"streamerDid"` 37 CurrentViewers uint64 `json:"currentViewers"` 38 TotalWatchTimeMs uint64 `json:"totalWatchTimeMs"` 39} 40 41// StreamerStatsRequest requests stats for a specific streamer 42type StreamerStatsRequest struct { 43 StreamerDid string 44 StartTimeMs *int64 45 EndTimeMs *int64 46} 47 48// StreamerStatsResponse contains aggregated stats for a streamer 49type StreamerStatsResponse struct { 50 StreamerDid string `json:"streamerDid"` 51 TotalViews uint64 `json:"totalViews"` 52 TotalWatchTimeMs uint64 `json:"totalWatchTimeMs"` 53 UniqueViewers uint64 `json:"uniqueViewers"` 54 DailyStats []DailyStats `json:"dailyStats"` 55} 56 57// DailyStats contains stats for a single day 58type DailyStats struct { 59 Date string `json:"date"` 60 Views uint64 `json:"views"` 61 WatchTimeMs uint64 `json:"watchTimeMs"` 62 UniqueViewers uint64 `json:"uniqueViewers"` 63} 64 65// ViewerHistoryRequest requests viewing history for a user 66type ViewerHistoryRequest struct { 67 Did string 68 StartTimeMs *int64 69 EndTimeMs *int64 70 Limit uint32 71} 72 73// ViewerHistoryResponse contains viewing history 74type ViewerHistoryResponse struct { 75 Sessions []WatchSession `json:"sessions"` 76} 77 78// WatchSession represents a single viewing session 79type WatchSession struct { 80 SessionId string `json:"sessionId"` 81 StreamerDid string `json:"streamerDid"` 82 StreamId *string `json:"streamId,omitempty"` 83 StartTimeMs int64 `json:"startTimeMs"` 84 EndTimeMs int64 `json:"endTimeMs"` 85 DurationMs uint64 `json:"durationMs"` 86} 87 88// Conversion helpers 89 90func convertRealtimeStatsResponse(pbResp *pb.RealtimeStatsResponse) *RealtimeStatsResponse { 91 if pbResp == nil { 92 return &RealtimeStatsResponse{} 93 } 94 95 streamers := make([]StreamerRealtimeStats, len(pbResp.Streamers)) 96 for i, s := range pbResp.Streamers { 97 streamers[i] = StreamerRealtimeStats{ 98 StreamerDid: s.StreamerDid, 99 CurrentViewers: s.CurrentViewers, 100 TotalWatchTimeMs: s.TotalWatchTimeMs, 101 } 102 } 103 104 return &RealtimeStatsResponse{ 105 Streamers: streamers, 106 } 107} 108 109func convertStreamerStatsResponse(pbResp *pb.StreamerStatsResponse) *StreamerStatsResponse { 110 if pbResp == nil { 111 return &StreamerStatsResponse{} 112 } 113 114 dailyStats := make([]DailyStats, len(pbResp.DailyStats)) 115 for i, s := range pbResp.DailyStats { 116 dailyStats[i] = DailyStats{ 117 Date: s.Date, 118 Views: s.Views, 119 WatchTimeMs: s.WatchTimeMs, 120 UniqueViewers: s.UniqueViewers, 121 } 122 } 123 124 return &StreamerStatsResponse{ 125 StreamerDid: pbResp.StreamerDid, 126 TotalViews: pbResp.TotalViews, 127 TotalWatchTimeMs: pbResp.TotalWatchTimeMs, 128 UniqueViewers: pbResp.UniqueViewers, 129 DailyStats: dailyStats, 130 } 131} 132 133func convertViewerHistoryResponse(pbResp *pb.ViewerHistoryResponse) *ViewerHistoryResponse { 134 if pbResp == nil { 135 return &ViewerHistoryResponse{} 136 } 137 138 sessions := make([]WatchSession, len(pbResp.Sessions)) 139 for i, s := range pbResp.Sessions { 140 sessions[i] = WatchSession{ 141 SessionId: s.SessionId, 142 StreamerDid: s.StreamerDid, 143 StreamId: s.StreamId, 144 StartTimeMs: s.StartTimeMs, 145 EndTimeMs: s.EndTimeMs, 146 DurationMs: s.DurationMs, 147 } 148 } 149 150 return &ViewerHistoryResponse{ 151 Sessions: sessions, 152 } 153}