Skip to content

Commit

Permalink
fix: switch to json to decode
Browse files Browse the repository at this point in the history
  • Loading branch information
franklinkim committed May 22, 2024
1 parent de0c44a commit a774684
Show file tree
Hide file tree
Showing 8 changed files with 82 additions and 38 deletions.
4 changes: 4 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ go 1.21

require (
github.com/ThreeDotsLabs/watermill v1.3.5
github.com/foomo/go v0.0.3
github.com/foomo/gostandards v0.1.0
github.com/json-iterator/go v1.1.12
github.com/mitchellh/mapstructure v1.5.0
github.com/pkg/errors v0.9.1
github.com/stretchr/testify v1.9.0
Expand All @@ -15,6 +17,8 @@ require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/lithammer/shortuuid/v3 v3.0.7 // indirect
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/oklog/ulid v1.3.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
Expand Down
12 changes: 12 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,26 +1,38 @@
github.com/ThreeDotsLabs/watermill v1.3.5 h1:50JEPEhMGZQMh08ct0tfO1PsgMOAOhV3zxK2WofkbXg=
github.com/ThreeDotsLabs/watermill v1.3.5/go.mod h1:O/u/Ptyrk5MPTxSeWM5vzTtZcZfxXfO9PK9eXTYiFZY=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/foomo/go v0.0.3 h1:5pGzcPC78dImuBTT7nsZZnH+GIQUylbCtMkFEH26uZk=
github.com/foomo/go v0.0.3/go.mod h1:x6g64wiQusqaFElnh5rlk9unCgLKmfUWy0YFLejJxio=
github.com/foomo/gostandards v0.1.0 h1:dN6Yoj5un74W8hooC+boYcdbkTzF9jqU39q5kQCkzn4=
github.com/foomo/gostandards v0.1.0/go.mod h1:eyoFzndWb1kuDfupR/qf567mHeHZRi5//m64khreVac=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=
github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/lithammer/shortuuid/v3 v3.0.7 h1:trX0KTHy4Pbwo/6ia8fscyHoGA+mf1jWbPJVuvyJQQ8=
github.com/lithammer/shortuuid/v3 v3.0.7/go.mod h1:vMk8ke37EmiewwolSO1NLW8vP4ZaKlRuDIi8tWWmAts=
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4=
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
Expand Down
10 changes: 5 additions & 5 deletions pkg/encoding/gtag/decode.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,11 @@ func Decode(values url.Values, target any) error {
}

// default
v, err := url.QueryUnescape(value[0])
if err != nil {
return errors.Wrap(err, "failed to unescape query parameter")
}
data[key] = v
// v, err := url.QueryUnescape(value[0])
// if err != nil {
// return errors.Wrap(err, "failed to unescape query parameter")
// }
data[key] = value[0]
}

