feat: make prefix configurable

This commit is contained in:
Kevin Franklin Kim 2024-03-14 14:00:52 +01:00
parent b8297aacaf
commit e5fcca2648
No known key found for this signature in database
29 changed files with 878 additions and 708 deletions

View File

@ -19,13 +19,28 @@ google:
typescript: typescript:
packages: packages:
- path: "github.com/foomo/sesamy-cli/_example/server" - path: 'github.com/foomo/sesamy-cli/_example/server'
output_path: "./_example/client/types.d.ts" output_path: './_example/client/types.d.ts'
indent: "\t" indent: '\t'
tagmanager: tagmanager:
packages: packages:
- path: "github.com/foomo/sesamy-cli/_example/server" - path: 'github.com/foomo/sesamy-cli/_example/server'
output_path: "./_example/client/types.d.ts" output_path: './_example/client/types.d.ts'
exclude_files: exclude_files:
- item.go - item.go
prefixes:
client: ''
folder: ''
tags:
ga4_event: 'GA4 - '
google_tag: ''
server_ga4_event: 'GA4 - '
triggers:
client: ''
custom_event: 'Event - '
variables:
constant: ''
event_model: 'dlv.eventModel.'
gt_event_settings: 'Event Settings - '
gt_settings: 'Setttings - '

View File

