Skip to content

Commit

Permalink
feat: refactor event creation and move clients
Browse files Browse the repository at this point in the history
  • Loading branch information
franklinkim committed May 25, 2024
1 parent 5cb6719 commit a4fa86a
Show file tree
Hide file tree
Showing 58 changed files with 468 additions and 229 deletions.
4 changes: 2 additions & 2 deletions integration/watermill/mpv2/messagehandler.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ import (
"github.com/pkg/errors"
)

func MessageHandler(handler func(payload *mpv2.Payload[any], msg *message.Message) error) func(msg *message.Message) ([]*message.Message, error) {
func MessageHandler(handler func(payload *mpv2.Payload[map[string]any], msg *message.Message) error) func(msg *message.Message) ([]*message.Message, error) {
return func(msg *message.Message) ([]*message.Message, error) {
var payload *mpv2.Payload[any]
var payload *mpv2.Payload[map[string]any]

// unmarshal payload
if err := json.Unmarshal(msg.Payload, &payload); err != nil {
Expand Down
71 changes: 31 additions & 40 deletions pkg/encoding/gtag/client.go → pkg/client/gtag.go
Original file line number Diff line number Diff line change
@@ -1,54 +1,55 @@
package gtag
package client

import (
"fmt"
"io"
"net/http"

"github.com/foomo/sesamy-go/pkg/encoding/gtag"
"github.com/pkg/errors"
"go.uber.org/zap"
)

type (
Client struct {
GTag struct {
l *zap.Logger
path string
host string
cookies []string
trackingID string
protocolVersion string
httpClient *http.Client
middlewares []ClientMiddleware
middlewares []GTagMiddleware
}
ClientOption func(*Client)
ClientHandler func(r *http.Request, event *Payload) error
ClientMiddleware func(next ClientHandler) ClientHandler
GTagOption func(*GTag)
GTagHandler func(r *http.Request, payload *gtag.Payload) error
GTagMiddleware func(next GTagHandler) GTagHandler
)

// ------------------------------------------------------------------------------------------------
// ~ Options
// ------------------------------------------------------------------------------------------------

func ClientWithHTTPClient(v *http.Client) ClientOption {
return func(o *Client) {
func GTagWithHTTPClient(v *http.Client) GTagOption {
return func(o *GTag) {
o.httpClient = v
}
}

func ClientWithPath(v string) ClientOption {
return func(o *Client) {
func GTagWithPath(v string) GTagOption {
return func(o *GTag) {
o.path = v
}
}

func ClientWithCookies(v ...string) ClientOption {
return func(o *Client) {
func GTagWithCookies(v ...string) GTagOption {
return func(o *GTag) {
o.cookies = append(o.cookies, v...)
}
}

func ClientWithMiddlewares(v ...ClientMiddleware) ClientOption {
return func(o *Client) {
func GTagWithMiddlewares(v ...GTagMiddleware) GTagOption {
return func(o *GTag) {
o.middlewares = append(o.middlewares, v...)
}
}
Expand All @@ -57,8 +58,8 @@ func ClientWithMiddlewares(v ...ClientMiddleware) ClientOption {
// ~ Constructor
// ------------------------------------------------------------------------------------------------

func NewClient(l *zap.Logger, host, trackingID string, opts ...ClientOption) *Client {
inst := &Client{
func NewGTag(l *zap.Logger, host, trackingID string, opts ...GTagOption) *GTag {
inst := &GTag{
l: l,
host: host,
path: "/g/collect",
Expand All @@ -71,14 +72,12 @@ func NewClient(l *zap.Logger, host, trackingID string, opts ...ClientOption) *Cl
opt(inst)
}
inst.middlewares = append(inst.middlewares,
MiddlewareRichsstsse,
MiddlewareTrackingID(inst.trackingID),
// MiddlewarIgnoreReferrer("1"),
MiddlewarProtocolVersion("2"),
// MiddlewarDebug,
MiddlewarClientID,
MiddlewarSessionID(inst.trackingID),
MiddlewarDocument,
GTagMiddlewareRichsstsse,
GTagMiddlewareTrackingID(inst.trackingID),
GTagMiddlewarProtocolVersion("2"),
GTagMiddlewarIsDebug,
GTagMiddlewarClientID,
GTagMiddlewarSessionID(inst.trackingID),
)
return inst
}
Expand All @@ -87,40 +86,32 @@ func NewClient(l *zap.Logger, host, trackingID string, opts ...ClientOption) *Cl
// ~ Getter
// ------------------------------------------------------------------------------------------------

func (c *Client) HTTPClient() *http.Client {
func (c *GTag) HTTPClient() *http.Client {
return c.httpClient
}

// ------------------------------------------------------------------------------------------------
// ~ Public methods
// ------------------------------------------------------------------------------------------------

func (c *Client) Send(r *http.Request, event Marshler) error {
e, err := event.MarshalMPv2()
if err != nil {
return err
}
return c.SendEvent(r, e)
}

func (c *Client) SendEvent(r *http.Request, event *Payload) error {
next := c.SendRawEvent
func (c *GTag) Send(r *http.Request, payload *gtag.Payload) error {
next := c.SendRaw
for _, middleware := range c.middlewares {
next = middleware(next)
}
return next(r, event)
return next(r, payload)
}

func (c *Client) SendRawEvent(r *http.Request, event *Payload) error {
values, body, err := Encode(event)
func (c *GTag) SendRaw(r *http.Request, payload *gtag.Payload) error {
values, body, err := gtag.Encode(payload)
if err != nil {
return errors.Wrap(err, "failed to encode event")
return errors.Wrap(err, "failed to encode payload")
}

req, err := http.NewRequestWithContext(
r.Context(),
http.MethodPost,
fmt.Sprintf("%s%s?%s", c.host, c.path, EncodeValues(values)),
fmt.Sprintf("%s%s?%s", c.host, c.path, gtag.EncodeValues(values)),
body,
)
if err != nil {
Expand Down
35 changes: 35 additions & 0 deletions pkg/client/gtag_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package client_test

import (
"context"
"net/http"
"net/http/httptest"
"net/http/httputil"
"testing"

"github.com/foomo/sesamy-go/pkg/client"
"github.com/foomo/sesamy-go/pkg/encoding/gtag"
"github.com/foomo/sesamy-go/pkg/sesamy"
"github.com/stretchr/testify/require"
"go.uber.org/zap/zaptest"
)

func TestNewGtag(t *testing.T) {
l := zaptest.NewLogger(t)

s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
t.Helper()
out, err := httputil.DumpRequest(r, true)
require.NoError(t, err)
t.Log(string(out))
}))

c := client.NewGTag(l, s.URL, "GA-XXXXXX")
incomingReq, err := http.NewRequestWithContext(context.TODO(), http.MethodGet, "/foo/bar", nil)
require.NoError(t, err)

err = c.Send(incomingReq, &gtag.Payload{
EventName: gtag.Set(sesamy.EventName("page_view")),
})
require.NoError(t, err)
}
75 changes: 75 additions & 0 deletions pkg/client/gtagmiddleware.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package client

import (
"net/http"
"strings"

"github.com/foomo/sesamy-go/pkg/encoding/gtag"
"github.com/foomo/sesamy-go/pkg/session"
"github.com/pkg/errors"
)

func GTagMiddlewareRichsstsse(next GTagHandler) GTagHandler {
v := ""
return func(r *http.Request, payload *gtag.Payload) error {
payload.Richsstsse = &v
return next(r, payload)
}
}

func GTagMiddlewareTrackingID(v string) GTagMiddleware {
return func(next GTagHandler) GTagHandler {
return func(r *http.Request, payload *gtag.Payload) error {
payload.TrackingID = &v
return next(r, payload)
}
}
}

func GTagMiddlewarProtocolVersion(v string) GTagMiddleware {
return func(next GTagHandler) GTagHandler {
return func(r *http.Request, payload *gtag.Payload) error {
payload.ProtocolVersion = &v
return next(r, payload)
}
}
}

func GTagMiddlewarIsDebug(next GTagHandler) GTagHandler {
v := "1"
return func(r *http.Request, payload *gtag.Payload) error {
if session.IsGTMDebug(r) {
payload.IsDebug = &v
}
return next(r, payload)
}
}

func GTagMiddlewarClientID(next GTagHandler) GTagHandler {
return func(r *http.Request, payload *gtag.Payload) error {
value, err := session.ParseGAClientID(r)
if err != nil && !errors.Is(err, http.ErrNoCookie) {
return errors.Wrap(err, "failed to parse client cookie")
}
if value != "" {
payload.ClientID = &value
}
return next(r, payload)
}
}

func GTagMiddlewarSessionID(trackingID string) GTagMiddleware {
trackingID = strings.Split(trackingID, "-")[1]
return func(next GTagHandler) GTagHandler {
return func(r *http.Request, payload *gtag.Payload) error {
value, err := session.ParseGASessionID(r, trackingID)
if err != nil && !errors.Is(err, http.ErrNoCookie) {
return errors.Wrap(err, "failed to parse session cookie")
}
if value != "" {
payload.SessionID = &value
}
return next(r, payload)
}
}
}
Loading

0 comments on commit a4fa86a

Please sign in to comment.