decoder, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{
Expand Down
6 changes: 5 additions & 1 deletion pkg/encoding/gtag/decode_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,16 @@ import (
"reflect"
"testing"

testingx "github.com/foomo/go/testing"
tagx "github.com/foomo/go/testing/tag"
"github.com/foomo/sesamy-go/pkg/encoding/gtag"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

func TestDecode(t *testing.T) {
testingx.Tags(t, tagx.Short)

tests := []struct {
name string
args string
Expand All @@ -30,7 +34,7 @@ func TestDecode(t *testing.T) {
{
name: "select_item",
args: "v=2&tid=G-F9XM71K45T&gtm=45he4580v9184715813z89184708445za200&_p=1715430403224&_dbg=1&gcd=13l3l3l2l1&npa=1&dma_cps=sypham&dma=1&cid=179294588.1715353601&ecid=251283723&ul=en-us&sr=3840x1600&_fplc=0&ur=&uaa=arm&uab=64&uafvl=Chromium%3B124.0.6367.119%7CGoogle%2520Chrome%3B124.0.6367.119%7CNot-A.Brand%3B99.0.0.0&uamb=0&uam=&uap=macOS&uapv=14.4.1&uaw=0&are=1&frm=0&pscdl=noapi&sst.gcd=13l3l3l2l1&sst.tft=1715430403224&sst.ude=0&_s=3&sid=1715428762&sct=2&seg=1&dl=https%3A%2F%2Fsesamy.local.bestbytes.net%2F%3Fgtm_debug%3D1715430402906&dr=https%3A%2F%2Ftagassistant.google.com%2F&dt=Home&en=select_item&pr1=idSKU_12345~nmStan%20and%20Friends%20Tee~afGoogle%20Merchandise%20Store~cpSUMMER_FUN~ds2.22~lp0~brGoogle~caApparel~c2Adult~c3Shirts~c4Crew~c5Short%20sleeve~lirelated_products~lnRelated%20Products~vagreen~loChIJIQBpAG2ahYAR_6128GcTUEo~pr10.01~qt3&ep.enable_page_views=false&ep.item_list_id=related_products&ep.item_list_name=Related%20products&_et=89&tfd=8618&richsstsse",
want: `{"consent":{"google_consent_default":"13l3l3l2l1"},"campaign":{},"ecommerce":{"items":[{"affiliation":"Google Merchandise Store","coupon":"SUMMER_FUN","discount":"2.22","item_brand":"Google","item_category":"Apparel","item_category2":"Adult","item_category3":"Shirts","item_category4":"Crew","item_category5":"Short sleeve","item_id":"SKU_12345","item_list_id":"related_products","item_list_name":"Related Products","item_name":"Stan and Friends Tee","item_variant":"green","item_list_position":"0","location_id":"ChIJIQBpAG2ahYAR_6128GcTUEo","price":"10.01","quantity":"3"}]},"client_hints":{"screen_resolution":"3840x1600","user_language":"en-us","user_agent_architecture":"arm","user_agent_bitness":"64","user_agent_full_version_list":"Chromium;124.0.6367.119|Google Chrome;124.0.6367.119|Not-A.Brand;99.0.0.0","user_agent_mobile":"0","user_agent_model":"","user_agent_platform":"macOS","user_agent_platform_version":"14.4.1","user_agent_wow_64":"0","user_region":""},"protocol_version":"2","tracking_id":"G-F9XM71K45T","gtmhash_info":"45he4580v9184715813z89184708445za200","client_id":"179294588.1715353601","richsstsse":"","document_location":"https://sesamy.local.bestbytes.net/?gtm_debug=1715430402906","document_title":"Home","document_referrer":"https://tagassistant.google.com/","event_name":"select_item","event_parameter":{"enable_page_views":"false","item_list_id":"related_products","item_list_name":"Related products"},"session_id":"1715428762","non_personalized_ads":"1","sst":{"tft":"1715430403224","gcd":"13l3l3l2l1"}}`,
want: `{"consent":{"google_consent_default":"13l3l3l2l1"},"campaign":{},"ecommerce":{"items":[{"affiliation":"Google Merchandise Store","coupon":"SUMMER_FUN","discount":"2.22","item_brand":"Google","item_category":"Apparel","item_category2":"Adult","item_category3":"Shirts","item_category4":"Crew","item_category5":"Short sleeve","item_id":"SKU_12345","item_list_id":"related_products","item_list_name":"Related Products","item_name":"Stan and Friends Tee","item_variant":"green","item_list_position":"0","location_id":"ChIJIQBpAG2ahYAR_6128GcTUEo","price":"10.01","quantity":"3"}]},"client_hints":{"screen_resolution":"3840x1600","user_language":"en-us","user_agent_architecture":"arm","user_agent_bitness":"64","user_agent_full_version_list":"Chromium;124.0.6367.119|Google%20Chrome;124.0.6367.119|Not-A.Brand;99.0.0.0","user_agent_mobile":"0","user_agent_model":"","user_agent_platform":"macOS","user_agent_platform_version":"14.4.1","user_agent_wow_64":"0","user_region":""},"protocol_version":"2","tracking_id":"G-F9XM71K45T","gtmhash_info":"45he4580v9184715813z89184708445za200","client_id":"179294588.1715353601","richsstsse":"","document_location":"https://sesamy.local.bestbytes.net/?gtm_debug=1715430402906","document_title":"Home","document_referrer":"https://tagassistant.google.com/","event_name":"select_item","event_parameter":{"enable_page_views":"false","item_list_id":"related_products","item_list_name":"Related products"},"session_id":"1715428762","non_personalized_ads":"1","sst":{"tft":"1715430403224", "ude":"0", "gcd":"13l3l3l2l1"}}`,
},
}
for _, tt := range tests {
Expand Down
49 changes: 33 additions & 16 deletions pkg/encoding/gtag/encode.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,35 +8,50 @@ import (
"sort"
"strings"

"github.com/mitchellh/mapstructure"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
)

func Encode(input *Payload) (url.Values, io.Reader, error) {
func Encode(payload *Payload) (url.Values, io.Reader, error) {
var richsstsse bool
// NOTE: `richsstsse` seems to be last parameter in the query to let's ensure it stays that way
if input.Richsstsse != nil {
if payload.Richsstsse != nil {
richsstsse = true
input.Richsstsse = nil
payload.Richsstsse = nil
}

remain := input.Remain
input.Remain = nil
remain := payload.Remain
payload.Remain = nil

data := Data{}
decoder, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{
Result: &data,
TagName: "gtag",
IgnoreUntaggedFields: true,
Squash: true,
})
var json = jsoniter.Config{
TagKey: "gtag",
EscapeHTML: false,
MarshalFloatWith6Digits: true, // will lose precession
ObjectFieldMustBeSimpleString: true, // do not unescape object field
}.Froze()

jsonBytes, err := json.Marshal(&payload)
if err != nil {
return nil, nil, errors.Wrap(err, "failed to weakly decode query")
return nil, nil, errors.Wrap(err, "failed to marshall payload")
}
if err := decoder.Decode(input); err != nil {
return nil, nil, errors.Wrap(err, "failed to weakly decode query")
if err := json.Unmarshal(jsonBytes, &data); err != nil {
return nil, nil, errors.Wrap(err, "failed to unmarshall payload")
}

// decoder, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{
// Result: &data,
// TagName: "gtag",
// IgnoreUntaggedFields: true,
// Squash: true,
// })
// if err != nil {
// return nil, nil, errors.Wrap(err, "failed to weakly decode query")
// }
// if err := decoder.Decode(payload); err != nil {
// return nil, nil, errors.Wrap(err, "failed to weakly decode query")
// }

for s, a := range remain {
data[s] = a
}
Expand Down Expand Up @@ -67,14 +82,16 @@ func Encode(input *Payload) (url.Values, io.Reader, error) {
ret[k] = []string{t}
case interface{ String() string }:
ret[k] = []string{t.String()}
case nil:
continue
default:
panic("unhandled")
}
}

var body []string
var reader io.Reader
maxQueryLength := 2048 //
maxQueryLength := 2048
if richsstsse {
maxQueryLength -= len("&richsstsse")
}
Expand Down
27 changes: 16 additions & 11 deletions pkg/encoding/gtag/encode_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,39 +4,44 @@ import (
"net/url"
"testing"

testingx "github.com/foomo/go/testing"
tagx "github.com/foomo/go/testing/tag"
"github.com/foomo/sesamy-go/pkg/encoding/gtag"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

func TestEncode(t *testing.T) {
testingx.Tags(t, tagx.Short)

tests := []struct {
name string
args string
want error
}{
{
name: "page_view",
args: "v=2&tid=G-123456&gtm=45je42s0v893689383z8894072534za200&_p=1709286636310&gcd=13l3l3l3l1&npa=0&dma_cps=sypham&dma=1&cid=292234677.1707898933&ul=en-us&sr=3840x1600&uaa=arm&uab=64&uafvl=Chromium&uamb=0&uam=&uap=macOS&uapv=14.3.1&uaw=0&are=1&pae=1&pscdl=noapi&_s=1&sid=1709286452&sct=7&seg=1&dl=https%3A%2F%2Fwww.homemade.ch%2Fprodukt%2Fkuhn-rikon-wiegemesser-900047100%3Fid%3D900047100&dr=https%3A%2F%2Fwww.homemade.ch%2Fmesser-besteck&dt=Wiegemesser&en=page_view&tfd=5682",
want: nil,
},
// {
// name: "add_to_cart",
// args: "v=2&tid=G-123456&gtm=45je42s0v9175354889z89175348963za200&_p=1709297934217&_dbg=1&gcd=13l3l3l3l1&npa=0&dma_cps=sypham&dma=1&cid=1220643501.1708014725&ul=en-us&sr=3840x1600&_fplc=0&ur=DE-BY&uaa=arm&uab=64&uafvl=Chromium&uamb=0&uam=&uap=macOS&uapv=14.3.1&uaw=0&are=1&pscdl=noapi&_eu=IA&sst.uc=DE&sst.etld=google.de&sst.gcsub=region1&sst.gcd=13l3l3l3l1&sst.tft=1709297934217&_s=8&cu=USD&sid=1709296380&sct=7&seg=1&dl=https%3A%2F%2Fsniffer.cloud.bestbytes.net%2F%3Fgtm_debug%3D1709297933868&dr=https%3A%2F%2Ftagassistant.google.com%2F&dt=Server%20Side%20Tracking%20Prototype%20(codename%3A%20sniffer)&en=add_to_cart&pr1=idSKU_12345~nmStan%20and%20Friends%20Tee~afGoogle%20Store~cpSUMMER_FUN~ds2.22~lp5~brGoogle~caApparel~c2Adult~c3Shirts~c4Crew~c5Short%20sleeve~lirelated_products~lnRelated%20products~vagreen~loChIJIQBpAG2ahYAR_6128GcTUEo~pr10.01~qt3&epn.value=30.03&tfd=15129&richsstsse",
// want: nil,
// },
{
name: "select_item",
args: "v=2&tid=G-F9XM71K45T&gtm=45he45k0v9184715813z89184708445za200zb9184708445&_p=1716358119533&_dbg=1&gcd=13l3l3l2l1&npa=1&dma_cps=sypham&dma=1&cid=179294588.1715353601&ecid=666528402&ul=en-us&sr=3840x1600&_fplc=0&ur=&uaa=arm&uab=64&uafvl=Chromium%3B124.0.6367.201%7CGoogle%2520Chrome%3B124.0.6367.201%7CNot-A.Brand%3B99.0.0.0&uamb=0&uam=&uap=macOS&uapv=14.4.1&uaw=0&are=1&frm=0&pscdl=noapi&sst.gcd=13l3l3l2l1&sst.tft=1716358119533&sst.ude=0&_s=5&sid=1716358118&sct=10&seg=1&dl=https%3A%2F%2Fsesamy.local.bestbytes.net%2F%3Fgtm_debug%3D1716352834644&dr=https%3A%2F%2Fsesamy.local.bestbytes.net%2F%3Fgtm_debug%3D1716352834644&dt=Home&en=select_item&pr1=idSKU_12345~nmStan%20and%20Friends%20Tee~afGoogle%20Merchandise%20Store~cpSUMMER_FUN~ds2.22~lp0~brGoogle~caApparel~c2Adult~c3Shirts~c4Crew~c5Short%20sleeve~lirelated_products~lnRelated%20Products~vagreen~loChIJIQBpAG2ahYAR_6128GcTUEo~pr10.01~qt3&ep.enable_page_views=false&ep.item_list_id=related_products&ep.item_list_name=Related%20products&_et=9888&tfd=38911&richsstsse",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
u, err := url.ParseQuery(tt.args)
// x, err := url.QueryUnescape(tt.args)
values, err := url.ParseQuery(tt.args)
require.NoError(t, err)
var event gtag.Payload

require.NoError(t, gtag.Decode(u, &event))
require.NoError(t, gtag.Decode(values, &event))
assert.NotEmpty(t, event.Remain)

if out, _, err := gtag.Encode(&event); assert.NoError(t, err) {
assert.EqualValues(t, u, out)
if actual, _, err := gtag.Encode(&event); assert.NoError(t, err) {
if assert.Len(t, actual.Encode(), len(values.Encode())) {
t.Logf("expected: %s", values.Encode())
t.Logf("actual: %s", actual.Encode())
}
}
})
}
Expand Down
10 changes: 5 additions & 5 deletions pkg/encoding/gtag/payload.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ import (

// Payload https://www.thyngster.com/ga4-measurement-protocol-cheatsheet/
type Payload struct {
Consent `json:"consent" gtag:",squash"`
Campaign `json:"campaign" gtag:",squash"`
ECommerce `json:"ecommerce" gtag:",squash"`
ClientHints `json:"client_hints" gtag:",squash"`
Consent `json:"consent" gtag:",inline,squash"`
Campaign `json:"campaign" gtag:",inline,squash"`
ECommerce `json:"ecommerce" gtag:",inline,squash"`
ClientHints `json:"client_hints" gtag:",inline,squash"`

// --- Request parameters ---

Expand Down Expand Up @@ -164,5 +164,5 @@ type Payload struct {

// --- Unresolved ---

Remain map[string]any `json:"-" gtag:",remain"`
Remain map[string]any `json:"-" gtag:"-,omitempy,remain"`
}
2 changes: 2 additions & 0 deletions pkg/encoding/gtag/sst.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,6 @@ type SST struct {
TFT *string `json:"tft,omitempty" gtag:"tft,omitempty"`
// Example: 13l3l3l3l1
GCD *string `json:"gcd,omitempty" gtag:"gcd,omitempty"`
// Example: 0
UDE *string `json:"ude,omitempty" gtag:"ude,omitempty"`
}

0 comments on commit a774684

Please sign in to comment.