github.com/status-im/status-go@v1.1.0/centralizedmetrics/providers/appsflyer.go (about)

     1  package providers
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/json"
     6  	"errors"
     7  	"fmt"
     8  	"net/http"
     9  	"time"
    10  
    11  	"github.com/ethereum/go-ethereum/log"
    12  
    13  	"github.com/status-im/status-go/centralizedmetrics/common"
    14  )
    15  
    16  const AppsflyerBaseURL = "https://api3.appsflyer.com"
    17  
    18  var AppsflyerAppID = ""
    19  var AppsflyerToken = ""
    20  
    21  // AppsflyerMetricProcessor implements MetricProcessor for Appsflyer
    22  type AppsflyerMetricProcessor struct {
    23  	appID   string
    24  	secret  string
    25  	baseURL string
    26  }
    27  
    28  // NewAppsflyerMetricProcessor is a constructor for AppsflyerMetricProcessor
    29  func NewAppsflyerMetricProcessor(appID, secret, baseURL string) *AppsflyerMetricProcessor {
    30  	return &AppsflyerMetricProcessor{
    31  		appID:   appID,
    32  		secret:  secret,
    33  		baseURL: baseURL,
    34  	}
    35  }
    36  
    37  func (p *AppsflyerMetricProcessor) GetAppID() string {
    38  	if len(p.appID) != 0 {
    39  		return p.appID
    40  	}
    41  	return AppsflyerAppID
    42  }
    43  
    44  func (p *AppsflyerMetricProcessor) GetToken() string {
    45  	if len(p.secret) != 0 {
    46  		return p.secret
    47  	}
    48  
    49  	return AppsflyerToken
    50  }
    51  
    52  // Process processes an array of metrics and sends them to the Appsflyer API
    53  func (p *AppsflyerMetricProcessor) Process(metrics []common.Metric) error {
    54  	for _, metric := range metrics {
    55  		if err := p.sendToAppsflyer(metric); err != nil {
    56  			return err
    57  		}
    58  	}
    59  	return nil
    60  }
    61  
    62  // sendToAppsflyer sends a single metric to the Appsflyer API
    63  func (p *AppsflyerMetricProcessor) sendToAppsflyer(metric common.Metric) error {
    64  	url := fmt.Sprintf("%s/inappevent/%s", p.baseURL, p.GetAppID())
    65  
    66  	payload, err := json.Marshal(toAppsflyerMetric(metric))
    67  	if err != nil {
    68  		return err
    69  	}
    70  
    71  	req, err := http.NewRequest("POST", url, bytes.NewBuffer(payload))
    72  	if err != nil {
    73  		return err
    74  	}
    75  
    76  	req.Header.Set("accept", "application/json")
    77  	req.Header.Set("authentication", p.GetToken())
    78  	req.Header.Set("content-type", "application/json")
    79  
    80  	client := &http.Client{}
    81  	resp, err := client.Do(req)
    82  	if err != nil {
    83  		return err
    84  	}
    85  	defer resp.Body.Close()
    86  
    87  	if resp.StatusCode != http.StatusOK {
    88  		log.Warn("failed to send metric", "status-code", resp.StatusCode, "body", resp.Body)
    89  		return errors.New("failed to send metric to Appsflyer")
    90  	}
    91  
    92  	return nil
    93  }
    94  
    95  func toAppsflyerMetric(metric common.Metric) appsflyerMetric {
    96  	timestampMillis := metric.Timestamp
    97  
    98  	seconds := timestampMillis / 1000
    99  	nanoseconds := (timestampMillis % 1000) * int64(time.Millisecond)
   100  
   101  	t := time.Unix(seconds, nanoseconds).UTC()
   102  
   103  	formattedTime := t.Format("2006-01-02 15:04:05.000")
   104  
   105  	return appsflyerMetric{
   106  		AppsflyerID: metric.UserID,
   107  		EventName:   metric.EventName,
   108  		EventValue:  metric.EventValue,
   109  		EventTime:   formattedTime,
   110  	}
   111  }
   112  
   113  type appsflyerMetric struct {
   114  	AppsflyerID string      `json:"appsflyer_id"`
   115  	EventName   string      `json:"eventName"`
   116  	EventValue  interface{} `json:"eventValue"`
   117  	EventTime   string      `json:"eventTime"`
   118  }