feat: add inline mpv2

This commit is contained in:
Kevin Franklin Kim 2024-09-30 18:01:20 +02:00
parent ee153c3504
commit 38715a58b6
No known key found for this signature in database
8 changed files with 143 additions and 16 deletions

7
go.mod
View File

@ -6,6 +6,7 @@ toolchain go1.23.0
require (
github.com/ThreeDotsLabs/watermill v1.3.5
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc
github.com/foomo/go v0.0.3
github.com/foomo/gostandards v0.1.0
github.com/gogo/protobuf v1.3.2
@ -17,8 +18,10 @@ require (
github.com/mitchellh/mapstructure v1.5.0
github.com/pkg/errors v0.9.1
github.com/prometheus/common v0.55.0
github.com/qntfy/kazaam/v4 v4.0.1
github.com/stretchr/testify v1.9.0
go.uber.org/zap v1.27.0
gopkg.in/yaml.v2 v2.4.0
)
require (
@ -40,7 +43,6 @@ require (
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/coreos/go-semver v0.3.0 // indirect
github.com/coreos/go-systemd/v22 v22.5.0 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/dennwc/varint v1.0.0 // indirect
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
github.com/dustin/go-humanize v1.0.1 // indirect
@ -54,6 +56,7 @@ require (
github.com/go-logr/logr v1.4.1 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-redis/redis/v8 v8.11.5 // indirect
github.com/gofrs/uuid v3.2.0+incompatible // indirect
github.com/gogo/googleapis v1.4.0 // indirect
github.com/gogo/status v1.1.1 // indirect
github.com/golang-jwt/jwt/v5 v5.2.1 // indirect
@ -108,6 +111,7 @@ require (
github.com/prometheus/exporter-toolkit v0.11.0 // indirect
github.com/prometheus/procfs v0.15.1 // indirect
github.com/prometheus/prometheus v0.51.0 // indirect
github.com/qntfy/jsonparser v1.0.2 // indirect
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 // indirect
github.com/sercand/kuberesolver/v5 v5.1.1 // indirect
github.com/shopspring/decimal v1.2.0 // indirect
@ -140,7 +144,6 @@ require (
google.golang.org/genproto/googleapis/rpc v0.0.0-20240318140521-94a12d6c2237 // indirect
google.golang.org/grpc v1.62.1 // indirect
google.golang.org/protobuf v1.34.2 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
k8s.io/apimachinery v0.29.2 // indirect
k8s.io/client-go v0.29.2 // indirect

6
go.sum
View File

@ -201,6 +201,8 @@ github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/me
github.com/go-zookeeper/zk v1.0.3 h1:7M2kwOsc//9VeeFiPtf+uSJlVpU66x9Ba5+8XK7/TDg=
github.com/go-zookeeper/zk v1.0.3/go.mod h1:nOB03cncLtlp4t+UAkGSV+9beXP/akpekBwL+UX1Qcw=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/gofrs/uuid v3.2.0+incompatible h1:y12jRkkFxsd7GpqdSZ+/KCs/fJbqpEXSGd4+jfEaewE=
github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
github.com/gogo/googleapis v0.0.0-20180223154316-0cd9801be74a/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s=
github.com/gogo/googleapis v1.4.0 h1:zgVt4UpGxcqVOw97aRGxT4svlcmdK35fynLNctY32zI=
github.com/gogo/googleapis v1.4.0/go.mod h1:5YRNX2z1oM5gXdAkurHa942MDgEJyk02w4OecKY87+c=
@ -529,6 +531,10 @@ github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0leargg
github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=
github.com/prometheus/prometheus v0.51.0 h1:aRdjTnmHLved29ILtdzZN2GNvOjWATtA/z+3fYuexOc=
github.com/prometheus/prometheus v0.51.0/go.mod h1:yv4MwOn3yHMQ6MZGHPg/U7Fcyqf+rxqiZfSur6myVtc=
github.com/qntfy/jsonparser v1.0.2 h1:hko+J4L7HSaYoB2yuzinWc9MkO93zWKUmzPHJwB53OM=
github.com/qntfy/jsonparser v1.0.2/go.mod h1:F+LCdwPnFBsubQ+ugnBczIP9RWv5wSCqnUmLHPUx4ZU=
github.com/qntfy/kazaam/v4 v4.0.1 h1:fMOC+w4o6ZYcWeKiscvPJDYPIDa1UwertGeOjTP/yII=
github.com/qntfy/kazaam/v4 v4.0.1/go.mod h1:wGZi4dkLdXkZJnAh3s9k27TAwov5z4DqdbuQJ/tqLdE=
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8=

View File

@ -149,12 +149,9 @@ func (p *Publisher) handle(l *zap.Logger, msg *message.Message) error {
if body, err := io.ReadAll(resp.Body); err == nil {
l = l.With(zap.String("http_response", string(body)))
}
l.Warn("server responded with error")
return errors.Wrap(ErrErrorResponse, resp.Status)
}
l.Debug("message published")
return nil
}(); err != nil {
return err

View File

@ -0,0 +1,70 @@
package mpv2_test
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/http/httptest"
"sync/atomic"
"testing"
"time"
"github.com/ThreeDotsLabs/watermill"
"github.com/ThreeDotsLabs/watermill/message"
"github.com/foomo/sesamy-go/integration/watermill/mpv2"
encoding "github.com/foomo/sesamy-go/pkg/encoding/mpv2"
"github.com/foomo/sesamy-go/pkg/event"
"github.com/foomo/sesamy-go/pkg/event/params"
"github.com/foomo/sesamy-go/pkg/sesamy"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"go.uber.org/zap/zaptest"
)
func TestPublisher(t *testing.T) {
l := zaptest.NewLogger(t)
var done atomic.Bool
s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
out, err := io.ReadAll(r.Body)
assert.NoError(t, err)
expected := `{"client_id":"C123456","user_id":"U123456","timestamp_micros":1727701064057701,"events":[{"name":"page_view","params":{"debug_mode":true,"session_id":"S123456","engagement_time_msec":100,"page_title":"Home","page_location":"https://foomo.org"}}]}`
if !assert.JSONEq(t, expected, string(out)) {
fmt.Println(string(out))
}
done.Store(true)
}))
p := mpv2.NewPublisher(l, s.URL)
payload := encoding.Payload[params.PageView]{
ClientID: "C123456",
UserID: "U123456",
TimestampMicros: 1727701064057701,
UserProperties: nil,
Consent: nil,
Events: []sesamy.Event[params.PageView]{
event.NewPageView(params.PageView{
MPv2: &params.MPv2{
DebugMode: true,
SessionID: "S123456",
EngagementTimeMSec: 100,
},
PageTitle: "Home",
PageLocation: "https://foomo.org",
}),
},
UserData: nil,
}
jsonPayload, err := json.Marshal(payload)
require.NoError(t, err)
msg := message.NewMessage(watermill.NewUUID(), jsonPayload)
err = p.Publish("foo", msg)
require.NoError(t, err)
assert.Eventually(t, done.Load, time.Second, time.Millisecond)
}

View File

@ -4,16 +4,16 @@ import (
"github.com/foomo/sesamy-go/pkg/sesamy"
)
// https://developers.google.com/analytics/devguides/collection/protocol/ga4/reference?client_type=gtag#payload_post_body
type Payload[P any] struct {
ClientID string `json:"client_id,omitempty"`
UserID string `json:"user_id,omitempty"`
SessionID string `json:"session_id,omitempty"`
TimestampMicros int64 `json:"timestamp_micros,omitempty"`
EngagementTimeMSec int64 `json:"engagement_time_msec,omitempty"`
// Reserved user property names: https://developers.google.com/analytics/devguides/collection/protocol/ga4/reference?client_type=gtag#reserved_user_property_names
UserProperties map[string]any `json:"user_properties,omitempty"`
Consent *ConsentData `json:"consent,omitempty"`
Events []sesamy.Event[P] `json:"events,omitempty"`
UserData *UserData `json:"user_data,omitempty"`
DebugMode bool `json:"debug_mode,omitempty"`
SessionID string `json:"session_id,omitempty"`
EngagementTimeMSec int64 `json:"engagement_time_msec,omitempty"`
}

View File

@ -0,0 +1,43 @@
package mpv2_test
import (
"encoding/json"
"testing"
"github.com/foomo/sesamy-go/pkg/encoding/mpv2"
"github.com/foomo/sesamy-go/pkg/event"
"github.com/foomo/sesamy-go/pkg/event/params"
"github.com/foomo/sesamy-go/pkg/sesamy"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestPayload(t *testing.T) {
v := mpv2.Payload[params.PageView]{
ClientID: "C123456",
UserID: "U123456",
TimestampMicros: 1727701064057701,
UserProperties: nil,
Consent: nil,
Events: []sesamy.Event[params.PageView]{
event.NewPageView(params.PageView{
PageTitle: "Home",
PageLocation: "https://foomo.org",
}),
},
UserData: nil,
DebugMode: true,
SessionID: "S123456",
EngagementTimeMSec: 100,
}
out, err := json.Marshal(v)
require.NoError(t, err)
expected := `{"debug_mode":true,"session_id":"S123456","engagement_time_msec":100,"client_id":"C123456","user_id":"U123456","timestamp_micros":1727701064057701,"events":[{"name":"page_view","params":{"page_title":"Home","page_location":"https://foomo.org"}}]}`
assert.JSONEq(t, expected, string(out))
var in mpv2.Payload[params.PageView]
err = json.Unmarshal(out, &in)
require.NoError(t, err)
assert.Equal(t, v, in)
}

View File

@ -6,6 +6,7 @@ import (
// AddToCart https://developers.google.com/analytics/devguides/collection/protocol/ga4/reference/events#add_to_cart
type AddToCart[I any] struct {
*MPv2 `json:",inline"`
Currency iso4217.Currency `json:"currency,omitempty"`
Value float64 `json:"value,omitempty"`
Items []I `json:"items,omitempty"`

View File

@ -2,6 +2,13 @@ package params
// PageView https://developers.google.com/analytics/devguides/collection/ga4/views?client_type=gtag#manually_send_page_view_events
type PageView struct {
*MPv2 `json:",inline"`
PageTitle string `json:"page_title,omitempty"`
PageLocation string `json:"page_location,omitempty"`
}
type MPv2 struct {
DebugMode bool `json:"debug_mode,omitempty"`
SessionID string `json:"session_id,omitempty"`
EngagementTimeMSec int64 `json:"engagement_time_msec,omitempty"`
}