From 13c89404d725e0dd84e081aa5f37cbc6c10b147e Mon Sep 17 00:00:00 2001 From: Mikhail Iudin Date: Tue, 25 Apr 2023 18:17:59 +0200 Subject: [PATCH] GO-894 Change amplitude report url to self-hosted --- go.mod | 1 - go.sum | 2 - metrics/amplitude/client.go | 105 +++++++++++++++++++++++++++++++ metrics/amplitude/client_test.go | 58 +++++++++++++++++ metrics/client.go | 9 +-- 5 files changed, 168 insertions(+), 7 deletions(-) create mode 100644 metrics/amplitude/client.go create mode 100644 metrics/amplitude/client_test.go diff --git a/go.mod b/go.mod index 0026403a9..a7581159f 100644 --- a/go.mod +++ b/go.mod @@ -70,7 +70,6 @@ require ( github.com/microcosm-cc/bluemonday v1.0.1 github.com/miolini/datacounter v1.0.2 github.com/mr-tron/base58 v1.2.0 - github.com/msingleton/amplitude-go v0.0.0-20200312121213-b7c11448c30e github.com/multiformats/go-base32 v0.1.0 github.com/multiformats/go-multiaddr v0.8.0 github.com/multiformats/go-multiaddr-dns v0.3.1 diff --git a/go.sum b/go.sum index 656b574d4..d28f88c5e 100644 --- a/go.sum +++ b/go.sum @@ -83,8 +83,6 @@ github.com/andybalholm/cascadia v1.3.1 h1:nhxRkql1kdYCc8Snf7D5/D3spOX+dBgjA6u8x0 github.com/andybalholm/cascadia v1.3.1/go.mod h1:R4bJ1UQfqADjvDa4P6HZHLh/3OxWWEqc0Sk8XGwHqvA= github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= -github.com/anytypeio/amplitude-go v0.0.0-20211130222238-8d16496a9b31 h1:fCXBjRAxXq4pKyfH8xmYPfjL/E6v5zTTxYrIKDz8ufw= -github.com/anytypeio/amplitude-go v0.0.0-20211130222238-8d16496a9b31/go.mod h1:uX6FcwR+wTQWzFszLXQxeKfNeittg1408V7pVAtLKqQ= github.com/anytypeio/any-sync v0.0.27 h1:k09fDKfnZKcft+mYe/Ns8dTm2x3HyeIxmsaSHT996iA= github.com/anytypeio/any-sync v0.0.27/go.mod h1:a34AUcUteo1Vc3InnM1TPXvakBWeb5HsHxFvHYqUmPc= github.com/anytypeio/go-chash v0.0.2 h1:BSpyMC3HXNkf2eosQrHM4svov0DrvxL9tb4gnHbdmbA= diff --git a/metrics/amplitude/client.go b/metrics/amplitude/client.go new file mode 100644 index 000000000..a23b357c4 --- /dev/null +++ b/metrics/amplitude/client.go @@ -0,0 +1,105 @@ +package amplitude + +import ( + "bytes" + "context" + "encoding/json" + "net/http" + "time" +) + +const eventEndpoint = "https://amplitude.anytype.io/2/httpapi" + +// Client manages the communication to the Amplitude API +type Client struct { + eventEndpoint string + key string + client *http.Client +} + +type Event struct { + Adid string `json:"adid,omitempty"` + AppVersion string `json:"app_version,omitempty"` + Carrier string `json:"carrier,omitempty"` + City string `json:"city,omitempty"` + Country string `json:"country,omitempty"` + DeviceBrand string `json:"device_brand,omitempty"` + DeviceID string `json:"device_id,omitempty"` + DeviceManufacturer string `json:"device_manufacturer,omitempty"` + DeviceModel string `json:"device_model,omitempty"` + DeviceType string `json:"device_type,omitempty"` + Dma string `json:"dma,omitempty"` + EventID int `json:"event_id,omitempty"` + EventProperties map[string]interface{} `json:"event_properties,omitempty"` + EventType string `json:"event_type,omitempty"` + Groups map[string]interface{} `json:"groups,omitempty"` + Ifda string `json:"ifda,omitempty"` + InsertID string `json:"insert_id,omitempty"` + IP string `json:"ip,omitempty"` + Language string `json:"language,omitempty"` + LocationLat string `json:"location_lat,omitempty"` + LocationLng string `json:"location_lng,omitempty"` + OsName string `json:"os_name,omitempty"` + OsVersion string `json:"os_version,omitempty"` + Paying string `json:"paying,omitempty"` + Platform string `json:"platform,omitempty"` + Price float64 `json:"price,omitempty"` + ProductID string `json:"productId,omitempty"` + Quantity int `json:"quantity,omitempty"` + Region string `json:"region,omitempty"` + Revenue float64 `json:"revenue,omitempty"` + RevenueType string `json:"revenueType,omitempty"` + SessionID int64 `json:"session_id,omitempty"` + StartVersion string `json:"start_version,omitempty"` + Time int64 `json:"time,omitempty"` + UserID string `json:"user_id,omitempty"` + UserProperties map[string]interface{} `json:"user_properties,omitempty"` +} + +type EventRequest struct { + APIKey string `json:"api_key,omitempty"` + Events []Event `json:"events,omitempty"` +} + +// New client with API key +func New(key string) *Client { + return &Client{ + eventEndpoint: eventEndpoint, + key: key, + client: new(http.Client), + } +} + +func (c *Client) SetClient(client *http.Client) { + c.client = client +} + +func (c *Client) Events(events []Event) error { + req := EventRequest{ + APIKey: c.key, + Events: events, + } + evJSON, err := json.Marshal(req) + if err != nil { + return err + } + + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + r, err := http.NewRequestWithContext(ctx, "POST", eventEndpoint, bytes.NewReader(evJSON)) + if err != nil { + return err + } + + r.Header.Set("content-type", "application/json") + resp, err := c.client.Do(r) + if err == nil { + return resp.Body.Close() + } + + return err +} + +func (c *Client) Event(msg Event) error { + return c.Events([]Event{msg}) +} diff --git a/metrics/amplitude/client_test.go b/metrics/amplitude/client_test.go new file mode 100644 index 000000000..814f29103 --- /dev/null +++ b/metrics/amplitude/client_test.go @@ -0,0 +1,58 @@ +package amplitude + +import ( + "encoding/json" + "fmt" + "net/http" + "net/http/httptest" +) + +func ExampleEvent() { + keyResp, bodyResp, server := mockServer("event") + defer server.Close() + + client := New("s3cr3ts") + client.eventEndpoint = server.URL + + client.Event(Event{ + UserID: "0000001", + EventType: "joined", + }) + + key := <-keyResp + body := <-bodyResp + fmt.Printf("Key: %s\n%s", string(key), string(body)) + + // Output: + // Key: s3cr3ts + // { + // "event_type": "joined", + // "user_id": "0000001" + // } +} + +func mockServer(msgKey string) (chan []byte, chan []byte, *httptest.Server) { + key, body := make(chan []byte, 1), make(chan []byte, 1) + + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + r.ParseForm() + k := r.FormValue("api_key") + id := r.FormValue(msgKey) + + var v interface{} + err := json.Unmarshal([]byte(id), &v) + if err != nil { + panic(err) + } + + b, err := json.MarshalIndent(v, "", " ") + if err != nil { + panic(err) + } + + key <- []byte(k) + body <- b + })) + + return key, body, server +} diff --git a/metrics/client.go b/metrics/client.go index 3025cc10f..a60e78228 100644 --- a/metrics/client.go +++ b/metrics/client.go @@ -2,12 +2,13 @@ package metrics import ( "context" - "github.com/cheggaaa/mb" "sync" "time" + "github.com/cheggaaa/mb" + + "github.com/anytypeio/go-anytype-middleware/metrics/amplitude" "github.com/anytypeio/go-anytype-middleware/pkg/lib/logging" - "github.com/msingleton/amplitude-go" ) var ( @@ -255,9 +256,9 @@ func (c *client) RecordEvent(ev EventRepresentable) { } c.lock.RLock() ampEvent := amplitude.Event{ - UserId: c.userId, + UserID: c.userId, Platform: c.platform, - DeviceId: c.deviceId, + DeviceID: c.deviceId, EventType: e.EventType, EventProperties: e.EventData, AppVersion: c.appVersion,