From c67e4d48986ab5d5d7b40c104b453c1f5497b82e Mon Sep 17 00:00:00 2001 From: Kevin Franklin Kim Date: Wed, 12 Feb 2025 11:24:53 +0100 Subject: [PATCH 1/2] feat: add enable geo resolution --- README.md | 21 +++--- cmd/tagmanager/server.go | 11 ++- cmd/tagmanager/web.go | 2 +- pkg/config/config.go | 3 + pkg/config/googleanalytics.go | 10 +-- pkg/config/googleanalyticsgtagjsoverride.go | 10 +++ pkg/config/googlegtag.go | 8 --- pkg/config/googletag.go | 2 - pkg/provider/googleanalytics/server.go | 24 +++++-- .../server/client/googleanalyticsga4.go | 67 +++++++++++++++++++ .../server/client/googlegtag.go | 2 +- .../server/client/measurementprotocolga4.go | 0 .../template/googleconsentmodecheckdata.go | 43 ++++++++---- pkg/provider/googletag/constants.go | 11 +-- pkg/provider/googletag/server.go | 25 +++++++ pkg/provider/googletag/web.go | 3 - pkg/provider/googletagmanager/constants.go | 1 + pkg/provider/googletagmanager/server.go | 12 +++- .../client/googletagmanagerwebcontainer.go | 19 ++++-- .../server/variable/visitorregion.go | 19 ++++++ .../server/client/googleanalyticsga4.go | 29 -------- sesamy.schema.json | 40 ++++++----- sesamy.yaml | 21 +++--- 23 files changed, 263 insertions(+), 120 deletions(-) create mode 100644 pkg/config/googleanalyticsgtagjsoverride.go delete mode 100644 pkg/config/googlegtag.go create mode 100644 pkg/provider/googleanalytics/server/client/googleanalyticsga4.go rename pkg/{tagmanager => provider/googleanalytics}/server/client/measurementprotocolga4.go (100%) create mode 100644 pkg/provider/googletag/server.go rename pkg/{tagmanager => provider/googletagmanager}/server/client/googletagmanagerwebcontainer.go (69%) create mode 100644 pkg/provider/googletagmanager/server/variable/visitorregion.go delete mode 100644 pkg/tagmanager/server/client/googleanalyticsga4.go diff --git a/README.md b/README.md index 33832db..1ed023a 100644 --- a/README.md +++ b/README.md @@ -55,6 +55,9 @@ version: '1.0' # Whether to redact the visitor ip redactVisitorIp: true +# Enable region specific settings +# https://developers.google.com/tag-platform/tag-manager/server-side/enable-region-specific-settings +enableGeoResolution: true # --- Google API settings googleApi: @@ -90,8 +93,6 @@ googleTagManager: googleTag: # A tag ID is an identifier that you put on your page to load a given Google tag tagId: G-PZ5ELRCR31 - # Enable debug mode for all user devices - debugMode: false # Whether a page_view should be sent on initial load sendPageView: true # TypeScript settings @@ -163,20 +164,20 @@ googleTag: googleAnalytics: # Enable provider enabled: true - # Google GTag.js settings - googleGTag: - # Provision custom client - enabled: true - # Client priority - priority: 10 - # Patch ecommerce items - ecommerceItems: true # Google Consent settings googleConsent: # Enable consent mode enabled: true # Consent mode name mode: analytics_storage + # Google GTag.js override settings + googleGTagJSOverride: + # Provision custom client + enabled: true + # Client priority + priority: 10 + # Patch ecommerce items + ecommerceItems: true # Google Tag Manager web container settings webContainer: # Contemplate package config for generated events diff --git a/cmd/tagmanager/server.go b/cmd/tagmanager/server.go index aea20c2..b83bbb4 100644 --- a/cmd/tagmanager/server.go +++ b/cmd/tagmanager/server.go @@ -8,6 +8,7 @@ import ( facebookprovider "github.com/foomo/sesamy-cli/pkg/provider/facebook" googleadsprovider "github.com/foomo/sesamy-cli/pkg/provider/googleads" googleanalyticsprovider "github.com/foomo/sesamy-cli/pkg/provider/googleanalytics" + googletagprovider "github.com/foomo/sesamy-cli/pkg/provider/googletag" googletagmanagerprovider "github.com/foomo/sesamy-cli/pkg/provider/googletagmanager" microsoftadsprovider "github.com/foomo/sesamy-cli/pkg/provider/microsoftads" tracifyprovider "github.com/foomo/sesamy-cli/pkg/provider/tracify" @@ -48,15 +49,21 @@ func NewServer(root *cobra.Command) { return err } + if pkgcmd.Tag(googletagprovider.Tag, tags) { + if err := googletagprovider.Server(tm, cfg.GoogleTag); err != nil { + return errors.Wrap(err, "failed to provision google tag provider") + } + } + if pkgcmd.Tag(googletagmanagerprovider.Tag, tags) { - if err := googletagmanagerprovider.Server(tm, cfg.GoogleTagManager); err != nil { + if err := googletagmanagerprovider.Server(tm, cfg.GoogleTagManager, cfg.EnableGeoResolution); err != nil { return errors.Wrap(err, "failed to provision google tag manager") } } if cfg.GoogleAnalytics.Enabled && pkgcmd.Tag(googleanalyticsprovider.Tag, tags) { l.Info("🅿️ Running provider", "name", googleanalyticsprovider.Name, "tag", googleanalyticsprovider.Tag) - if err := googleanalyticsprovider.Server(tm, cfg.GoogleAnalytics, cfg.RedactVisitorIP); err != nil { + if err := googleanalyticsprovider.Server(tm, cfg.GoogleAnalytics, cfg.RedactVisitorIP, cfg.EnableGeoResolution); err != nil { return errors.Wrap(err, "failed to provision google analytics") } } diff --git a/cmd/tagmanager/web.go b/cmd/tagmanager/web.go index 00a10d6..b1c2694 100644 --- a/cmd/tagmanager/web.go +++ b/cmd/tagmanager/web.go @@ -46,7 +46,7 @@ func NewWeb(root *cobra.Command) { if pkgcmd.Tag(googletagprovider.Tag, tags) { if err := googletagprovider.Web(tm, cfg.GoogleTag); err != nil { - return errors.Wrap(err, "failed to provision google provider") + return errors.Wrap(err, "failed to provision google tag provider") } } diff --git a/pkg/config/config.go b/pkg/config/config.go index 5352827..cd7729f 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -5,6 +5,9 @@ type Config struct { Version string `json:"version" yaml:"version" jsonschema:"required"` // Globally redact visitor ip RedactVisitorIP bool `json:"redactVisitorIp" yaml:"redactVisitorIp"` + // Enable region specific settings + // https://developers.google.com/tag-platform/tag-manager/server-side/enable-region-specific-settings + EnableGeoResolution bool `json:"enableGeoResolution" yaml:"enableGeoResolution"` // Google Tag settings GoogleTag GoogleTag `json:"googleTag" yaml:"googleTag"` // Google API settings diff --git a/pkg/config/googleanalytics.go b/pkg/config/googleanalytics.go index beaabf9..2ef63bd 100644 --- a/pkg/config/googleanalytics.go +++ b/pkg/config/googleanalytics.go @@ -6,11 +6,13 @@ import ( type GoogleAnalytics struct { // Enable provider - Enabled bool `json:"enabled" yaml:"enabled"` - GoogleGTag GoogleGTag `json:"googleGTag" yaml:"googleGTag"` + Enabled bool `json:"enabled" yaml:"enabled"` // Google Consent settings - GoogleConsent GoogleConsent `json:"googleConsent" yaml:"googleConsent"` - WebContainer contemplate.Config `json:"webContainer" yaml:"webContainer"` + GoogleConsent GoogleConsent `json:"googleConsent" yaml:"googleConsent"` + // GTag.js override configuration + GoogleGTagJSOverride GoogleAnalyticsGTagJSOverride `json:"googleGTagJSOverride" yaml:"googleGTagJSOverride"` + // Google Tag Manager web container settings + WebContainer contemplate.Config `json:"webContainer" yaml:"webContainer"` // Google Tag Manager server container settings ServerContainer contemplate.Config `json:"serverContainer" yaml:"serverContainer"` } diff --git a/pkg/config/googleanalyticsgtagjsoverride.go b/pkg/config/googleanalyticsgtagjsoverride.go new file mode 100644 index 0000000..7efeeb6 --- /dev/null +++ b/pkg/config/googleanalyticsgtagjsoverride.go @@ -0,0 +1,10 @@ +package config + +type GoogleAnalyticsGTagJSOverride struct { + // Enable override + Enabled bool `json:"enabled" yaml:"enabled"` + // Client priority + Priority int64 `json:"priority" yaml:"priority"` + // Allow sending items for non ecommerce events + EcommerceItems bool `json:"ecommerceItems" yaml:"ecommerceItems"` +} diff --git a/pkg/config/googlegtag.go b/pkg/config/googlegtag.go deleted file mode 100644 index 3abc9dd..0000000 --- a/pkg/config/googlegtag.go +++ /dev/null @@ -1,8 +0,0 @@ -package config - -type GoogleGTag struct { - // Enable provider - Enabled bool `json:"enabled" yaml:"enabled"` - Priority int64 `json:"priority" yaml:"priority"` - EcommerceItems bool `json:"ecommerceItems" yaml:"ecommerceItems"` -} diff --git a/pkg/config/googletag.go b/pkg/config/googletag.go index 280562e..429c3ed 100644 --- a/pkg/config/googletag.go +++ b/pkg/config/googletag.go @@ -3,8 +3,6 @@ package config type GoogleTag struct { // A tag ID is an identifier that you put on your page to load a given Google tag TagID string `json:"tagId" yaml:"tagId"` - // Enable debug mode for all user devices - DebugMode bool `json:"debugMode" yaml:"debugMode"` // Whether a page_view should be sent on initial load SendPageView bool `json:"sendPageView" yaml:"sendPageView"` // TypeScript settings diff --git a/pkg/provider/googleanalytics/server.go b/pkg/provider/googleanalytics/server.go index ca15448..88ea1a1 100644 --- a/pkg/provider/googleanalytics/server.go +++ b/pkg/provider/googleanalytics/server.go @@ -8,8 +8,9 @@ import ( "github.com/foomo/sesamy-cli/pkg/provider/googleanalytics/server/trigger" "github.com/foomo/sesamy-cli/pkg/provider/googleconsent" googleconsentvariable "github.com/foomo/sesamy-cli/pkg/provider/googleconsent/server/variable" + "github.com/foomo/sesamy-cli/pkg/provider/googletag" + "github.com/foomo/sesamy-cli/pkg/provider/googletagmanager" "github.com/foomo/sesamy-cli/pkg/tagmanager" - serverclient "github.com/foomo/sesamy-cli/pkg/tagmanager/server/client" servertemplate "github.com/foomo/sesamy-cli/pkg/tagmanager/server/template" servertransformation "github.com/foomo/sesamy-cli/pkg/tagmanager/server/transformation" servertrigger "github.com/foomo/sesamy-cli/pkg/tagmanager/server/trigger" @@ -18,7 +19,7 @@ import ( "github.com/pkg/errors" ) -func Server(tm *tagmanager.TagManager, cfg config.GoogleAnalytics, redactVisitorIP bool) error { +func Server(tm *tagmanager.TagManager, cfg config.GoogleAnalytics, redactVisitorIP, enableGeoResolution bool) error { { // create folder if folder, err := tm.UpsertFolder("Sesamy - " + Name); err != nil { return err @@ -29,17 +30,28 @@ func Server(tm *tagmanager.TagManager, cfg config.GoogleAnalytics, redactVisitor { // create clients { - client, err := tm.UpsertClient(serverclient.NewGoogleAnalyticsGA4(NameGoogleAnalyticsGA4Client)) + measurementID, err := tm.LookupVariable(googletag.NameGoogleTagMeasurementID) if err != nil { return err } + + visitorRegion, err := tm.LookupVariable(googletagmanager.NameGoogleTagManagerVisitorRegion) + if err != nil { + return err + } + + client, err := tm.UpsertClient(googleanalyticsclient.NewGoogleAnalyticsGA4(NameGoogleAnalyticsGA4Client, enableGeoResolution, visitorRegion, measurementID)) + if err != nil { + return err + } + if _, err = tm.UpsertTrigger(servertrigger.NewClient(NameGoogleAnalyticsGA4ClientTrigger, client)); err != nil { return err } } { - client, err := tm.UpsertClient(serverclient.NewMeasurementProtocolGA4(NameMeasurementProtocolGA4Client)) + client, err := tm.UpsertClient(googleanalyticsclient.NewMeasurementProtocolGA4(NameMeasurementProtocolGA4Client)) if err != nil { return err } @@ -63,13 +75,13 @@ func Server(tm *tagmanager.TagManager, cfg config.GoogleAnalytics, redactVisitor } } - if cfg.GoogleGTag.Enabled { + if cfg.GoogleGTagJSOverride.Enabled { template, err := tm.UpsertCustomTemplate(googleanalyticstemplate.NewGoogleGTagClient(NameGoogleGTagClientTemplate)) if err != nil { return err } - _, err = tm.UpsertClient(googleanalyticsclient.NewGoogleGTag(NameGoogleGTagClient, cfg.GoogleGTag, template)) + _, err = tm.UpsertClient(googleanalyticsclient.NewGoogleGTag(NameGoogleGTagClient, cfg.GoogleGTagJSOverride, template)) if err != nil { return err } diff --git a/pkg/provider/googleanalytics/server/client/googleanalyticsga4.go b/pkg/provider/googleanalytics/server/client/googleanalyticsga4.go new file mode 100644 index 0000000..49e5df7 --- /dev/null +++ b/pkg/provider/googleanalytics/server/client/googleanalyticsga4.go @@ -0,0 +1,67 @@ +package client + +import ( + "strconv" + + "google.golang.org/api/tagmanager/v2" +) + +func NewGoogleAnalyticsGA4(name string, enableGeoResolution bool, visitorRegion, measurementID *tagmanager.Variable) *tagmanager.Client { + return &tagmanager.Client{ + Name: name, + Parameter: []*tagmanager.Parameter{ + { + Key: "activateResponseCompression", + Type: "template", + Value: "true", + }, + { + Key: "activateGeoResolution", + Type: "boolean", + Value: strconv.FormatBool(enableGeoResolution), + }, + { + Key: "activateGtagSupport", + Type: "boolean", + Value: "true", + }, + { + Key: "activateDependencyServing", + Type: "boolean", + Value: "true", + }, + { + Key: "activateDefaultPaths", + Type: "boolean", + Value: "true", + }, + { + Key: "region", + Type: "template", + Value: "{{" + visitorRegion.Name + "}}", + }, + { + Key: "cookieManagement", + Type: "template", + Value: "js", + }, + { + Key: "gtagMeasurementIds", + Type: "list", + List: []*tagmanager.Parameter{ + { + Type: "map", + Map: []*tagmanager.Parameter{ + { + Key: "measurementId", + Type: "template", + Value: "{{" + measurementID.Name + "}}", + }, + }, + }, + }, + }, + }, + Type: "gaaw_client", + } +} diff --git a/pkg/provider/googleanalytics/server/client/googlegtag.go b/pkg/provider/googleanalytics/server/client/googlegtag.go index a1e8c6e..ef42a7a 100644 --- a/pkg/provider/googleanalytics/server/client/googlegtag.go +++ b/pkg/provider/googleanalytics/server/client/googlegtag.go @@ -8,7 +8,7 @@ import ( "google.golang.org/api/tagmanager/v2" ) -func NewGoogleGTag(name string, cfg config.GoogleGTag, template *tagmanager.CustomTemplate) *tagmanager.Client { +func NewGoogleGTag(name string, cfg config.GoogleAnalyticsGTagJSOverride, template *tagmanager.CustomTemplate) *tagmanager.Client { return &tagmanager.Client{ Name: name, Priority: cfg.Priority, diff --git a/pkg/tagmanager/server/client/measurementprotocolga4.go b/pkg/provider/googleanalytics/server/client/measurementprotocolga4.go similarity index 100% rename from pkg/tagmanager/server/client/measurementprotocolga4.go rename to pkg/provider/googleanalytics/server/client/measurementprotocolga4.go diff --git a/pkg/provider/googleconsent/server/template/googleconsentmodecheckdata.go b/pkg/provider/googleconsent/server/template/googleconsentmodecheckdata.go index e12a503..b6679c5 100644 --- a/pkg/provider/googleconsent/server/template/googleconsentmodecheckdata.go +++ b/pkg/provider/googleconsent/server/template/googleconsentmodecheckdata.go @@ -59,25 +59,34 @@ const consentType = data.consentType; // --- GA4 --- -if (eventData['x-ga-gcs']) { - const gcs = eventData['x-ga-gcs']; +if (eventData['x-ga-gcd']) { + const gcd = eventData['x-ga-gcd']; + const isGranted = function(v) { + return v === 't' || v === 'r' || v === 'n' || v === 'v'; + }; switch (consentType) { case "ad_storage": - return (gcs.substring(2, 3) === "1") ? 'granted' : 'denied'; + return isGranted(gcd.substring(2, 3)) ? 'granted' : 'denied'; case "analytics_storage": - return (gcs.substring(3, 4) === "1") ? 'granted' : 'denied'; + return isGranted(gcd.substring(4, 5)) ? 'granted' : 'denied'; + case "ad_user_data": + return isGranted(gcd.substring(6, 7)) ? 'granted' : 'denied'; + case "ad_personalization": + return isGranted(gcd.substring(8, 9)) ? 'granted' : 'denied'; default: return 'denied'; } } -if (eventData['x-ga-gcd']) { - const gcd = eventData['x-ga-gcd']; +if (eventData['x-ga-gcs']) { + const gcs = eventData['x-ga-gcs']; switch (consentType) { case "ad_storage": - return (gcd.substring(2, 3) === "1") ? 'granted' : 'denied'; + return (gcs.substring(2, 3) === "1") ? 'granted' : 'denied'; + case "ad_user_data": + return (gcs.substring(2, 3) === "1") ? 'granted' : 'denied'; case "analytics_storage": - return (gcd.substring(3, 4) === "1") ? 'granted' : 'denied'; + return (gcs.substring(3, 4) === "1") ? 'granted' : 'denied'; default: return 'denied'; } @@ -88,13 +97,23 @@ if (eventData['x-ga-gcd']) { let requestBody = getRequestBody(); if (requestBody && getRequestHeader('content-type') === 'application/json') { requestBody = JSON.parse(requestBody); - if (requestBody._consent) { + if (requestBody.consent) { const consent = requestBody.consent; switch (consentType) { case "ad_storage": - return (consent.ad_storage === "GRANTED") ? 'granted' : 'denied'; + return (consent.ad_storage && consent.ad_storage.toUpperCase() === "GRANTED") ? 'granted' : 'denied'; + case "ad_user_data": + return (consent.ad_user_data && consent.ad_user_data.toUpperCase() === "GRANTED") ? 'granted' : 'denied'; + case "ad_personalization": + return (consent.ad_personalization && consent.ad_personalization.toUpperCase() === "GRANTED") ? 'granted' : 'denied'; case "analytics_storage": - return (consent.analytics_storage === "GRANTED") ? 'granted' : 'denied'; + return (consent.analytics_storage && consent.analytics_storage.toUpperCase() === "GRANTED") ? 'granted' : 'denied'; + case "functionality_storage": + return (consent.functionality_storage && consent.functionality_storage.toUpperCase() === "GRANTED") ? 'granted' : 'denied'; + case "personalization_storage": + return (consent.personalization_storage && consent.personalization_storage.toUpperCase() === "GRANTED") ? 'granted' : 'denied'; + case "security_storage": + return (consent.security_storage && consent.security_storage.toUpperCase() === "GRANTED") ? 'granted' : 'denied'; default: return 'denied'; } @@ -122,7 +141,7 @@ if (cookiebotCookie !== undefined) { logToConsole('[FAILURE]', { eventData: eventData, request: requestBody, - cookie: cookiebotCookie, + cookiebot: cookiebotCookie, }); return 'denied'; diff --git a/pkg/provider/googletag/constants.go b/pkg/provider/googletag/constants.go index 5af2786..6433860 100644 --- a/pkg/provider/googletag/constants.go +++ b/pkg/provider/googletag/constants.go @@ -1,9 +1,10 @@ package googletag const ( - Tag = "gt" - Name = "Google Tag" - NameGoogleTag = "Google Tag" - NameGoogleTagID = "Google Tag ID" - NameGoogleTagSettings = "Google Tag Settings" + Tag = "gt" + Name = "Google Tag" + NameGoogleTag = "Google Tag" + NameGoogleTagID = "Google Tag ID" + NameGoogleTagSettings = "Google Tag Settings" + NameGoogleTagMeasurementID = "Google Tag Measurement ID" ) diff --git a/pkg/provider/googletag/server.go b/pkg/provider/googletag/server.go new file mode 100644 index 0000000..805836f --- /dev/null +++ b/pkg/provider/googletag/server.go @@ -0,0 +1,25 @@ +package googletag + +import ( + "github.com/foomo/sesamy-cli/pkg/config" + "github.com/foomo/sesamy-cli/pkg/tagmanager" + commonvariable "github.com/foomo/sesamy-cli/pkg/tagmanager/common/variable" +) + +func Server(tm *tagmanager.TagManager, cfg config.GoogleTag) error { + { // create folder + if folder, err := tm.UpsertFolder("Sesamy - " + Name); err != nil { + return err + } else { + tm.SetFolderName(folder.Name) + } + } + + { // create constants + if _, err := tm.UpsertVariable(commonvariable.NewConstant(NameGoogleTagMeasurementID, cfg.TagID)); err != nil { + return err + } + } + + return nil +} diff --git a/pkg/provider/googletag/web.go b/pkg/provider/googletag/web.go index 3e3ace3..fa63864 100644 --- a/pkg/provider/googletag/web.go +++ b/pkg/provider/googletag/web.go @@ -26,9 +26,6 @@ func Web(tm *tagmanager.TagManager, cfg config.GoogleTag) error { settings := map[string]string{ "server_container_url": "https://{{Page Hostname}}", } - if cfg.DebugMode { - settings["debug_mode"] = "true" - } if !cfg.SendPageView { settings["send_page_view"] = "false" } diff --git a/pkg/provider/googletagmanager/constants.go b/pkg/provider/googletagmanager/constants.go index 2dc9675..4e2f266 100644 --- a/pkg/provider/googletagmanager/constants.go +++ b/pkg/provider/googletagmanager/constants.go @@ -4,4 +4,5 @@ const ( Tag = "gtm" Name = "Google Tag Manager" NameGoogleTagManagerWebContainerClient = "Google Tag Manager Web Container" + NameGoogleTagManagerVisitorRegion = "Visitor Region" ) diff --git a/pkg/provider/googletagmanager/server.go b/pkg/provider/googletagmanager/server.go index e941c54..519c4a2 100644 --- a/pkg/provider/googletagmanager/server.go +++ b/pkg/provider/googletagmanager/server.go @@ -2,11 +2,12 @@ package googletagmanager import ( "github.com/foomo/sesamy-cli/pkg/config" + "github.com/foomo/sesamy-cli/pkg/provider/googletagmanager/server/client" + "github.com/foomo/sesamy-cli/pkg/provider/googletagmanager/server/variable" "github.com/foomo/sesamy-cli/pkg/tagmanager" - containerclient "github.com/foomo/sesamy-cli/pkg/tagmanager/server/client" ) -func Server(tm *tagmanager.TagManager, cfg config.GoogleTagManager) error { +func Server(tm *tagmanager.TagManager, cfg config.GoogleTagManager, enableGeoResolution bool) error { { // create folder if folder, err := tm.UpsertFolder("Sesamy - " + Name); err != nil { return err @@ -22,7 +23,12 @@ func Server(tm *tagmanager.TagManager, cfg config.GoogleTagManager) error { } { // create client - if _, err := tm.UpsertClient(containerclient.NewGoogleTagManagerWebContainer(NameGoogleTagManagerWebContainerClient, cfg.WebContainer.TagID)); err != nil { + visitorRegion, err := tm.UpsertVariable(variable.NewVisitorRegion(NameGoogleTagManagerVisitorRegion)) + if err != nil { + return err + } + + if _, err := tm.UpsertClient(client.NewGoogleTagManagerWebContainer(NameGoogleTagManagerWebContainerClient, cfg.WebContainer.TagID, enableGeoResolution, visitorRegion)); err != nil { return err } } diff --git a/pkg/tagmanager/server/client/googletagmanagerwebcontainer.go b/pkg/provider/googletagmanager/server/client/googletagmanagerwebcontainer.go similarity index 69% rename from pkg/tagmanager/server/client/googletagmanagerwebcontainer.go rename to pkg/provider/googletagmanager/server/client/googletagmanagerwebcontainer.go index 7171cfd..b36f0b1 100644 --- a/pkg/tagmanager/server/client/googletagmanagerwebcontainer.go +++ b/pkg/provider/googletagmanager/server/client/googletagmanagerwebcontainer.go @@ -1,31 +1,33 @@ package client import ( + "strconv" + "google.golang.org/api/tagmanager/v2" ) -func NewGoogleTagManagerWebContainer(name string, tagID string) *tagmanager.Client { +func NewGoogleTagManagerWebContainer(name string, tagID string, enableGeoResolution bool, visitorRegion *tagmanager.Variable) *tagmanager.Client { return &tagmanager.Client{ Name: name, Parameter: []*tagmanager.Parameter{ { - Type: "boolean", Key: "activateResponseCompression", + Type: "boolean", Value: "true", }, { - Type: "boolean", Key: "activateGeoResolution", - Value: "false", + Type: "boolean", + Value: strconv.FormatBool(enableGeoResolution), }, { - Type: "boolean", Key: "activateDependencyServing", + Type: "boolean", Value: "true", }, { - Type: "list", Key: "allowedContainerIds", + Type: "list", List: []*tagmanager.Parameter{ { Type: "map", @@ -39,6 +41,11 @@ func NewGoogleTagManagerWebContainer(name string, tagID string) *tagmanager.Clie }, }, }, + { + Key: "region", + Type: "template", + Value: "{{" + visitorRegion.Name + "}}", + }, }, Type: "gtm_client", } diff --git a/pkg/provider/googletagmanager/server/variable/visitorregion.go b/pkg/provider/googletagmanager/server/variable/visitorregion.go new file mode 100644 index 0000000..15f590d --- /dev/null +++ b/pkg/provider/googletagmanager/server/variable/visitorregion.go @@ -0,0 +1,19 @@ +package variable + +import ( + "google.golang.org/api/tagmanager/v2" +) + +func NewVisitorRegion(name string) *tagmanager.Variable { + return &tagmanager.Variable{ + Name: name, + Parameter: []*tagmanager.Parameter{ + { + Key: "resolutionOptions", + Type: "template", + Value: "requestHeaders", + }, + }, + Type: "vr", + } +} diff --git a/pkg/tagmanager/server/client/googleanalyticsga4.go b/pkg/tagmanager/server/client/googleanalyticsga4.go deleted file mode 100644 index 848d03d..0000000 --- a/pkg/tagmanager/server/client/googleanalyticsga4.go +++ /dev/null @@ -1,29 +0,0 @@ -package client - -import ( - "google.golang.org/api/tagmanager/v2" -) - -func NewGoogleAnalyticsGA4(name string) *tagmanager.Client { - return &tagmanager.Client{ - Name: name, - Parameter: []*tagmanager.Parameter{ - { - Type: "boolean", - Key: "activateGtagSupport", - Value: "false", - }, - { - Type: "boolean", - Key: "activateDefaultPaths", - Value: "true", - }, - { - Type: "template", - Key: "cookieManagement", - Value: "js", - }, - }, - Type: "gaaw_client", - } -} diff --git a/sesamy.schema.json b/sesamy.schema.json index 433ef1a..d9583bc 100644 --- a/sesamy.schema.json +++ b/sesamy.schema.json @@ -46,6 +46,10 @@ "type": "boolean", "description": "Globally redact visitor ip" }, + "enableGeoResolution": { + "type": "boolean", + "description": "Enable region specific settings\nhttps://developers.google.com/tag-platform/tag-manager/server-side/enable-region-specific-settings" + }, "googleTag": { "$ref": "#/$defs/github.com.foomo.sesamy-cli.pkg.config.GoogleTag", "description": "Google Tag settings" @@ -348,15 +352,17 @@ "type": "boolean", "description": "Enable provider" }, - "googleGTag": { - "$ref": "#/$defs/github.com.foomo.sesamy-cli.pkg.config.GoogleGTag" - }, "googleConsent": { "$ref": "#/$defs/github.com.foomo.sesamy-cli.pkg.config.GoogleConsent", "description": "Google Consent settings" }, + "googleGTagJSOverride": { + "$ref": "#/$defs/github.com.foomo.sesamy-cli.pkg.config.GoogleAnalyticsGTagJSOverride", + "description": "GTag.js override configuration" + }, "webContainer": { - "$ref": "#/$defs/github.com.foomo.gocontemplate.pkg.contemplate.Config" + "$ref": "#/$defs/github.com.foomo.gocontemplate.pkg.contemplate.Config", + "description": "Google Tag Manager web container settings" }, "serverContainer": { "$ref": "#/$defs/github.com.foomo.gocontemplate.pkg.contemplate.Config", @@ -366,30 +372,32 @@ "additionalProperties": false, "type": "object" }, - "github.com.foomo.sesamy-cli.pkg.config.GoogleConsent": { + "github.com.foomo.sesamy-cli.pkg.config.GoogleAnalyticsGTagJSOverride": { "properties": { "enabled": { "type": "boolean", - "description": "Enable provider" + "description": "Enable override" }, - "mode": { - "type": "string" + "priority": { + "type": "integer", + "description": "Client priority" + }, + "ecommerceItems": { + "type": "boolean", + "description": "Allow sending items for non ecommerce events" } }, "additionalProperties": false, "type": "object" }, - "github.com.foomo.sesamy-cli.pkg.config.GoogleGTag": { + "github.com.foomo.sesamy-cli.pkg.config.GoogleConsent": { "properties": { "enabled": { "type": "boolean", "description": "Enable provider" }, - "priority": { - "type": "integer" - }, - "ecommerceItems": { - "type": "boolean" + "mode": { + "type": "string" } }, "additionalProperties": false, @@ -401,10 +409,6 @@ "type": "string", "description": "A tag ID is an identifier that you put on your page to load a given Google tag" }, - "debugMode": { - "type": "boolean", - "description": "Enable debug mode for all user devices" - }, "sendPageView": { "type": "boolean", "description": "Whether a page_view should be sent on initial load" diff --git a/sesamy.yaml b/sesamy.yaml index ac40a92..f70c904 100644 --- a/sesamy.yaml +++ b/sesamy.yaml @@ -3,6 +3,9 @@ version: '1.0' # Whether to redact the visitor ip redactVisitorIp: true +# Enable region specific settings +# https://developers.google.com/tag-platform/tag-manager/server-side/enable-region-specific-settings +enableGeoResolution: true # --- Google API settings googleApi: @@ -38,8 +41,6 @@ googleTagManager: googleTag: # A tag ID is an identifier that you put on your page to load a given Google tag tagId: G-PZ5ELRCR31 - # Enable debug mode for all user devices - debugMode: false # Whether a page_view should be sent on initial load sendPageView: true # TypeScript settings @@ -111,20 +112,20 @@ googleTag: googleAnalytics: # Enable provider enabled: true - # Google GTag.js settings - googleGTag: - # Provision custom client - enabled: true - # Client priority - priority: 10 - # Patch ecommerce items - ecommerceItems: true # Google Consent settings googleConsent: # Enable consent mode enabled: true # Consent mode name mode: analytics_storage + # Google GTag.js override settings + googleGTagJSOverride: + # Provision custom client + enabled: true + # Client priority + priority: 10 + # Patch ecommerce items + ecommerceItems: true # Google Tag Manager web container settings webContainer: # Contemplate package config for generated events From 036c32ee0ca4e10e945af67bf2aebfb31453a337 Mon Sep 17 00:00:00 2001 From: Kevin Franklin Kim Date: Wed, 12 Feb 2025 11:42:35 +0100 Subject: [PATCH 2/2] feat: add debug_mode transformation --- pkg/provider/googleanalytics/server.go | 11 ++++- .../server/transformation/mpv2userdata.go | 43 ++++++++++--------- 2 files changed, 33 insertions(+), 21 deletions(-) diff --git a/pkg/provider/googleanalytics/server.go b/pkg/provider/googleanalytics/server.go index 88ea1a1..0825f1a 100644 --- a/pkg/provider/googleanalytics/server.go +++ b/pkg/provider/googleanalytics/server.go @@ -17,6 +17,7 @@ import ( servervariable "github.com/foomo/sesamy-cli/pkg/tagmanager/server/variable" "github.com/foomo/sesamy-cli/pkg/utils" "github.com/pkg/errors" + api "google.golang.org/api/tagmanager/v2" ) func Server(tm *tagmanager.TagManager, cfg config.GoogleAnalytics, redactVisitorIP, enableGeoResolution bool) error { @@ -69,7 +70,15 @@ func Server(tm *tagmanager.TagManager, cfg config.GoogleAnalytics, redactVisitor return err } - _, err = tm.UpsertTransformation(servertransformation.NewMPv2UserData(NameMPv2UserDataTransformation, userDataVariable, client)) + debugModeVariable, err := tm.UpsertVariable(servervariable.NewMPv2Data("debug_mode", userDataTemplate)) + if err != nil { + return err + } + + _, err = tm.UpsertTransformation(servertransformation.NewMPv2UserData(NameMPv2UserDataTransformation, map[string]*api.Variable{ + "user_data": userDataVariable, + "debug_mode": debugModeVariable, + }, client)) if err != nil { return err } diff --git a/pkg/tagmanager/server/transformation/mpv2userdata.go b/pkg/tagmanager/server/transformation/mpv2userdata.go index e56d66f..0b60e3f 100644 --- a/pkg/tagmanager/server/transformation/mpv2userdata.go +++ b/pkg/tagmanager/server/transformation/mpv2userdata.go @@ -4,7 +4,27 @@ import ( "google.golang.org/api/tagmanager/v2" ) -func NewMPv2UserData(name string, variable *tagmanager.Variable, client *tagmanager.Client) *tagmanager.Transformation { +func NewMPv2UserData(name string, variables map[string]*tagmanager.Variable, client *tagmanager.Client) *tagmanager.Transformation { + var list []*tagmanager.Parameter + for k, v := range variables { + list = append(list, &tagmanager.Parameter{ + IsWeakReference: false, + Map: []*tagmanager.Parameter{ + { + Key: "paramName", + Type: "template", + Value: k, + }, + { + Key: "paramValue", + Type: "template", + Value: "{{" + v.Name + "}}", + }, + }, + Type: "map", + }) + } + return &tagmanager.Transformation{ Name: name, Parameter: []*tagmanager.Parameter{ @@ -23,25 +43,8 @@ func NewMPv2UserData(name string, variable *tagmanager.Variable, client *tagmana Type: "template", }, { - Key: "augmentEventTable", - List: []*tagmanager.Parameter{ - { - IsWeakReference: false, - Map: []*tagmanager.Parameter{ - { - Key: "paramName", - Type: "template", - Value: "user_data", - }, - { - Key: "paramValue", - Type: "template", - Value: "{{" + variable.Name + "}}", - }, - }, - Type: "map", - }, - }, + Key: "augmentEventTable", + List: list, Type: "list", }, {