@ -3,6 +3,7 @@ package cmd
import ( import (
"bytes" "bytes"
"io" "io"
"log/slog"
"os" "os"
"github.com/foomo/sesamy-cli/pkg/config" "github.com/foomo/sesamy-cli/pkg/config"
@ -13,7 +14,7 @@ import (
) )
var ( var (
logger *pterm.Logger logger *slog.Logger
verbose bool verbose bool
cfgFilename string cfgFilename string
cfg *config.Config cfg *config.Config
@ -46,7 +47,7 @@ func init() {
// Cobra also supports local flags, which will only run // Cobra also supports local flags, which will only run
// when this action is called directly. // when this action is called directly.
//rootCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle") // rootCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
} }
// initConfig reads in config file and ENV variables if set. // initConfig reads in config file and ENV variables if set.
@ -64,14 +65,20 @@ func initConfig() {
} }
// read in environment variables that match // read in environment variables that match
//viper.EnvKeyReplacer(strings.NewReplacer(".", "_")) // viper.EnvKeyReplacer(strings.NewReplacer(".", "_"))
//viper.SetEnvPrefix("SESAMY") // viper.SetEnvPrefix("SESAMY")
//viper.AutomaticEnv() // viper.AutomaticEnv()
logger = pterm.DefaultLogger.WithTime(false) plogger := pterm.DefaultLogger.WithTime(false)
if verbose { if verbose {
logger = logger.WithLevel(pterm.LogLevelTrace).WithCaller(true) plogger = plogger.WithLevel(pterm.LogLevelTrace).WithCaller(true)
} }
// Create a new slog handler with the default PTerm logger
handler := pterm.NewSlogHandler(plogger)
// Create a new slog logger with the handler
logger = slog.New(handler)
} }
func preRunReadConfig(cmd *cobra.Command, args []string) error { func preRunReadConfig(cmd *cobra.Command, args []string) error {
@ -85,12 +92,12 @@ func preRunReadConfig(cmd *cobra.Command, args []string) error {
return err return err
} }
} else { } else {
logger.Debug("using config file", logger.Args("filename", viper.ConfigFileUsed())) logger.Debug("using config file", "filename", viper.ConfigFileUsed())
if err := viper.ReadInConfig(); err != nil { if err := viper.ReadInConfig(); err != nil {
return err return err
} }
} }
logger.Debug("config", logger.ArgsFromMap(viper.AllSettings())) // logger.Debug("config", logger.ArgsFromMap(viper.AllSettings()))
if err := viper.Unmarshal(&cfg, func(decoderConfig *mapstructure.DecoderConfig) { if err := viper.Unmarshal(&cfg, func(decoderConfig *mapstructure.DecoderConfig) {
decoderConfig.TagName = "yaml" decoderConfig.TagName = "yaml"

View File

@ -2,8 +2,13 @@ package cmd
import ( import (
"github.com/foomo/sesamy-cli/pkg/tagmanager" "github.com/foomo/sesamy-cli/pkg/tagmanager"
"github.com/foomo/sesamy-cli/pkg/tagmanager/client"
client2 "github.com/foomo/sesamy-cli/pkg/tagmanager/tag"
"github.com/foomo/sesamy-cli/pkg/tagmanager/trigger"
"github.com/foomo/sesamy-cli/pkg/tagmanager/variable"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"google.golang.org/api/option" "google.golang.org/api/option"
tagmanager2 "google.golang.org/api/tagmanager/v2"
) )
// tagmanagerServerCmd represents the server command // tagmanagerServerCmd represents the server command
@ -14,6 +19,7 @@ var tagmanagerServerCmd = &cobra.Command{
Short: "Provision Google Tag Manager Server Container", Short: "Provision Google Tag Manager Server Container",
PersistentPreRunE: preRunReadConfig, PersistentPreRunE: preRunReadConfig,
RunE: func(cmd *cobra.Command, args []string) error { RunE: func(cmd *cobra.Command, args []string) error {
var clientCredentialsOption option.ClientOption var clientCredentialsOption option.ClientOption
if cfg.Google.CredentialsFile != "" { if cfg.Google.CredentialsFile != "" {
clientCredentialsOption = option.WithCredentialsFile(cfg.Google.CredentialsFile) clientCredentialsOption = option.WithCredentialsFile(cfg.Google.CredentialsFile)
@ -23,6 +29,7 @@ var tagmanagerServerCmd = &cobra.Command{
c, err := tagmanager.NewClient( c, err := tagmanager.NewClient(
cmd.Context(), cmd.Context(),
logger,
cfg.Google.GTM.AccountID, cfg.Google.GTM.AccountID,
cfg.Google.GTM.Server.ContainerID, cfg.Google.GTM.Server.ContainerID,
cfg.Google.GTM.Server.WorkspaceID, cfg.Google.GTM.Server.WorkspaceID,
@ -34,37 +41,65 @@ var tagmanagerServerCmd = &cobra.Command{
return err return err
} }
logger.Info("- Folder:", logger.Args("name", c.FolderName())) p := cfg.Tagmanager.Prefixes
if _, err := c.UpsertFolder(c.FolderName()); err != nil {
return err {
name := p.FolderName(c.FolderName())
if _, err := c.UpsertFolder(name); err != nil {
return err
}
} }
logger.Info("- Variable:", logger.Args("name", "ga4-measurement-id")) {
measurementID, err := c.UpsertConstantVariable("ga4-measurement-id", c.MeasurementID()) if _, err := c.EnableBuiltInVariable("clientName"); err != nil {
if err != nil { return err
return err }
} }
logger.Info("- GTM client:", logger.Args("name", "Google Tag Manager Web Container")) var ga4MeasurementID *tagmanager2.Variable
if _, err := c.UpsertGTMClient("Google Tag Manager Web Container", cfg.Google.GTM.Web.MeasurementID); err != nil { {
return err name := p.Variables.ConstantName("Google Analytics GA4 ID")
if ga4MeasurementID, err = c.UpsertVariable(variable.NewConstant(name, c.MeasurementID())); err != nil {
return err
}
} }
logger.Info("- GA4 client:", logger.Args("name", "Google Analytics GA4")) var webContainerMeasurementID *tagmanager2.Variable
ga4Client, err := c.UpsertGA4Client("Google Analytics GA4") {
if err != nil { name := p.Variables.ConstantName("Google Tag Mangager Web Container ID")
return err if webContainerMeasurementID, err = c.UpsertVariable(variable.NewConstant(name, cfg.Google.GTM.Web.MeasurementID)); err != nil {
return err
}
} }
logger.Info("- GA4 trigger:", logger.Args("name", "Google Analytics GA4")) {
ga4ClientTrigger, err := c.UpsertClientTrigger("ga4", ga4Client) name := p.ClientName("Google Tag Manager Web Container")
if err != nil { if _, err := c.UpsertClient(client.NewGTM(name, webContainerMeasurementID)); err != nil {
return err return err
}
} }
logger.Info("- GA4 tag:", logger.Args("name", "Google Analytics GA4")) var ga4Client *tagmanager2.Client
if _, err := c.UpsertGA4ServerTag("Google Analytics GA4", measurementID, ga4ClientTrigger); err != nil { {
return err name := p.ClientName("Google Analytics GA4")
if ga4Client, err = c.UpsertClient(client.NewGA4(name)); err != nil {
return err
}
}
var ga4ClientTrigger *tagmanager2.Trigger
{
name := p.Triggers.ClientName("Google Analytics GA4 Client")
if ga4ClientTrigger, err = c.UpsertTrigger(trigger.NewClient(name, ga4Client)); err != nil {
return err
}
}
{
name := p.Tags.ServerGA4EventName("Google Analytics GA4")
if _, err := c.UpsertTag(client2.NewServerGA4Event(name, ga4MeasurementID, ga4ClientTrigger)); err != nil {
return err
}
} }
return nil return nil

View File

@ -3,6 +3,9 @@ package cmd
import ( import (
"github.com/foomo/sesamy-cli/internal" "github.com/foomo/sesamy-cli/internal"
"github.com/foomo/sesamy-cli/pkg/tagmanager" "github.com/foomo/sesamy-cli/pkg/tagmanager"
client "github.com/foomo/sesamy-cli/pkg/tagmanager/tag"
trigger2 "github.com/foomo/sesamy-cli/pkg/tagmanager/trigger"
"github.com/foomo/sesamy-cli/pkg/tagmanager/variable"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"google.golang.org/api/option" "google.golang.org/api/option"
tagmanager2 "google.golang.org/api/tagmanager/v2" tagmanager2 "google.golang.org/api/tagmanager/v2"
@ -28,6 +31,7 @@ var tagmanagerWebCmd = &cobra.Command{
c, err := tagmanager.NewClient( c, err := tagmanager.NewClient(
cmd.Context(), cmd.Context(),
logger,
cfg.Google.GTM.AccountID, cfg.Google.GTM.AccountID,
cfg.Google.GTM.Web.ContainerID, cfg.Google.GTM.Web.ContainerID,
cfg.Google.GTM.Web.WorkspaceID, cfg.Google.GTM.Web.WorkspaceID,
@ -39,61 +43,76 @@ var tagmanagerWebCmd = &cobra.Command{
return err return err
} }
logger.Info("- Folder:", logger.Args("name", c.FolderName())) p := cfg.Tagmanager.Prefixes
if _, err := c.UpsertFolder(c.FolderName()); err != nil {
if _, err := c.UpsertFolder(p.FolderName(c.FolderName())); err != nil {
return err return err
} }
logger.Info("- Variable:", logger.Args("name", "ga4-measurement-id")) var ga4MeasurementID *tagmanager2.Variable
measurementID, err := c.UpsertConstantVariable("ga4-measurement-id", c.MeasurementID()) {
if err != nil { name := p.Variables.ConstantName("Google Analytics GA4 ID")
return err if ga4MeasurementID, err = c.UpsertVariable(variable.NewConstant(name, c.MeasurementID())); err != nil {
return err
}
} }
logger.Info("- Variable:", logger.Args("name", "server-container-url")) var serverContainerURL *tagmanager2.Variable
serverContainerURL, err := c.UpsertConstantVariable("server-container-url", cfg.Google.ServerContainerURL) {
if err != nil { name := p.Variables.ConstantName("Server Container URL")
return err if serverContainerURL, err = c.UpsertVariable(variable.NewConstant(name, cfg.Google.ServerContainerURL)); err != nil {
return err
}
} }
logger.Info("- Variable:", logger.Args("name", "Google Tag Settings")) var googleTagSettings *tagmanager2.Variable
googleTagSettings, err := c.UpsertGoogleTagSettingsVariable("Google Tag Settings", map[string]*tagmanager2.Variable{ {
"server_container_url": serverContainerURL, name := p.Variables.GTSettingsName("Google Tag")
}) if googleTagSettings, err = c.UpsertVariable(variable.NewGTSettings(name, map[string]*tagmanager2.Variable{
if err != nil { "server_container_url": serverContainerURL,
return err })); err != nil {
return err
}
} }
logger.Info("- Tag:", logger.Args("name", "Google Tag")) {
if _, err = c.UpsertGoogleTagWebTag("Google Tag", measurementID, googleTagSettings); err != nil { name := p.Tags.GoogleTagName("Google Tag")
return err if _, err = c.UpsertTag(client.NewGoogleTag(name, ga4MeasurementID, googleTagSettings)); err != nil {
return err
}
} }
for event, parameters := range eventParameters { for event, parameters := range eventParameters {
logger.Info("- GA4 Event Trigger:", logger.Args("name", event)) var trigger *tagmanager2.Trigger
trigger, err := c.UpsertCustomEventTrigger(event) {
if err != nil { name := p.Triggers.CustomEventName(event)
return err if trigger, err = c.UpsertTrigger(trigger2.NewCustomEvent(name, event)); err != nil {
return err
}
} }
eventSettingsVariables := make(map[string]*tagmanager2.Variable, len(parameters)) eventSettingsVariables := make(map[string]*tagmanager2.Variable, len(parameters))
for _, parameter := range parameters { for _, parameter := range parameters {
logger.Info("- Event Model Variable:", logger.Args("name", parameter)) name := p.Variables.EventModelName(parameter)
eventSettingsVariables[parameter], err = c.UpsertEventModelVariable(parameter) eventSettingsVariables[parameter], err = c.UpsertVariable(variable.NewEventModel(name, parameter))
if err != nil { if err != nil {
return err return err
} }
} }
logger.Info("- GT Event Settings Variable:", logger.Args("name", event)) var eventSettings *tagmanager2.Variable
eventSettings, err := c.UpsertGTEventSettingsVariable(event, eventSettingsVariables) {
if err != nil { name := p.Variables.GTEventSettingsName(event)
return err if eventSettings, err = c.UpsertVariable(variable.NewGTEventSettings(name, eventSettingsVariables)); err != nil {
return err
}
} }
logger.Info("- GA4 Tag:", logger.Args("name", event, "parameters", parameters)) {
if _, err := c.UpsertGA4WebTag(event, eventSettings, measurementID, trigger); err != nil { name := p.Tags.GA4EventName(event)
return err if _, err := c.UpsertTag(client.NewGA4Event(name, event, eventSettings, ga4MeasurementID, trigger)); err != nil {
return err
}
} }
} }

View File

@ -13,7 +13,7 @@ import (
"golang.org/x/tools/go/packages" "golang.org/x/tools/go/packages"
) )
func GetEventParameters(source config.Source) (map[string][]string, error) { func GetEventParameters(source config.Tagmanager) (map[string][]string, error) {
ret := map[string][]string{} ret := map[string][]string{}
pkgs, err := packages.Load(&packages.Config{ pkgs, err := packages.Load(&packages.Config{

View File

@ -1,59 +1,9 @@
package config package config
import (
"github.com/gzuidhof/tygo/tygo"
)
type Config struct { type Config struct {
Google Google `yaml:"google"` Google Google `yaml:"google"`
// https://github.com/gzuidhof/tygo // https://github.com/gzuidhof/tygo
Typescript Source `yaml:"typescript"` Typescript Typescript `yaml:"typescript"`
// https://github.com/gzuidhof/tygo // https://github.com/gzuidhof/tygo
Tagmanager Source `yaml:"tagmanager"` Tagmanager Tagmanager `yaml:"tagmanager"`
}
type Google struct {
GA4 GA4 `yaml:"ga4"`
GTM GTM `yaml:"gtm"`
CredentialsFile string `yaml:"credentials_file"`
CredentialsJSON string `yaml:"credentials_json"`
ServerContainerURL string `yaml:"server_container_url"`
}
type GA4 struct {
MeasurementID string `yaml:"measurement_id"`
}
type GTM struct {
AccountID string `yaml:"account_id"`
Web Container `yaml:"web"`
Server Container `yaml:"server"`
}
type Source struct {
Packages []*tygo.PackageConfig `yaml:"packages"`
TypeMappings map[string]string `yaml:"type_mappings"`
}
func (e Source) PackageNames() []string {
ret := make([]string, len(e.Packages))
for i, value := range e.Packages {
ret[i] = value.Path
}
return ret
}
func (e Source) PackageConfig(path string) *tygo.PackageConfig {
for _, value := range e.Packages {
if value.Path == path {
return value
}
}
return nil
}
type Container struct {
ContainerID string `yaml:"container_id"`
WorkspaceID string `yaml:"workspace_id"`
MeasurementID string `yaml:"measurement_id"`
} }

7
pkg/config/container.go Normal file
View File

@ -0,0 +1,7 @@
package config
type Container struct {
ContainerID string `yaml:"container_id"`
WorkspaceID string `yaml:"workspace_id"`
MeasurementID string `yaml:"measurement_id"`
}

5
pkg/config/ga4.go Normal file
View File

@ -0,0 +1,5 @@
package config
type GA4 struct {
MeasurementID string `yaml:"measurement_id"`
}

9
pkg/config/google.go Normal file
View File

@ -0,0 +1,9 @@
package config
type Google struct {
GA4 GA4 `yaml:"ga4"`
GTM GTM `yaml:"gtm"`
CredentialsFile string `yaml:"credentials_file"`
CredentialsJSON string `yaml:"credentials_json"`
ServerContainerURL string `yaml:"server_container_url"`
}

7
pkg/config/gtm.go Normal file
View File

@ -0,0 +1,7 @@
package config
type GTM struct {
AccountID string `yaml:"account_id"`
Web Container `yaml:"web"`
Server Container `yaml:"server"`
}

28
pkg/config/tagmanager.go Normal file
View File

@ -0,0 +1,28 @@
package config
import (
"github.com/gzuidhof/tygo/tygo"
)
type Tagmanager struct {
Packages []*tygo.PackageConfig `yaml:"packages"`
TypeMappings map[string]string `yaml:"type_mappings"`
Prefixes TagmanagerPrefixes `yaml:"prefixes"`
}
func (e Tagmanager) PackageNames() []string {
ret := make([]string, len(e.Packages))
for i, value := range e.Packages {
ret[i] = value.Path
}
return ret
}
func (e Tagmanager) PackageConfig(path string) *tygo.PackageConfig {
for _, value := range e.Packages {
if value.Path == path {
return value
}
}
return nil
}

View File

@ -0,0 +1,17 @@
package config
type TagmanagerPrefixes struct {
Client string `yaml:"client"`
Folder string `yaml:"folder"`
Tags TagmangerTagPrefixes `yaml:"tags"`
Triggers TagmangerTriggerPrefixes `yaml:"triggers"`
Variables TagmangerVariablePrefixes `yaml:"variables"`
}
func (p TagmanagerPrefixes) ClientName(name string) string {
return p.Client + name
}
func (p TagmanagerPrefixes) FolderName(name string) string {
return p.Folder + name
}

View File

@ -0,0 +1,19 @@
package config
type TagmangerTagPrefixes struct {
GA4Event string `yaml:"ga4_event"`
GoogleTag string `yaml:"google_tag"`
ServerGA4Event string `yaml:"server_ga4_event"`
}
func (p TagmangerTagPrefixes) GA4EventName(name string) string {
return p.GA4Event + name
}
func (p TagmangerTagPrefixes) GoogleTagName(name string) string {
return p.GoogleTag + name
}
func (p TagmangerTagPrefixes) ServerGA4EventName(name string) string {
return p.ServerGA4Event + name
}

View File

@ -0,0 +1,14 @@
package config
type TagmangerTriggerPrefixes struct {
Client string `yaml:"client"`
CustomEvent string `yaml:"custom_event"`
}
func (p TagmangerTriggerPrefixes) ClientName(name string) string {
return p.Client + name
}
func (p TagmangerTriggerPrefixes) CustomEventName(name string) string {
return p.CustomEvent + name
}

View File

@ -0,0 +1,24 @@
package config
type TagmangerVariablePrefixes struct {
Constant string `yaml:"constant"`
EventModel string `yaml:"event_model"`
GTEventSettings string `yaml:"gt_event_settings"`
GTSettings string `yaml:"gt_settings"`
}
func (p TagmangerVariablePrefixes) ConstantName(name string) string {
return p.Constant + name
}
func (p TagmangerVariablePrefixes) EventModelName(name string) string {
return p.EventModel + name
}
func (p TagmangerVariablePrefixes) GTEventSettingsName(name string) string {
return p.GTEventSettings + name
}
func (p TagmangerVariablePrefixes) GTSettingsName(name string) string {
return p.GTSettings + name
}

27
pkg/config/typescript.go Normal file
View File

@ -0,0 +1,27 @@
package config
import (
"github.com/gzuidhof/tygo/tygo"
)
type Typescript struct {
Packages []*tygo.PackageConfig `yaml:"packages"`
TypeMappings map[string]string `yaml:"type_mappings"`
}
func (e Typescript) PackageNames() []string {
ret := make([]string, len(e.Packages))
for i, value := range e.Packages {
ret[i] = value.Path
}
return ret
}
func (e Typescript) PackageConfig(path string) *tygo.PackageConfig {
for _, value := range e.Packages {
if value.Path == path {
return value
}
}
return nil
}

View File

@ -3,7 +3,7 @@ package tagmanager
import ( import (
"context" "context"
"errors" "errors"
"sort" "log/slog"
"time" "time"
"google.golang.org/api/option" "google.golang.org/api/option"
@ -16,6 +16,7 @@ var (
type ( type (
Client struct { Client struct {
l *slog.Logger
notes string notes string
accountID string accountID string
containerID string containerID string
@ -25,12 +26,13 @@ type (
clientOptions []option.ClientOption clientOptions []option.ClientOption
requestThrottler *time.Ticker requestThrottler *time.Ticker
// cache // cache
service *tagmanager.Service service *tagmanager.Service
clients map[string]*tagmanager.Client clients map[string]*tagmanager.Client
folders map[string]*tagmanager.Folder folders map[string]*tagmanager.Folder
variables map[string]*tagmanager.Variable variables map[string]*tagmanager.Variable
triggers map[string]*tagmanager.Trigger builtInVariables map[string]*tagmanager.BuiltInVariable
tags map[string]*tagmanager.Tag triggers map[string]*tagmanager.Trigger
tags map[string]*tagmanager.Tag
} }
ClientOption func(*Client) ClientOption func(*Client)
) )
@ -67,17 +69,13 @@ func ClientWithClientOptions(v ...option.ClientOption) ClientOption {
// ~ Constructor // ~ Constructor
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
func NewClient(ctx context.Context, accountID, containerID, workspaceID, measurementID string, opts ...ClientOption) (*Client, error) { func NewClient(ctx context.Context, l *slog.Logger, accountID, containerID, workspaceID, measurementID string, opts ...ClientOption) (*Client, error) {
inst := &Client{ inst := &Client{
l: l,
accountID: accountID, accountID: accountID,
containerID: containerID, containerID: containerID,
workspaceID: workspaceID, workspaceID: workspaceID,
measurementID: measurementID, measurementID: measurementID,
clients: map[string]*tagmanager.Client{},
folders: map[string]*tagmanager.Folder{},
variables: map[string]*tagmanager.Variable{},
triggers: map[string]*tagmanager.Trigger{},
tags: map[string]*tagmanager.Tag{},
notes: "Managed by Sesamy. DO NOT EDIT.", notes: "Managed by Sesamy. DO NOT EDIT.",
folderName: "Sesamy", folderName: "Sesamy",
clientOptions: []option.ClientOption{ clientOptions: []option.ClientOption{
@ -145,127 +143,149 @@ func (c *Client) WorkspacePath() string {
return c.ContainerPath() + "/workspaces/" + c.workspaceID return c.ContainerPath() + "/workspaces/" + c.workspaceID
} }
// ------------------------------------------------------------------------------------------------
// ~ Public methods
// ------------------------------------------------------------------------------------------------
func (c *Client) Client(name string) (*tagmanager.Client, error) { func (c *Client) Client(name string) (*tagmanager.Client, error) {
if _, ok := c.clients[name]; !ok { if c.clients == nil {
c.clients = map[string]*tagmanager.Client{}
c.l.Debug("listing", "type", "Client")
r, err := c.Service().Accounts.Containers.Workspaces.Clients.List(c.WorkspacePath()).Do() r, err := c.Service().Accounts.Containers.Workspaces.Clients.List(c.WorkspacePath()).Do()
if err != nil { if err != nil {
return nil, err return nil, err
} }
var found bool
for _, value := range r.Client { for _, value := range r.Client {
if value.Name == name { c.clients[name] = value
c.clients[name] = value
found = true
break
}
}
if !found {
return nil, ErrNotFound
} }
} }
if _, ok := c.clients[name]; !ok {
return nil, ErrNotFound
}
return c.clients[name], nil return c.clients[name], nil
} }
func (c *Client) Folder(name string) (*tagmanager.Folder, error) { func (c *Client) Folder(name string) (*tagmanager.Folder, error) {
if _, ok := c.folders[name]; !ok { if c.folders == nil {
c.folders = map[string]*tagmanager.Folder{}
c.l.Debug("listing", "type", "Folder")
r, err := c.Service().Accounts.Containers.Workspaces.Folders.List(c.WorkspacePath()).Do() r, err := c.Service().Accounts.Containers.Workspaces.Folders.List(c.WorkspacePath()).Do()
if err != nil { if err != nil {
return nil, err return nil, err
} }
var found bool
for _, value := range r.Folder { for _, value := range r.Folder {
if value.Name == name { c.folders[name] = value
c.folders[name] = value
found = true
break
}
}
if !found {
return nil, ErrNotFound
} }
} }
if _, ok := c.folders[name]; !ok {
return nil, ErrNotFound
}
return c.folders[name], nil return c.folders[name], nil
} }
func (c *Client) Variable(name string) (*tagmanager.Variable, error) { func (c *Client) Variable(name string) (*tagmanager.Variable, error) {
if _, ok := c.variables[name]; !ok { if c.variables == nil {
c.variables = map[string]*tagmanager.Variable{}
c.l.Debug("listing", "type", "Variable")
r, err := c.Service().Accounts.Containers.Workspaces.Variables.List(c.WorkspacePath()).Do() r, err := c.Service().Accounts.Containers.Workspaces.Variables.List(c.WorkspacePath()).Do()
if err != nil { if err != nil {
return nil, err return nil, err
} }
var found bool
for _, value := range r.Variable { for _, value := range r.Variable {
if value.Name == name { c.variables[name] = value
c.variables[name] = value
found = true
break
}
} }
}
if !found { if _, ok := c.variables[name]; !ok {
return nil, ErrNotFound return nil, ErrNotFound
}
} }
return c.variables[name], nil return c.variables[name], nil
} }
func (c *Client) BuiltInVariable(name string) (*tagmanager.Variable, error) {
if c.builtInVariables == nil {
c.builtInVariables = map[string]*tagmanager.BuiltInVariable{}
c.l.Debug("listing", "type", "Built-In Variable")
r, err := c.Service().Accounts.Containers.Workspaces.BuiltInVariables.List(c.WorkspacePath()).Do()
if err != nil {
return nil, err
}
for _, value := range r.BuiltInVariable {
c.builtInVariables[value.Type] = value
}
}
if _, ok := c.variables[name]; !ok {
return nil, ErrNotFound
}
return c.variables[name], nil
}
func (c *Client) Trigger(name string) (*tagmanager.Trigger, error) { func (c *Client) Trigger(name string) (*tagmanager.Trigger, error) {
if _, ok := c.triggers[name]; !ok { if c.triggers == nil {
c.triggers = map[string]*tagmanager.Trigger{}
c.l.Debug("listing", "type", "Trigger")
r, err := c.Service().Accounts.Containers.Workspaces.Triggers.List(c.WorkspacePath()).Do() r, err := c.Service().Accounts.Containers.Workspaces.Triggers.List(c.WorkspacePath()).Do()
if err != nil { if err != nil {
return nil, err return nil, err
} }
var found bool
for _, value := range r.Trigger { for _, value := range r.Trigger {
if value.Name == name { c.triggers[name] = value
c.triggers[name] = value
found = true
break
}
} }
}
if !found { if _, ok := c.triggers[name]; !ok {
return nil, ErrNotFound return nil, ErrNotFound
}
} }
return c.triggers[name], nil return c.triggers[name], nil
} }
func (c *Client) Tag(name string) (*tagmanager.Tag, error) { func (c *Client) Tag(name string) (*tagmanager.Tag, error) {
if _, ok := c.tags[name]; !ok { if c.tags == nil {
c.tags = map[string]*tagmanager.Tag{}
c.l.Debug("listing", "type", "Tag")
r, err := c.Service().Accounts.Containers.Workspaces.Tags.List(c.WorkspacePath()).Do() r, err := c.Service().Accounts.Containers.Workspaces.Tags.List(c.WorkspacePath()).Do()
if err != nil { if err != nil {
return nil, err return nil, err
} }
var found bool
for _, value := range r.Tag { for _, value := range r.Tag {
if value.Name == name { c.tags[name] = value
c.tags[name] = value
found = true
break
}
}
if !found {
return nil, ErrNotFound
} }
} }
if _, ok := c.tags[name]; !ok {
return nil, ErrNotFound
}
return c.tags[name], nil return c.tags[name], nil
} }
// ------------------------------------------------------------------------------------------------ func (c *Client) UpsertClient(client *tagmanager.Client) (*tagmanager.Client, error) {
// ~ Public methods l := c.l.With("type", "Client", "name", client.Name)
// ------------------------------------------------------------------------------------------------
func (c *Client) UpsertGA4Client(name string) (*tagmanager.Client, error) { client.AccountId = c.AccountID()
cache, err := c.Client(name) client.ContainerId = c.ContainerID()
client.WorkspaceId = c.WorkspaceID()
client.Notes = c.Notes()
cache, err := c.Client(client.Name)
if err != nil && !errors.Is(err, ErrNotFound) { if err != nil && !errors.Is(err, ErrNotFound) {
return nil, err return nil, err
} }
@ -274,119 +294,31 @@ func (c *Client) UpsertGA4Client(name string) (*tagmanager.Client, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
client.ParentFolderId = folder.FolderId
obj := &tagmanager.Client{
AccountId: c.accountID,
ContainerId: c.containerID,
WorkspaceId: c.workspaceID,
ParentFolderId: folder.FolderId,
Name: name,
Notes: c.notes,
Parameter: []*tagmanager.Parameter{
{
Type: "boolean",
Key: "activateGtagSupport",
Value: "false",
},
{
Type: "boolean",
Key: "activateDefaultPaths",
Value: "true",
},
{
Type: "template",
Key: "cookieManagement",
Value: "js",
},
},
Type: "gaaw_client",
}
if cache == nil { if cache == nil {
c.clients[name], err = c.Service().Accounts.Containers.Workspaces.Clients.Create(c.WorkspacePath(), obj).Do() l.Info("creating")
c.clients[client.Name], err = c.Service().Accounts.Containers.Workspaces.Clients.Create(c.WorkspacePath(), client).Do()
} else { } else {
c.clients[name], err = c.Service().Accounts.Containers.Workspaces.Clients.Update(c.WorkspacePath()+"/clients/"+cache.ClientId, obj).Do() l.Info("updating")
c.clients[client.Name], err = c.Service().Accounts.Containers.Workspaces.Clients.Update(c.WorkspacePath()+"/clients/"+cache.ClientId, client).Do()
} }
if err != nil { if err != nil {
return nil, err return nil, err
} }
return c.Client(name) return c.Client(client.Name)
}
func (c *Client) UpsertGTMClient(name, webContainerMeasurementID string) (*tagmanager.Client, error) {
cache, err := c.Client(name)
if err != nil && !errors.Is(err, ErrNotFound) {
return nil, err
}
folder, err := c.Folder(c.folderName)
if err != nil {
return nil, err
}
obj := &tagmanager.Client{
AccountId: c.accountID,
ContainerId: c.containerID,
WorkspaceId: c.workspaceID,
ParentFolderId: folder.FolderId,
Name: name,
Notes: c.notes,
Parameter: []*tagmanager.Parameter{
{
Type: "boolean",
Key: "activateResponseCompression",
Value: "true",
},
{
Type: "boolean",
Key: "activateGeoResolution",
Value: "false",
},
{
Type: "boolean",
Key: "activateDependencyServing",
Value: "true",
},
{
Type: "list",
Key: "allowedContainerIds",
List: []*tagmanager.Parameter{
{
Type: "map",
Map: []*tagmanager.Parameter{
{
Type: "template",
Key: "containerId",
Value: webContainerMeasurementID,
},
},
},
},
},
},
Type: "gtm_client",
}
if cache == nil {
c.clients[name], err = c.Service().Accounts.Containers.Workspaces.Clients.Create(c.WorkspacePath(), obj).Do()
} else {
c.clients[name], err = c.Service().Accounts.Containers.Workspaces.Clients.Update(c.WorkspacePath()+"/clients/"+cache.ClientId, obj).Do()
}
if err != nil {
return nil, err
}
return c.Client(name)
} }
func (c *Client) UpsertFolder(name string) (*tagmanager.Folder, error) { func (c *Client) UpsertFolder(name string) (*tagmanager.Folder, error) {
l := c.l.With("type", "Folder", "name", name)
cache, err := c.Folder(name) cache, err := c.Folder(name)
if err != nil && !errors.Is(err, ErrNotFound) && !errors.Is(err, ErrNotFound) { if err != nil && !errors.Is(err, ErrNotFound) && !errors.Is(err, ErrNotFound) {
return nil, err return nil, err
} }
obj := &tagmanager.Folder{ folder := &tagmanager.Folder{
AccountId: c.accountID, AccountId: c.accountID,
ContainerId: c.containerID, ContainerId: c.containerID,
WorkspaceId: c.workspaceID, WorkspaceId: c.workspaceID,
@ -395,9 +327,11 @@ func (c *Client) UpsertFolder(name string) (*tagmanager.Folder, error) {
} }
if cache == nil { if cache == nil {
c.folders[name], err = c.Service().Accounts.Containers.Workspaces.Folders.Create(c.WorkspacePath(), obj).Do() l.Info("creating")
c.folders[name], err = c.Service().Accounts.Containers.Workspaces.Folders.Create(c.WorkspacePath(), folder).Do()
} else { } else {
c.folders[name], err = c.Service().Accounts.Containers.Workspaces.Folders.Update(c.WorkspacePath()+"/folders/"+cache.FolderId, obj).Do() l.Info("updating")
c.folders[name], err = c.Service().Accounts.Containers.Workspaces.Folders.Update(c.WorkspacePath()+"/folders/"+cache.FolderId, folder).Do()
} }
if err != nil { if err != nil {
return nil, err return nil, err
@ -407,6 +341,13 @@ func (c *Client) UpsertFolder(name string) (*tagmanager.Folder, error) {
} }
func (c *Client) UpsertVariable(variable *tagmanager.Variable) (*tagmanager.Variable, error) { func (c *Client) UpsertVariable(variable *tagmanager.Variable) (*tagmanager.Variable, error) {
l := c.l.With("type", "Variable", "name", variable.Name)
variable.AccountId = c.AccountID()
variable.ContainerId = c.ContainerID()
variable.WorkspaceId = c.WorkspaceID()
variable.Notes = c.Notes()
cache, err := c.Variable(variable.Name) cache, err := c.Variable(variable.Name)
if err != nil && !errors.Is(err, ErrNotFound) { if err != nil && !errors.Is(err, ErrNotFound) {
return nil, err return nil, err
@ -419,8 +360,10 @@ func (c *Client) UpsertVariable(variable *tagmanager.Variable) (*tagmanager.Vari
variable.ParentFolderId = folder.FolderId variable.ParentFolderId = folder.FolderId
if cache == nil { if cache == nil {
l.Info("creating")
c.variables[variable.Name], err = c.Service().Accounts.Containers.Workspaces.Variables.Create(c.WorkspacePath(), variable).Do() c.variables[variable.Name], err = c.Service().Accounts.Containers.Workspaces.Variables.Create(c.WorkspacePath(), variable).Do()
} else { } else {
l.Info("updating")
c.variables[variable.Name], err = c.Service().Accounts.Containers.Workspaces.Variables.Update(c.WorkspacePath()+"/variables/"+cache.VariableId, variable).Do() c.variables[variable.Name], err = c.Service().Accounts.Containers.Workspaces.Variables.Update(c.WorkspacePath()+"/variables/"+cache.VariableId, variable).Do()
} }
if err != nil { if err != nil {
@ -430,149 +373,39 @@ func (c *Client) UpsertVariable(variable *tagmanager.Variable) (*tagmanager.Vari
return c.Variable(variable.Name) return c.Variable(variable.Name)
} }
func (c *Client) UpsertConstantVariable(name, value string) (*tagmanager.Variable, error) { func (c *Client) EnableBuiltInVariable(name string) (*tagmanager.Variable, error) {
obj := &tagmanager.Variable{ l := c.l.With("type", "Built-In Variable", "name", name)
AccountId: c.accountID,
ContainerId: c.containerID, cache, err := c.BuiltInVariable(name)
WorkspaceId: c.workspaceID, if err != nil && !errors.Is(err, ErrNotFound) {
Name: "Constant." + name, return nil, err
Notes: c.notes,
Parameter: []*tagmanager.Parameter{
{
Key: "value",
Type: "template",
Value: value,
},
},
Type: "c",
} }
return c.UpsertVariable(obj)
if cache != nil {
return cache, nil
}
l.Info("creating")
resp, err := c.Service().Accounts.Containers.Workspaces.BuiltInVariables.Create(c.WorkspacePath()).Type(name).Do()
if err != nil {
return nil, err
}
for _, builtInVariable := range resp.BuiltInVariable {
c.builtInVariables[builtInVariable.Name] = builtInVariable
}
return c.BuiltInVariable(name)
} }
func (c *Client) UpsertEventModelVariable(name string) (*tagmanager.Variable, error) { func (c *Client) UpsertTrigger(trigger *tagmanager.Trigger) (*tagmanager.Trigger, error) {
obj := &tagmanager.Variable{ l := c.l.With("type", "Trigger", "name", trigger.Name)
AccountId: c.accountID,
ContainerId: c.containerID,
WorkspaceId: c.workspaceID,
Name: "EventModel." + name,
Notes: c.notes,
Parameter: []*tagmanager.Parameter{
{
Key: "dataLayerVersion",
Type: "integer",
Value: "2",
},
{
Key: "setDefaultValue",
Type: "boolean",
Value: "false",
},
{
Key: "name",
Type: "template",
Value: "eventModel." + name,
},
},
Type: "v",
}
return c.UpsertVariable(obj)
}
func (c *Client) UpsertGTEventSettingsVariable(name string, variables map[string]*tagmanager.Variable) (*tagmanager.Variable, error) { trigger.AccountId = c.AccountID()
fullname := "GTEventSettings." + name trigger.ContainerId = c.ContainerID()
trigger.WorkspaceId = c.WorkspaceID()
trigger.Notes = c.Notes()
parameters := make([]string, 0, len(variables)) cache, err := c.Trigger(trigger.Name)
for k := range variables {
parameters = append(parameters, k)
}
sort.Strings(parameters)
list := make([]*tagmanager.Parameter, len(parameters))
for i, parameter := range parameters {
list[i] = &tagmanager.Parameter{
Type: "map",
Map: []*tagmanager.Parameter{
{
Key: "parameter",
Type: "template",
Value: parameter,
},
{
Key: "parameterValue",
Type: "template",
Value: "{{" + variables[parameter].Name + "}}",
},
},
}
}
obj := &tagmanager.Variable{
AccountId: c.accountID,
ContainerId: c.containerID,
WorkspaceId: c.workspaceID,
Name: fullname,
Notes: c.notes,
Parameter: []*tagmanager.Parameter{
{
Key: "eventSettingsTable",
Type: "list",
List: list,
},
},
Type: "gtes",
}
return c.UpsertVariable(obj)
}
func (c *Client) UpsertGoogleTagSettingsVariable(name string, variables map[string]*tagmanager.Variable) (*tagmanager.Variable, error) {
parameters := make([]string, 0, len(variables))
for k := range variables {
parameters = append(parameters, k)
}
sort.Strings(parameters)
list := make([]*tagmanager.Parameter, len(parameters))
for i, parameter := range parameters {
list[i] = &tagmanager.Parameter{
Type: "map",
Map: []*tagmanager.Parameter{
{
Key: "parameter",
Type: "template",
Value: parameter,
},
{
Key: "parameterValue",
Type: "template",
Value: "{{" + variables[parameter].Name + "}}",
},
},
}
}
obj := &tagmanager.Variable{
AccountId: c.accountID,
ContainerId: c.containerID,
WorkspaceId: c.workspaceID,
Name: name,
Notes: c.notes,
Parameter: []*tagmanager.Parameter{
{
Key: "configSettingsTable",
Type: "list",
List: list,
},
},
Type: "gtcs",
}
return c.UpsertVariable(obj)
}
func (c *Client) UpsertCustomEventTrigger(name string) (*tagmanager.Trigger, error) {
fullname := "Event." + name
cache, err := c.Trigger(fullname)
if err != nil && !errors.Is(err, ErrNotFound) { if err != nil && !errors.Is(err, ErrNotFound) {
return nil, err return nil, err
} }
@ -581,49 +414,31 @@ func (c *Client) UpsertCustomEventTrigger(name string) (*tagmanager.Trigger, err
if err != nil { if err != nil {
return nil, err return nil, err
} }
trigger.ParentFolderId = folder.FolderId
obj := &tagmanager.Trigger{
AccountId: c.accountID,
ContainerId: c.containerID,
WorkspaceId: c.workspaceID,
ParentFolderId: folder.FolderId,
Type: "customEvent",
Name: fullname,
Notes: c.notes,
CustomEventFilter: []*tagmanager.Condition{
{
Parameter: []*tagmanager.Parameter{
{
Key: "arg0",
Type: "template",
Value: "{{_event}}",
},
{
Key: "arg1",
Type: "template",
Value: name,
},
},
Type: "equals",
},
},
}
if cache == nil { if cache == nil {
c.triggers[fullname], err = c.Service().Accounts.Containers.Workspaces.Triggers.Create(c.WorkspacePath(), obj).Do() l.Info("creating")
c.triggers[trigger.Name], err = c.Service().Accounts.Containers.Workspaces.Triggers.Create(c.WorkspacePath(), trigger).Do()
} else { } else {
c.triggers[fullname], err = c.Service().Accounts.Containers.Workspaces.Triggers.Update(c.WorkspacePath()+"/triggers/"+cache.TriggerId, obj).Do() l.Info("updating")
c.triggers[trigger.Name], err = c.Service().Accounts.Containers.Workspaces.Triggers.Update(c.WorkspacePath()+"/triggers/"+cache.TriggerId, trigger).Do()
} }
if err != nil { if err != nil {
return nil, err return nil, err
} }
return c.Trigger(fullname) return c.Trigger(trigger.Name)
} }
func (c *Client) UpsertClientTrigger(name string, client *tagmanager.Client) (*tagmanager.Trigger, error) { func (c *Client) UpsertTag(tag *tagmanager.Tag) (*tagmanager.Tag, error) {
fullname := "Client." + name l := c.l.With("type", "Tag", "name", tag.Name)
cache, err := c.Trigger(fullname)
tag.AccountId = c.AccountID()
tag.ContainerId = c.ContainerID()
tag.WorkspaceId = c.WorkspaceID()
tag.Notes = c.Notes()
cache, err := c.Tag(tag.Name)
if err != nil && !errors.Is(err, ErrNotFound) { if err != nil && !errors.Is(err, ErrNotFound) {
return nil, err return nil, err
} }
@ -632,248 +447,18 @@ func (c *Client) UpsertClientTrigger(name string, client *tagmanager.Client) (*t
if err != nil { if err != nil {
return nil, err return nil, err
} }
tag.ParentFolderId = folder.FolderId
obj := &tagmanager.Trigger{
AccountId: c.accountID,
ContainerId: c.containerID,
WorkspaceId: c.workspaceID,
ParentFolderId: folder.FolderId,
Type: "always",
Name: fullname,
Notes: c.notes,
Filter: []*tagmanager.Condition{
{
Parameter: []*tagmanager.Parameter{
{
Key: "arg0",
Type: "template",
Value: "{{Client Name}}",
},
{
Key: "arg1",
Type: "template",
Value: client.Name,
},
},
Type: "equals",
},
},
}
if cache == nil { if cache == nil {
c.triggers[fullname], err = c.Service().Accounts.Containers.Workspaces.Triggers.Create(c.WorkspacePath(), obj).Do() l.Info("creating")
c.tags[tag.Name], err = c.Service().Accounts.Containers.Workspaces.Tags.Create(c.WorkspacePath(), tag).Do()
} else { } else {
c.triggers[fullname], err = c.Service().Accounts.Containers.Workspaces.Triggers.Update(c.WorkspacePath()+"/triggers/"+cache.TriggerId, obj).Do() l.Info("updating")
c.tags[tag.Name], err = c.Service().Accounts.Containers.Workspaces.Tags.Update(c.WorkspacePath()+"/tags/"+cache.TagId, tag).Do()
} }
if err != nil { if err != nil {
return nil, err return nil, err
} }
return c.Trigger(fullname) return c.Tag(tag.Name)
}
func (c *Client) UpsertGA4WebTag(name string, eventSettings *tagmanager.Variable, measurementID *tagmanager.Variable, trigger *tagmanager.Trigger) (*tagmanager.Tag, error) {
fullname := "GA4." + name
cache, err := c.Tag(fullname)
if err != nil && !errors.Is(err, ErrNotFound) {
return nil, err
}
folder, err := c.Folder(c.folderName)
if err != nil {
return nil, err
}
obj := &tagmanager.Tag{
AccountId: c.accountID,
ContainerId: c.containerID,
WorkspaceId: c.workspaceID,
FiringTriggerId: []string{trigger.TriggerId},
ParentFolderId: folder.FolderId,
Name: fullname,
Notes: c.notes,
Parameter: []*tagmanager.Parameter{
{
Type: "boolean",
Key: "sendEcommerceData",
Value: "false",
},
{
Type: "boolean",
Key: "enhancedUserId",
Value: "false",
},
{
Type: "template",
Key: "eventName",
Value: name,
},
{
Type: "template",
Key: "measurementIdOverride",
Value: "{{" + measurementID.Name + "}}",
},
{
Type: "template",
Key: "eventSettingsVariable",
Value: "{{" + eventSettings.Name + "}}",
},
},
Type: "gaawe",
}
// if len(parameters) > 0 {
// list := &tagmanager.Parameter{
// Type: "list",
// Key: "eventSettingsTable",
// List: []*tagmanager.Parameter{},
// }
//
// for _, parameterName := range parameters {
// param, err := c.UpsertEventModelVariable(parameterName)
// if err != nil {
// return nil, err
// }
// list.List = append(list.List, &tagmanager.Parameter{
// Type: "map",
// Map: []*tagmanager.Parameter{
// {
// Type: "template",
// Key: "parameter",
// Value: parameterName,
// },
// {
// Type: "template",
// Key: "parameterValue",
// Value: "{{" + param.Name + "}}",
// },
// },
// })
// }
// obj.Parameter = append(obj.Parameter, list)
// }
if cache == nil {
c.tags[fullname], err = c.Service().Accounts.Containers.Workspaces.Tags.Create(c.WorkspacePath(), obj).Do()
} else {
c.tags[fullname], err = c.Service().Accounts.Containers.Workspaces.Tags.Update(c.WorkspacePath()+"/tags/"+cache.TagId, obj).Do()
}
if err != nil {
return nil, err
}
return c.Tag(fullname)
}
func (c *Client) UpsertGoogleTagWebTag(name string, measurementID *tagmanager.Variable, configSettings *tagmanager.Variable) (*tagmanager.Tag, error) {
cache, err := c.Tag(name)
if err != nil && !errors.Is(err, ErrNotFound) {
return nil, err
}
folder, err := c.Folder(c.folderName)
if err != nil {
return nil, err
}
obj := &tagmanager.Tag{
AccountId: c.accountID,
ContainerId: c.containerID,
WorkspaceId: c.workspaceID,
FiringTriggerId: []string{"2147479573"},
ParentFolderId: folder.FolderId,
Name: name,
Notes: c.notes,
Parameter: []*tagmanager.Parameter{
{
Key: "tagId",
Type: "template",
Value: "{{" + measurementID.Name + "}}",
},
{
Key: "configSettingsVariable",
Type: "template",
Value: "{{" + configSettings.Name + "}}",
},
},
Type: "googtag",
}
if cache == nil {
c.tags[name], err = c.Service().Accounts.Containers.Workspaces.Tags.Create(c.WorkspacePath(), obj).Do()
} else {
c.tags[name], err = c.Service().Accounts.Containers.Workspaces.Tags.Update(c.WorkspacePath()+"/tags/"+cache.TagId, obj).Do()
}
if err != nil {
return nil, err
}
return c.Tag(name)
}
func (c *Client) UpsertGA4ServerTag(name string, measurementID *tagmanager.Variable, trigger *tagmanager.Trigger) (*tagmanager.Tag, error) {
cache, err := c.Tag(name)
if err != nil && !errors.Is(err, ErrNotFound) {
return nil, err
}
folder, err := c.Folder(c.folderName)
if err != nil {
return nil, err
}
obj := &tagmanager.Tag{
AccountId: c.accountID,
ContainerId: c.containerID,
WorkspaceId: c.workspaceID,
FiringTriggerId: []string{trigger.TriggerId},
ParentFolderId: folder.FolderId,
Name: name,
Notes: c.notes,
Parameter: []*tagmanager.Parameter{
{
Type: "boolean",
Key: "redactVisitorIp",
Value: "false",
},
{
Type: "template",
Key: "epToIncludeDropdown",
Value: "all",
},
{
Type: "boolean",
Key: "enableGoogleSignals",
Value: "false",
},
{
Type: "template",
Key: "upToIncludeDropdown",
Value: "all",
},
{
Type: "template",
Key: "measurementId",
Value: "{{" + measurementID.Name + "}}",
},
{
Type: "boolean",
Key: "enableEuid",
Value: "false",
},
},
Type: "sgtmgaaw",
}
if cache == nil {
c.tags[name], err = c.Service().Accounts.Containers.Workspaces.Tags.Create(c.WorkspacePath(), obj).Do()
} else {
c.tags[name], err = c.Service().Accounts.Containers.Workspaces.Tags.Update(c.WorkspacePath()+"/tags/"+cache.TagId, obj).Do()
}
if err != nil {
return nil, err
}
return c.Tag(name)
} }

View File

@ -0,0 +1,29 @@
package client
import (
"google.golang.org/api/tagmanager/v2"
)
func NewGA4(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",
}
}

View File

@ -0,0 +1,45 @@
package client
import (
"google.golang.org/api/tagmanager/v2"
)
func NewGTM(name string, webContainerMeasurementID *tagmanager.Variable) *tagmanager.Client {
return &tagmanager.Client{
Name: name,
Parameter: []*tagmanager.Parameter{
{
Type: "boolean",
Key: "activateResponseCompression",
Value: "true",
},
{
Type: "boolean",
Key: "activateGeoResolution",
Value: "false",
},
{
Type: "boolean",
Key: "activateDependencyServing",
Value: "true",
},
{
Type: "list",
Key: "allowedContainerIds",
List: []*tagmanager.Parameter{
{
Type: "map",
Map: []*tagmanager.Parameter{
{
Type: "template",
Key: "containerId",
Value: "{{" + webContainerMeasurementID.Name + "}}",
},
},
},
},
},
},
Type: "gtm_client",
}
}

View File

@ -4,12 +4,15 @@ import (
"bytes" "bytes"
"context" "context"
"encoding/json" "encoding/json"
"log/slog"
"os" "os"
"reflect" "reflect"
"strings" "strings"
"testing" "testing"
"github.com/foomo/sesamy-cli/pkg/tagmanager" "github.com/foomo/sesamy-cli/pkg/tagmanager"
"github.com/foomo/sesamy-cli/pkg/tagmanager/trigger"
"github.com/foomo/sesamy-cli/pkg/tagmanager/variable"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"google.golang.org/api/option" "google.golang.org/api/option"
@ -17,10 +20,11 @@ import (
) )
func TestNewClient_Server(t *testing.T) { func TestNewClient_Server(t *testing.T) {
t.Skip() // t.Skip()
c, err := tagmanager.NewClient( c, err := tagmanager.NewClient(
context.TODO(), context.TODO(),
slog.New(slog.NewTextHandler(os.Stdout, nil)),
os.Getenv("TEST_ACCOUNT_ID"), os.Getenv("TEST_ACCOUNT_ID"),
os.Getenv("TEST_SERVER_CONTAINER_ID"), os.Getenv("TEST_SERVER_CONTAINER_ID"),
os.Getenv("TEST_SERVER_WORKSPACE_ID"), os.Getenv("TEST_SERVER_WORKSPACE_ID"),
@ -41,13 +45,28 @@ func TestNewClient_Server(t *testing.T) {
{ // --- Variables --- { // --- Variables ---
t.Run("upsert GTM client", func(t *testing.T) { t.Run("upsert GTM client", func(t *testing.T) {
client, err := c.UpsertConstantVariable("web-container-id", os.Getenv("TEST_WEB_CONTAINER_GID")) client, err := c.UpsertVariable(variable.NewConstant("web-container-id", os.Getenv("TEST_WEB_CONTAINER_GID")))
if assert.NoError(t, err) { if assert.NoError(t, err) {
dump(t, client) dump(t, client)
} }
}) })
} }
{ // --- Built-In Variables ---
t.Run("list built-in variables", func(t *testing.T) {
cmd := c.Service().Accounts.Containers.Workspaces.BuiltInVariables.List(c.WorkspacePath())
if r, err := cmd.Do(); assert.NoError(t, err) {
dump(t, r)
}
})
t.Run("list built-in variables", func(t *testing.T) {
cmd := c.Service().Accounts.Containers.Workspaces.BuiltInVariables.Create(c.WorkspacePath()).Type()
if r, err := cmd.Do(); assert.NoError(t, err) {
dump(t, r)
}
})
}
{ // --- Clients --- { // --- Clients ---
t.Run("list clients", func(t *testing.T) { t.Run("list clients", func(t *testing.T) {
cmd := c.Service().Accounts.Containers.Workspaces.Clients.List(c.WorkspacePath()) cmd := c.Service().Accounts.Containers.Workspaces.Clients.List(c.WorkspacePath())
@ -56,12 +75,12 @@ func TestNewClient_Server(t *testing.T) {
} }
}) })
t.Run("upsert GTM client", func(t *testing.T) { // t.Run("upsert GTM client", func(t *testing.T) {
client, err := c.UpsertGTMClient("Google Tag Manager Web Container", "Constant.web-container-id") // client, err := c.UpsertClient(client2.NewGTM("Google Tag Manager Web Container", "Constant.web-container-id"))
if assert.NoError(t, err) { // if assert.NoError(t, err) {
dump(t, client) // dump(t, client)
} // }
}) // })
} }
{ // --- Triggers --- { // --- Triggers ---
@ -84,10 +103,11 @@ func TestNewClient_Server(t *testing.T) {
} }
func TestNewClient_Web(t *testing.T) { func TestNewClient_Web(t *testing.T) {
t.Skip() // t.Skip()
c, err := tagmanager.NewClient( c, err := tagmanager.NewClient(
context.TODO(), context.TODO(),
slog.New(slog.NewTextHandler(os.Stdout, nil)),
os.Getenv("TEST_ACCOUNT_ID"), os.Getenv("TEST_ACCOUNT_ID"),
os.Getenv("TEST_WEB_CONTAINER_ID"), os.Getenv("TEST_WEB_CONTAINER_ID"),
os.Getenv("TEST_WEB_WORKSPACE_ID"), os.Getenv("TEST_WEB_WORKSPACE_ID"),
@ -222,7 +242,7 @@ func TestNewClient_Web(t *testing.T) {
}) })
t.Run("upsert variable", func(t *testing.T) { t.Run("upsert variable", func(t *testing.T) {
obj, err := c.UpsertConstantVariable(name, c.MeasurementID()) obj, err := c.UpsertVariable(variable.NewConstant(name, c.MeasurementID()))
require.NoError(t, err) require.NoError(t, err)
t.Log("ID: " + obj.VariableId) t.Log("ID: " + obj.VariableId)
}) })
@ -283,7 +303,7 @@ func TestNewClient_Web(t *testing.T) {
}) })
t.Run("upsert trigger", func(t *testing.T) { t.Run("upsert trigger", func(t *testing.T) {
obj, err := c.UpsertCustomEventTrigger(name) obj, err := c.UpsertTrigger(trigger.NewCustomEvent("Event."+name, name))
require.NoError(t, err) require.NoError(t, err)
t.Log("ID: " + obj.TriggerId) t.Log("ID: " + obj.TriggerId)
}) })

View File

@ -0,0 +1,40 @@
package client
import (
"google.golang.org/api/tagmanager/v2"
)
func NewGA4Event(name, eventName string, eventSettings *tagmanager.Variable, measurementID *tagmanager.Variable, trigger *tagmanager.Trigger) *tagmanager.Tag {
return &tagmanager.Tag{
FiringTriggerId: []string{trigger.TriggerId},
Name: name,
Parameter: []*tagmanager.Parameter{
{
Type: "boolean",
Key: "sendEcommerceData",
Value: "false",
},
{
Type: "boolean",
Key: "enhancedUserId",
Value: "false",
},
{
Type: "template",
Key: "eventName",
Value: eventName,
},
{
Type: "template",
Key: "measurementIdOverride",
Value: "{{" + measurementID.Name + "}}",
},
{
Type: "template",
Key: "eventSettingsVariable",
Value: "{{" + eventSettings.Name + "}}",
},
},
Type: "gaawe",
}
}

View File

@ -0,0 +1,25 @@
package client
import (
"google.golang.org/api/tagmanager/v2"
)
func NewGoogleTag(name string, measurementID *tagmanager.Variable, configSettings *tagmanager.Variable) *tagmanager.Tag {
return &tagmanager.Tag{
FiringTriggerId: []string{"2147479573"}, // TODO
Name: name,
Parameter: []*tagmanager.Parameter{
{
Key: "tagId",
Type: "template",
Value: "{{" + measurementID.Name + "}}",
},
{
Key: "configSettingsVariable",
Type: "template",
Value: "{{" + configSettings.Name + "}}",
},
},
Type: "googtag",
}
}

View File

@ -0,0 +1,45 @@
package client
import (
"google.golang.org/api/tagmanager/v2"
)
func NewServerGA4Event(name string, measurementID *tagmanager.Variable, trigger *tagmanager.Trigger) *tagmanager.Tag {
return &tagmanager.Tag{
FiringTriggerId: []string{trigger.TriggerId},
Name: name,
Parameter: []*tagmanager.Parameter{
{
Type: "boolean",
Key: "redactVisitorIp",
Value: "false",
},
{
Type: "template",
Key: "epToIncludeDropdown",
Value: "all",
},
{
Type: "boolean",
Key: "enableGoogleSignals",
Value: "false",
},
{
Type: "template",
Key: "upToIncludeDropdown",
Value: "all",
},
{
Type: "template",
Key: "measurementId",
Value: "{{" + measurementID.Name + "}}",
},
{
Type: "boolean",
Key: "enableEuid",
Value: "false",
},
},
Type: "sgtmgaaw",
}
}

View File

@ -0,0 +1,29 @@
package trigger
import (
"google.golang.org/api/tagmanager/v2"
)
func NewClient(name string, client *tagmanager.Client) *tagmanager.Trigger {
return &tagmanager.Trigger{
Type: "always",
Name: name,
Filter: []*tagmanager.Condition{
{
Parameter: []*tagmanager.Parameter{
{
Key: "arg0",
Type: "template",
Value: "{{Client Name}}",
},
{
Key: "arg1",
Type: "template",
Value: client.Name,
},
},
Type: "equals",
},
},
}
}

View File

@ -0,0 +1,29 @@
package trigger
import (
"google.golang.org/api/tagmanager/v2"
)
func NewCustomEvent(name, eventName string) *tagmanager.Trigger {
return &tagmanager.Trigger{
Type: "customEvent",
Name: name,
CustomEventFilter: []*tagmanager.Condition{
{
Parameter: []*tagmanager.Parameter{
{
Key: "arg0",
Type: "template",
Value: "{{_event}}",
},
{
Key: "arg1",
Type: "template",
Value: eventName,
},
},
Type: "equals",
},
},
}
}

View File

@ -0,0 +1,19 @@
package variable
import (
"google.golang.org/api/tagmanager/v2"
)
func NewConstant(name, value string) *tagmanager.Variable {
return &tagmanager.Variable{
Name: name,
Parameter: []*tagmanager.Parameter{
{
Key: "value",
Type: "template",
Value: value,
},
},
Type: "c",
}
}

View File

@ -0,0 +1,29 @@
package variable
import (
"google.golang.org/api/tagmanager/v2"
)
func NewEventModel(name, parameterName string) *tagmanager.Variable {
return &tagmanager.Variable{
Name: name,
Parameter: []*tagmanager.Parameter{
{
Key: "dataLayerVersion",
Type: "integer",
Value: "2",
},
{
Key: "setDefaultValue",
Type: "boolean",
Value: "false",
},
{
Key: "name",
Type: "template",
Value: "eventModel." + parameterName,
},
},
Type: "v",
}
}

View File

@ -0,0 +1,46 @@
package variable
import (
"sort"
"google.golang.org/api/tagmanager/v2"
)
func NewGTEventSettings(name string, variables map[string]*tagmanager.Variable) *tagmanager.Variable {
parameters := make([]string, 0, len(variables))
for k := range variables {
parameters = append(parameters, k)
}
sort.Strings(parameters)
list := make([]*tagmanager.Parameter, len(parameters))
for i, parameter := range parameters {
list[i] = &tagmanager.Parameter{
Type: "map",
Map: []*tagmanager.Parameter{
{
Key: "parameter",
Type: "template",
Value: parameter,
},
{
Key: "parameterValue",
Type: "template",
Value: "{{" + variables[parameter].Name + "}}",
},
},
}
}
return &tagmanager.Variable{
Name: name,
Parameter: []*tagmanager.Parameter{
{
Key: "eventSettingsTable",
Type: "list",
List: list,
},
},
Type: "gtes",
}
}

View File

@ -0,0 +1,46 @@
package variable
import (
"sort"
"google.golang.org/api/tagmanager/v2"
)
func NewGTSettings(name string, variables map[string]*tagmanager.Variable) *tagmanager.Variable {
parameters := make([]string, 0, len(variables))
for k := range variables {
parameters = append(parameters, k)
}
sort.Strings(parameters)
list := make([]*tagmanager.Parameter, len(parameters))
for i, parameter := range parameters {
list[i] = &tagmanager.Parameter{
Type: "map",
Map: []*tagmanager.Parameter{
{
Key: "parameter",
Type: "template",
Value: parameter,
},
{
Key: "parameterValue",
Type: "template",
Value: "{{" + variables[parameter].Name + "}}",
},
},
}
}
return &tagmanager.Variable{
Name: name,
Parameter: []*tagmanager.Parameter{
{
Key: "configSettingsTable",
Type: "list",
List: list,
},
},
Type: "gtcs",
}
}