Skip to content

Commit

Permalink
Merge pull request #88 from foomo/v0.12.0
Browse files Browse the repository at this point in the history
V0.12.0
  • Loading branch information
franklinkim authored Feb 17, 2025
2 parents 75182bc + 618fa68 commit 7a58d31
Show file tree
Hide file tree
Showing 17 changed files with 402 additions and 174 deletions.
9 changes: 5 additions & 4 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ linters:
- asciicheck # checks that all code identifiers does not have non-ASCII symbols in the name [fast: true, auto-fix: false]
- bidichk # Checks for dangerous unicode character sequences [fast: true, auto-fix: false]
- bodyclose # checks whether HTTP response body is closed successfully [fast: false, auto-fix: false]
- canonicalheader # Checks whether net/http.Header uses canonical header [fast: false, auto-fix: false]
- containedctx # containedctx is a linter that detects struct contained context.Context field [fast: false, auto-fix: false]
- contextcheck # check whether the function uses a non-inherited context [fast: false, auto-fix: false]
- copyloopvar # (go >= 1.22) copyloopvar is a linter detects places where loop variables are copied [fast: true, auto-fix: false]
Expand All @@ -117,6 +118,7 @@ linters:
- errname # Checks that sentinel errors are prefixed with the `Err` and error types are suffixed with the `Error`. [fast: false, auto-fix: false]
- errorlint # errorlint is a linter for that can be used to find code that will cause problems with the error wrapping scheme introduced in Go 1.13. [fast: false, auto-fix: false]
- exhaustive # check exhaustiveness of enum switch statements [fast: false, auto-fix: false]
- fatcontext #Detects nested contexts in loops [fast: false, auto-fix: false]
#- forbidigo # Forbids identifiers [fast: false, auto-fix: false]
- forcetypeassert # finds forced type assertions [fast: true, auto-fix: false]
- gocheckcompilerdirectives # Checks that go compiler directive comments (//go:) are valid. [fast: true, auto-fix: false]
Expand All @@ -137,11 +139,12 @@ linters:
- intrange # (go >= 1.22) intrange is a linter to find places where for loops could make use of an integer range. [fast: true, auto-fix: false]
- loggercheck # (logrlint) Checks key value pairs for common logger libraries (kitlog,klog,logr,zap). [fast: false, auto-fix: false]
- makezero # Finds slice declarations with non-zero initial length [fast: false, auto-fix: false]
- misspell # Finds commonly misspelled English words [fast: true, auto-fix: true]
- mirror # reports wrong mirror patterns of bytes/strings usage [fast: false, auto-fix: true]
- misspell # Finds commonly misspelled English words [fast: true, auto-fix: true]
- musttag # enforce field tags in (un)marshaled structs [fast: false, auto-fix: false]
- nakedret # Checks that functions with naked returns are not longer than a maximum size (can be zero). [fast: true, auto-fix: false]
- nilerr # Finds the code that returns nil even if it checks that the error is not nil. [fast: false, auto-fix: false]
- nilnesserr # Reports constructs that checks for err != nil, but returns a different nil value error.
- nilnil # Checks that there is no simultaneous return of `nil` error and an invalid value. [fast: false, auto-fix: false]
- noctx # Finds sending http request without context.Context [fast: false, auto-fix: false]
- nolintlint # Reports ill-formed or insufficient nolint directives [fast: true, auto-fix: true]
Expand All @@ -156,7 +159,6 @@ linters:
- spancheck # Checks for mistakes with OpenTelemetry/Census spans. [fast: false, auto-fix: false]
- sqlclosecheck # Checks that sql.Rows, sql.Stmt, sqlx.NamedStmt, pgx.Query are closed. [fast: false, auto-fix: false]
- stylecheck # Stylecheck is a replacement for golint [fast: false, auto-fix: false]
- tenv # tenv is analyzer that detects using os.Setenv instead of t.Setenv since Go1.17 [fast: false, auto-fix: false]
- testableexamples # linter checks if examples are testable (have an expected output) [fast: true, auto-fix: false]
- testifylint # Checks usage of github.com/stretchr/testify. [fast: false, auto-fix: false]
- testpackage # linter that makes you use a separate _test package [fast: true, auto-fix: false]
Expand All @@ -166,8 +168,6 @@ linters:
- usestdlibvars # A linter that detect the possibility to use variables/constants from the Go standard library. [fast: true, auto-fix: false]
- wastedassign # Finds wasted assignment statements [fast: false, auto-fix: false]
- whitespace # Whitespace is a linter that checks for unnecessary newlines at the start and end of functions, if, for, etc. [fast: true, auto-fix: true]
- canonicalheader # Checks whether net/http.Header uses canonical header [fast: false, auto-fix: false]
- fatcontext #Detects nested contexts in loops [fast: false, auto-fix: false]

