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  }