From dcc4eeb19bde3612d1733a8321bf3d6986a065a3 Mon Sep 17 00:00:00 2001 From: Kevin Franklin Kim Date: Sun, 14 Jul 2024 14:05:21 +0200 Subject: [PATCH] feat: add google ads conversion --- cmd/tagmanager/server.go | 8 +++ pkg/config/config.go | 1 + pkg/config/googleads.go | 6 ++ pkg/config/googleadsconversion.go | 12 ++++ pkg/provider/facebook/constants.go | 6 +- pkg/provider/googleads/constants.go | 8 +++ pkg/provider/googleads/server.go | 55 +++++++++++++++++ .../server/tag/googleadsconversiontracking.go | 61 +++++++++++++++++++ sesamy.yaml | 29 +++++++-- 9 files changed, 178 insertions(+), 8 deletions(-) create mode 100644 pkg/config/googleads.go create mode 100644 pkg/config/googleadsconversion.go create mode 100644 pkg/provider/googleads/constants.go create mode 100644 pkg/provider/googleads/server.go create mode 100644 pkg/provider/googleads/server/tag/googleadsconversiontracking.go diff --git a/cmd/tagmanager/server.go b/cmd/tagmanager/server.go index 6ec9fa6..caad57b 100644 --- a/cmd/tagmanager/server.go +++ b/cmd/tagmanager/server.go @@ -4,6 +4,7 @@ import ( pkgcmd "github.com/foomo/sesamy-cli/pkg/cmd" conversionlinkerprovider "github.com/foomo/sesamy-cli/pkg/provider/conversionlinker" 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" @@ -84,6 +85,13 @@ func NewServer(root *cobra.Command) { } } + if cfg.GoogleAds.Enabled && pkgcmd.Tag(googleadsprovider.Tag, tags) { + l.Info("🅿️ Running provider", "name", googleadsprovider.Name) + if err := googleadsprovider.Server(l, tm, cfg.GoogleAds); err != nil { + return errors.Wrap(err, "failed to provision google ads") + } + } + return nil }, } diff --git a/pkg/config/config.go b/pkg/config/config.go index 2779e0e..64554b4 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -7,6 +7,7 @@ type Config struct { GoogleAPI GoogleAPI `json:"googleAPI" yaml:"googleAPI"` GoogleTagManager GoogleTagManager `json:"googleTagManager" yaml:"googleTagManager"` // Providers + GoogleAds GoogleAds `json:"googleAds" yaml:"googleAds"` GoogleAnalytics GoogleAnalytics `json:"googleAnalytics" yaml:"googleAnalytics"` ConversionLinker ConversionLinker `json:"conversionLinker" yaml:"conversionLinker"` Facebook Facebook `json:"facebook" yaml:"facebook"` diff --git a/pkg/config/googleads.go b/pkg/config/googleads.go new file mode 100644 index 0000000..cffbcdc --- /dev/null +++ b/pkg/config/googleads.go @@ -0,0 +1,6 @@ +package config + +type GoogleAds struct { + Enabled bool `json:"enabled" yaml:"enabled"` + Conversion GoogleAdsConversion `json:"conversion" yaml:"conversion"` +} diff --git a/pkg/config/googleadsconversion.go b/pkg/config/googleadsconversion.go new file mode 100644 index 0000000..2adb9da --- /dev/null +++ b/pkg/config/googleadsconversion.go @@ -0,0 +1,12 @@ +package config + +import ( + "github.com/foomo/gocontemplate/pkg/contemplate" +) + +type GoogleAdsConversion struct { + Enabled bool `json:"enabled" yaml:"enabled"` + ConversionID string `json:"conversionId" yaml:"conversionId"` + ConversionLabel string `json:"conversionLabel" yaml:"conversionLabel"` + ServerContainer contemplate.Config `json:"serverContainer" yaml:"serverContainer"` +} diff --git a/pkg/provider/facebook/constants.go b/pkg/provider/facebook/constants.go index 90832ba..7b765a2 100644 --- a/pkg/provider/facebook/constants.go +++ b/pkg/provider/facebook/constants.go @@ -3,8 +3,8 @@ package facebook const ( Tag = "meta" Name = "Facebook" - NamePixelIDConstant = "Facebook Pixel ID" - NameAPIAcessTokenConstant = "Facebook API Access Token" - NameTestEventTokenConstant = "Facebook Test Event Token" + NamePixelIDConstant = "FB Pixel ID" + NameAPIAcessTokenConstant = "FB API Access Token" + NameTestEventTokenConstant = "FB Test Event Token" NameConversionsAPITagTemplate = "Conversions API Tag" ) diff --git a/pkg/provider/googleads/constants.go b/pkg/provider/googleads/constants.go new file mode 100644 index 0000000..dc35d66 --- /dev/null +++ b/pkg/provider/googleads/constants.go @@ -0,0 +1,8 @@ +package googleads + +const ( + Tag = "gads" + Name = "Google Ads" + NameConversionIDConstant = "GAds Conversion ID" + NameConversionLabelConstant = "GAds Conversion Label" +) diff --git a/pkg/provider/googleads/server.go b/pkg/provider/googleads/server.go new file mode 100644 index 0000000..7ab138d --- /dev/null +++ b/pkg/provider/googleads/server.go @@ -0,0 +1,55 @@ +package googleads + +import ( + "log/slog" + + "github.com/foomo/sesamy-cli/pkg/config" + servertagx "github.com/foomo/sesamy-cli/pkg/provider/googleads/server/tag" + "github.com/foomo/sesamy-cli/pkg/provider/googletag" + "github.com/foomo/sesamy-cli/pkg/tagmanager" + commontrigger "github.com/foomo/sesamy-cli/pkg/tagmanager/common/trigger" + commonvariable "github.com/foomo/sesamy-cli/pkg/tagmanager/common/variable" + "github.com/pkg/errors" +) + +func Server(l *slog.Logger, tm *tagmanager.TagManager, cfg config.GoogleAds) error { + { // create folder + if folder, err := tm.UpsertFolder("Sesamy - " + Name); err != nil { + return err + } else { + tm.SetFolderName(folder.Name) + } + } + + { // conversion + conversionID, err := tm.UpsertVariable(commonvariable.NewConstant(NameConversionIDConstant, cfg.Conversion.ConversionID)) + if err != nil { + return err + } + + conversionLabel, err := tm.UpsertVariable(commonvariable.NewConstant(NameConversionLabelConstant, cfg.Conversion.ConversionLabel)) + if err != nil { + return err + } + + { // create tags + eventParameters, err := googletag.CreateServerEventTriggers(tm, cfg.Conversion.ServerContainer) + if err != nil { + return err + } + + for event := range eventParameters { + eventTrigger, err := tm.LookupTrigger(commontrigger.EventName(event)) + if err != nil { + return errors.Wrap(err, "failed to lookup event trigger: "+event) + } + + if _, err := tm.UpsertTag(servertagx.NewGoogleAdsConversionTracking(event, conversionID, conversionLabel, eventTrigger)); err != nil { + return err + } + } + } + } + + return nil +} diff --git a/pkg/provider/googleads/server/tag/googleadsconversiontracking.go b/pkg/provider/googleads/server/tag/googleadsconversiontracking.go new file mode 100644 index 0000000..47ee308 --- /dev/null +++ b/pkg/provider/googleads/server/tag/googleadsconversiontracking.go @@ -0,0 +1,61 @@ +package tag + +import ( + "github.com/foomo/sesamy-cli/pkg/utils" + "google.golang.org/api/tagmanager/v2" +) + +func GoogleAdsConversionTrackingName(v string) string { + return "GAds Conversion - " + v +} + +func NewGoogleAdsConversionTracking(name string, conversionID, conversionLabel *tagmanager.Variable, triggers ...*tagmanager.Trigger) *tagmanager.Tag { + return &tagmanager.Tag{ + FiringTriggerId: utils.TriggerIDs(triggers), + Name: GoogleAdsConversionTrackingName(name), + TagFiringOption: "oncePerEvent", + Parameter: []*tagmanager.Parameter{ + { + Key: "enableNewCustomerReporting", + Type: "boolean", + Value: "false", + }, + { + Key: "enableConversionLinker", + Type: "boolean", + Value: "true", + }, + { + Key: "enableProductReporting", + Type: "boolean", + Value: "false", + }, + { + Key: "conversionValue", + Type: "template", + Value: "{{value}}", + }, + { + Key: "conversionId", + Type: "template", + Value: "{{" + conversionID.Name + "}}", + }, + { + Key: "currencyCode", + Type: "template", + Value: "{{currency}}", + }, + { + Key: "conversionLabel", + Type: "template", + Value: "{{" + conversionLabel.Name + "}}", + }, + { + Key: "rdp", + Type: "boolean", + Value: "false", + }, + }, + Type: "sgtmadsct", + } +} diff --git a/sesamy.yaml b/sesamy.yaml index 681326d..9606f80 100644 --- a/sesamy.yaml +++ b/sesamy.yaml @@ -46,7 +46,7 @@ googleTag: webContainer: # Contemplate package config for generated events packages: - - path: 'github.com/foomo/sesamy-cli/_example/server' + - path: github.com/foomo/sesamy-go/pkg/event types: - PageView - SelectItem @@ -54,7 +54,7 @@ googleTag: serverContainer: # Contemplate package config for generated events packages: - - path: 'github.com/foomo/sesamy-cli/_example/server' + - path: github.com/foomo/sesamy-go/pkg/event types: - PageView - SelectItem @@ -131,7 +131,7 @@ googleAnalytics: webContainer: # Contemplate package config for generated events packages: - - path: 'github.com/foomo/sesamy-cli/_example/server' + - path: github.com/foomo/sesamy-go/pkg/event types: - PageView - SelectItem @@ -139,11 +139,30 @@ googleAnalytics: serverContainer: # Contemplate package config for generated events packages: - - path: 'github.com/foomo/sesamy-cli/_example/server' + - path: github.com/foomo/sesamy-go/pkg/event types: - PageView - SelectItem +# --- Google Ads +googleAds: + # Enable provider + enabled: true + # Google Ads Conversion settings + conversion: + # Google Ads Conversion Tracking ID + conversionId: '' + # Google Ads Conversion Tracking Label + conversionLabel: '' + # Google Tag Manager server container settings + serverContainer: + # Contemplate package config for generated events + packages: + - path: github.com/foomo/sesamy-go/pkg/event + types: + - AddToCart + - Purchase + # --- Conversion Linker settings conversionLinker: # Enable provider @@ -163,7 +182,7 @@ umami: serverContainer: # Contemplate package config for generated events packages: - - path: 'github.com/foomo/sesamy-cli/_example/server' + - path: github.com/foomo/sesamy-go/pkg/event types: - PageView - SelectItem