## Don't enable
#- cyclop # checks function and package cyclomatic complexity [fast: false, auto-fix: false]
Expand All @@ -177,6 +177,7 @@ linters:
#- dogsled # Checks assignments with too many blank identifiers (e.g. x, _, _, _, := f()) [fast: true, auto-fix: false]
#- err113 # Go linter to check the errors handling expressions [fast: false, auto-fix: false]
#- exhaustruct # Checks if all structure fields are initialized [fast: false, auto-fix: false]
#- exptostd # Detects functions from golang.org/x/exp/ that can be replaced by std functions. [auto-fix]
#- gci # Gci controls Go package import order and makes it always deterministic. [fast: true, auto-fix: true]
#- gochecknoglobals # Check that no global variables exist. [fast: false, auto-fix: false]
#- gochecknoinits # Checks that no init functions are present in Go code [fast: true, auto-fix: false]
Expand Down
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ require (
github.com/fatih/structtag v1.2.0
github.com/foomo/go v0.0.3
github.com/foomo/gocontemplate v0.1.4
github.com/foomo/sesamy-go v0.8.0
github.com/foomo/sesamy-go v0.8.1
github.com/invopop/jsonschema v0.13.0
github.com/joho/godotenv v1.5.1
github.com/mitchellh/hashstructure/v2 v2.0.2
github.com/mitchellh/mapstructure v1.5.0
github.com/mitchellh/mapstructure v1.5.1-0.20220423185008-bf980b35cac4
github.com/pkg/errors v0.9.1
github.com/pterm/pterm v0.12.80
github.com/spf13/cobra v1.9.0
Expand Down
12 changes: 6 additions & 6 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@ github.com/foomo/gocontemplate v0.1.4 h1:MYSsoltno9pNMU5NwALd7PNSQ1XjN1tpqMGWAhC
github.com/foomo/gocontemplate v0.1.4/go.mod h1:BH8eODDwlqWhasSl86avbtMN3Zfgt4pWwr8/PBPM5v0=
github.com/foomo/gostandards v0.2.0 h1:Ryd7TI9yV3Xk5B84DcUDB7KcL3LzQ8NS+TVOrFxTYfA=
github.com/foomo/gostandards v0.2.0/go.mod h1:XQx7Ur6vyvxaIe2cQvAthuhPYDe+d2soibqVcXDXOh4=
github.com/foomo/sesamy-go v0.8.0 h1:o3zfJ6/FDpBpy/+fGihiQrePLUWwe34zK4iTa5OlHQU=
github.com/foomo/sesamy-go v0.8.0/go.mod h1:P1EKsMhG8kAPmxeGCACorY4lfDzIaAgCWw9FVi6r3+Y=
github.com/foomo/sesamy-go v0.8.1 h1:5m1ySZB5gW9Dymz8MFggU8DXs7F1AAcV6WW2ieX9DPI=
github.com/foomo/sesamy-go v0.8.1/go.mod h1:9TlGLPABYmjt/louonKy4Na4nmx9RHq7N9KyZ6Sy7Xw=
github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
github.com/fsnotify/fsnotify v1.8.0 h1:dAwr6QBTBZIkG8roQaJjGof0pp0EeF+tNV7YBP3F/8M=
Expand Down Expand Up @@ -102,8 +102,8 @@ github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6T
github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/mitchellh/hashstructure/v2 v2.0.2 h1:vGKWl0YJqUNxE8d+h8f6NJLcCJrgbhC4NcD46KavDd4=
github.com/mitchellh/hashstructure/v2 v2.0.2/go.mod h1:MG3aRVU/N29oo/V/IhBX8GR/zz4kQkprJgF2EVszyDE=
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/mitchellh/mapstructure v1.5.1-0.20220423185008-bf980b35cac4 h1:BpfhmLKZf+SjVanKKhCgf3bg+511DmU9eDQTen7LLbY=
github.com/mitchellh/mapstructure v1.5.1-0.20220423185008-bf980b35cac4/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/pelletier/go-toml/v2 v2.2.3 h1:YmeHyLY8mFWbdkNWwpr+qIL2bEqT0o95WSdkNHvL12M=
github.com/pelletier/go-toml/v2 v2.2.3/go.mod h1:MfCQTFTvCcUyyvvwm1+G6H/jORL20Xlb6rzQu9GuUkc=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
Expand Down Expand Up @@ -243,8 +243,8 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T
google.golang.org/api v0.221.0 h1:qzaJfLhDsbMeFee8zBRdt/Nc+xmOuafD/dbdgGfutOU=
google.golang.org/api v0.221.0/go.mod h1:7sOU2+TL4TxUTdbi0gWgAIg7tH5qBXxoyhtL+9x3biQ=
google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9 h1:9+tzLLstTlPTRyJTh+ah5wIMsBW5c4tQwGTN3thOW9Y=
google.golang.org/genproto/googleapis/api v0.0.0-20241209162323-e6fa225c2576 h1:CkkIfIt50+lT6NHAVoRYEyAvQGFM7xEwXUUywFvEb3Q=
google.golang.org/genproto/googleapis/api v0.0.0-20241209162323-e6fa225c2576/go.mod h1:1R3kvZ1dtP3+4p4d3G8uJ8rFk/fWlScl38vanWACI08=
google.golang.org/genproto/googleapis/api v0.0.0-20250115164207-1a7da9e5054f h1:gap6+3Gk41EItBuyi4XX/bp4oqJ3UwuIMl25yGinuAA=
google.golang.org/genproto/googleapis/api v0.0.0-20250115164207-1a7da9e5054f/go.mod h1:Ic02D47M+zbarjYYUlK57y316f2MoN0gjAwI3f2S95o=
google.golang.org/genproto/googleapis/rpc v0.0.0-20250207221924-e9438ea467c6 h1:2duwAxN2+k0xLNpjnHTXoMUgnv6VPSp5fiqTuwSxjmI=
google.golang.org/genproto/googleapis/rpc v0.0.0-20250207221924-e9438ea467c6/go.mod h1:8BS3B93F/U1juMFq9+EDk+qOT5CO1R9IzXxG3PTqiRk=
google.golang.org/grpc v1.70.0 h1:pWFv03aZoHzlRKHWicjsZytKAiYCtNS0dHbXnIdq7jQ=
Expand Down
4 changes: 4 additions & 0 deletions pkg/config/emarsys.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ type Emarsys struct {
Enabled bool `json:"enabled" yaml:"enabled"`
// Emarsys merchant id
MerchantID string `json:"merchantId" yaml:"merchantId"`
// Enable test mode
TestMode bool `json:"testMode" yaml:"testMode"`
// Enable debug mode
DebugMode bool `json:"debugMode" yaml:"debugMode"`
// Google Consent settings
GoogleConsent GoogleConsent `json:"googleConsent" yaml:"googleConsent"`
// Google Tag Manager web container settings
Expand Down
2 changes: 2 additions & 0 deletions pkg/config/googletag.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ type GoogleTag struct {
TagID string `json:"tagId" yaml:"tagId"`
// Whether a page_view should be sent on initial load
SendPageView bool `json:"sendPageView" yaml:"sendPageView"`
// Data layer variables to be added to the event settings
DataLayerVariables map[string]string `json:"dataLayerVariables" yaml:"dataLayerVariables"`
// TypeScript settings
TypeScript TypeScript `json:"typeScript" yaml:"typeScript"`
}
127 changes: 127 additions & 0 deletions pkg/provider/emarsys/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
# Emarsys Web Extend

The emarsys server side web extend provider makes use of the [Web Extend Command](https://dev.emarsys.com/docs/web-extend-reference/a1a185e5fbb6b-web-extend-command-implementation).

## Initialization

Since we need to trigger multiple commands, we need to ensure we're always sending the same `sessionId`, `visitorId` & `pageViewId` for all calls.
The initialization sets the `emarsys.page_view_id` variable into the `dataLayer` to be sent with each following request.

```mermaid
sequenceDiagram
participant Data Layer
participant Web Container
participant Server Container
participant Emarsys
Web Container->>+Server Container: initialization (/gtag/js/emarsys)
Server Container->>Emarsys: pageViewId (sesssionId, visitorId)
Server Container->>-Web Container: Cookies (emarsys_cdv, emarsys_s)
Web Container->>Data Layer: emarsys.page_view_id
```

## Commands

### Cart

NOTE: The default `page_view` event does not contain the `items` so we need to enrich them in the `collect` service.

```mermaid
sequenceDiagram
participant Web Container
participant Collect
participant Server Container
participant Emarsys
Web Container->>Collect: page_view
Collect->>+Server Container: enrich: items
Server Container->>Emarsys: cart<br/>Cookies (s, cdv, xp, fc)
Server Container->>-Web Container: Cookies (s, cdv, xp, fc)
```

Standard implementation

```javascript
// The usual commands to identify visitors and report cart contents.
ScarabQueue.push(['cart', [
{item: 'item_1', price: 19.9, quantity: 1},
{item: 'item_2', price: 29.7, quantity: 3}
]]);
// Firing the ScarabQueue. Should be the last call on the page, called only once.
ScarabQueue.push(['go']);
```

### View

```mermaid
sequenceDiagram
participant Web Container
participant Server Container
participant Emarsys
Web Container->>+Server Container: view_item
Server Container->>Emarsys: view<br/>Cookies (s, cdv, xp, fc)
Server Container->>-Web Container: Cookies (s, cdv, xp, fc)
```

Standard implementation

```javascript
// Passing on item ID to report product view. Item ID should match the value listed in the Product Catalog
ScarabQueue.push(['view', 'item_3']);
// Firing the ScarabQueue. Should be the last call on the page, called only once.
ScarabQueue.push(['go']);
```

## Category

```mermaid
sequenceDiagram
participant Web Container
participant Server Container
participant Emarsys
Web Container->>+Server Container: view_item_list
Server Container->>Emarsys: category<br/>Cookies (s, cdv, xp, fc)
Server Container->>-Web Container: Cookies (s, cdv, xp, fc)
```

Standard implementation

```javascript
// Passing on the category path being visited. Must match the 'category' values listed in the Product Catalog
ScarabQueue.push(['category', 'Bikes > Road Bikes']);
// Firing the ScarabQueue. Should be the last call on the page, called only once.
ScarabQueue.push(['go']);
```

## Purchase

```mermaid
sequenceDiagram
participant Web Container
participant Server Container
participant Emarsys
Web Container->>+Server Container: purchase
Server Container->>Emarsys: category<br/>Cookies (s, cdv, xp, fc)
Server Container->>-Web Container: Cookies (s, cdv, xp, fc)
```

Standard implementation

```javascript
// Passing on order details. The price values passed on here serve as the basis of our revenue and revenue contribution reports.
ScarabQueue.push(['purchase', {
orderId: '231213',
items: [
{item: 'item_1', price: 19.9, quantity: 1},
{item: 'item_2', price: 29.7, quantity: 3}
]
}]);
// Firing the ScarabQueue. Should be the last call on the page, called only once.
ScarabQueue.push(['go']);
```

## References

- [Web Extend Command](https://dev.emarsys.com/docs/web-extend-reference/a1a185e5fbb6b-web-extend-command-implementationhttps://dev.emarsys.com/docs/web-extend-reference/a1a185e5fbb6b-web-extend-command-implementation)
2 changes: 1 addition & 1 deletion pkg/provider/emarsys/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ func Server(l *slog.Logger, tm *tagmanager.TagManager, cfg config.Emarsys) error
return errors.Wrap(err, "failed to upsert event trigger: "+event)
}

if _, err := tm.UpsertTag(servertagx.NewEmarsys(event, merchantID, tagTemplate, eventTrigger)); err != nil {
if _, err := tm.UpsertTag(servertagx.NewEmarsys(event, merchantID, cfg.TestMode, cfg.DebugMode, tagTemplate, eventTrigger)); err != nil {
return err
}
}
Expand Down
8 changes: 5 additions & 3 deletions pkg/provider/emarsys/server/tag/emarsys.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package tag

import (
"strconv"

"github.com/foomo/sesamy-cli/pkg/utils"
"google.golang.org/api/tagmanager/v2"
)
Expand All @@ -9,7 +11,7 @@ func EmarsysName(v string) string {
return "Emarsys - " + v
}

func NewEmarsys(name string, merchantID *tagmanager.Variable, template *tagmanager.CustomTemplate, triggers ...*tagmanager.Trigger) *tagmanager.Tag {
func NewEmarsys(name string, merchantID *tagmanager.Variable, testMode, debugMode bool, template *tagmanager.CustomTemplate, triggers ...*tagmanager.Trigger) *tagmanager.Tag {
return &tagmanager.Tag{
FiringTriggerId: utils.TriggerIDs(triggers),
Name: EmarsysName(name),
Expand All @@ -28,12 +30,12 @@ func NewEmarsys(name string, merchantID *tagmanager.Variable, template *tagmanag
{
Key: "isTestMode",
Type: "boolean",
Value: "false",
Value: strconv.FormatBool(testMode),
},
{
Key: "isDebugMode",
Type: "boolean",
Value: "false",
Value: strconv.FormatBool(debugMode),
},
},
Type: utils.TemplateType(template),
Expand Down
Loading

0 comments on commit 7a58d31

Please sign in to comment.