Andrea Maria Piana 9a59d6a459 feat(metrics)_: add centralized metrics
This commit adds support for centralized metrics.
There are two providers as of now, and we haven't quite decided which
one to go for, so for the time being both are supported.
It also introduces a new endpoint InitializeApplication that replaces
OpenAccounts
2024-07-11 10:05:31 +01:00

119 lines
2.7 KiB
Go

package providers
import (
"bytes"
"encoding/json"
"errors"
"fmt"
"net/http"
"time"
"github.com/ethereum/go-ethereum/log"
"github.com/status-im/status-go/centralizedmetrics/common"
)
const AppsflyerBaseURL = "https://api3.appsflyer.com"
var AppsflyerAppID = ""
var AppsflyerToken = ""
// AppsflyerMetricProcessor implements MetricProcessor for Appsflyer
type AppsflyerMetricProcessor struct {
appID string
secret string
baseURL string
}
// NewAppsflyerMetricProcessor is a constructor for AppsflyerMetricProcessor
func NewAppsflyerMetricProcessor(appID, secret, baseURL string) *AppsflyerMetricProcessor {
return &AppsflyerMetricProcessor{
appID: appID,
secret: secret,
baseURL: baseURL,
}
}
func (p *AppsflyerMetricProcessor) GetAppID() string {
if len(p.appID) != 0 {
return p.appID
}
return AppsflyerAppID
}
func (p *AppsflyerMetricProcessor) GetToken() string {
if len(p.secret) != 0 {
return p.secret
}
return AppsflyerToken
}
// Process processes an array of metrics and sends them to the Appsflyer API
func (p *AppsflyerMetricProcessor) Process(metrics []common.Metric) error {
for _, metric := range metrics {
if err := p.sendToAppsflyer(metric); err != nil {
return err
}
}
return nil
}
// sendToAppsflyer sends a single metric to the Appsflyer API
func (p *AppsflyerMetricProcessor) sendToAppsflyer(metric common.Metric) error {
url := fmt.Sprintf("%s/inappevent/%s", p.baseURL, p.GetAppID())
payload, err := json.Marshal(toAppsflyerMetric(metric))
if err != nil {
return err
}
req, err := http.NewRequest("POST", url, bytes.NewBuffer(payload))
if err != nil {
return err
}
req.Header.Set("accept", "application/json")
req.Header.Set("authentication", p.GetToken())
req.Header.Set("content-type", "application/json")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
log.Warn("failed to send metric", "status-code", resp.StatusCode, "body", resp.Body)
return errors.New("failed to send metric to Appsflyer")
}
return nil
}
func toAppsflyerMetric(metric common.Metric) appsflyerMetric {
timestampMillis := metric.Timestamp
seconds := timestampMillis / 1000
nanoseconds := (timestampMillis % 1000) * int64(time.Millisecond)
t := time.Unix(seconds, nanoseconds).UTC()
formattedTime := t.Format("2006-01-02 15:04:05.000")
return appsflyerMetric{
AppsflyerID: metric.UserID,
EventName: metric.EventName,
EventValue: metric.EventValue,
EventTime: formattedTime,
}
}
type appsflyerMetric struct {
AppsflyerID string `json:"appsflyer_id"`
EventName string `json:"eventName"`
EventValue interface{} `json:"eventValue"`
EventTime string `json:"eventTime"`
}