github.com/status-im/status-go@v1.1.0/protocol/messenger_community_metrics.go (about) 1 package protocol 2 3 import ( 4 "fmt" 5 "sort" 6 7 "github.com/status-im/status-go/eth-node/types" 8 "github.com/status-im/status-go/protocol/requests" 9 ) 10 11 type MetricsIntervalResponse struct { 12 StartTimestamp uint64 `json:"startTimestamp"` 13 EndTimestamp uint64 `json:"endTimestamp"` 14 Timestamps []uint64 `json:"timestamps"` 15 Count int `json:"count"` 16 } 17 18 type CommunityMetricsResponse struct { 19 Type requests.CommunityMetricsRequestType `json:"type"` 20 CommunityID types.HexBytes `json:"communityId"` 21 Intervals []MetricsIntervalResponse `json:"intervals"` 22 } 23 24 func (m *Messenger) getChatIdsForCommunity(communityID types.HexBytes) ([]string, error) { 25 community, err := m.GetCommunityByID(communityID) 26 if err != nil { 27 return []string{}, err 28 } 29 return community.ChatIDs(), nil 30 } 31 32 func (m *Messenger) collectCommunityMessagesTimestamps(request *requests.CommunityMetricsRequest) (*CommunityMetricsResponse, error) { 33 chatIDs, err := m.getChatIdsForCommunity(request.CommunityID) 34 if err != nil { 35 return nil, err 36 } 37 38 intervals := make([]MetricsIntervalResponse, len(request.Intervals)) 39 for i, sourceInterval := range request.Intervals { 40 // TODO: messages count should be stored in special table, not calculated here 41 timestamps, err := m.persistence.SelectMessagesTimestampsForChatsByPeriod(chatIDs, sourceInterval.StartTimestamp, sourceInterval.EndTimestamp) 42 if err != nil { 43 return nil, err 44 } 45 46 // there is no built-in sort for uint64 47 sort.Slice(timestamps, func(i, j int) bool { return timestamps[i] < timestamps[j] }) 48 49 intervals[i] = MetricsIntervalResponse{ 50 StartTimestamp: sourceInterval.StartTimestamp, 51 EndTimestamp: sourceInterval.EndTimestamp, 52 Timestamps: timestamps, 53 Count: len(timestamps), 54 } 55 } 56 57 response := &CommunityMetricsResponse{ 58 Type: request.Type, 59 CommunityID: request.CommunityID, 60 Intervals: intervals, 61 } 62 63 return response, nil 64 } 65 66 func (m *Messenger) collectCommunityMessagesCount(request *requests.CommunityMetricsRequest) (*CommunityMetricsResponse, error) { 67 chatIDs, err := m.getChatIdsForCommunity(request.CommunityID) 68 if err != nil { 69 return nil, err 70 } 71 72 intervals := make([]MetricsIntervalResponse, len(request.Intervals)) 73 for i, sourceInterval := range request.Intervals { 74 // TODO: messages count should be stored in special table, not calculated here 75 count, err := m.persistence.SelectMessagesCountForChatsByPeriod(chatIDs, sourceInterval.StartTimestamp, sourceInterval.EndTimestamp) 76 if err != nil { 77 return nil, err 78 } 79 intervals[i] = MetricsIntervalResponse{ 80 StartTimestamp: sourceInterval.StartTimestamp, 81 EndTimestamp: sourceInterval.EndTimestamp, 82 Count: count, 83 } 84 } 85 86 response := &CommunityMetricsResponse{ 87 Type: request.Type, 88 CommunityID: request.CommunityID, 89 Intervals: intervals, 90 } 91 92 return response, nil 93 } 94 95 func (m *Messenger) CollectCommunityMetrics(request *requests.CommunityMetricsRequest) (*CommunityMetricsResponse, error) { 96 if err := request.Validate(); err != nil { 97 return nil, err 98 } 99 100 switch request.Type { 101 case requests.CommunityMetricsRequestMessagesTimestamps: 102 return m.collectCommunityMessagesTimestamps(request) 103 case requests.CommunityMetricsRequestMessagesCount: 104 return m.collectCommunityMessagesCount(request) 105 default: 106 return nil, fmt.Errorf("metrics for %d is not implemented yet", request.Type) 107 } 108 }