feat: add request quota throttle

This commit is contained in:
Kevin Franklin Kim 2024-03-08 23:12:53 +01:00
parent 678959c920
commit 604aadb998
No known key found for this signature in database
7 changed files with 270 additions and 278 deletions

View File

@ -1,12 +1,22 @@
# Sesamy CLI
[![Build Status](https://github.com/foomo/sesamy-cli/actions/workflows/test.yml/badge.svg?branch=main&event=push)](https://github.com/foomo/sesamy-cli/actions/workflows/test.yml)
[![Go Report Card](https://goreportcard.com/badge/github.com/foomo/sesamy-cli)](https://goreportcard.com/report/github.com/foomo/sesamy-cli)
[![godoc](https://godoc.org/github.com/foomo/sesamy-cli?status.svg)](https://godoc.org/github.com/foomo/sesamy-cli)
[![goreleaser](https://github.com/foomo/sesamy-cli/workflows/goreleaser/badge.svg)](https://github.com/foomo/sesamy-cli/actions)
[![goreleaser](https://github.com/foomo/sesamy-cli/actions/workflows/release.yml/badge.svg)](https://github.com/foomo/sesamy-cli/actions)
> CLI to keep you sane while working with GTM.
## Quickstart
## Installing
Install the latest release of the cli:
````bash
$ brew update
$ brew install foomo/tap/sesamy-cli
````
## Usage
Add a `sesamy.yaml` configurtion

View File

@ -12,56 +12,56 @@ var tagmanagerServerCmd = &cobra.Command{
Short: "Provision Google Tag Manager Server Container",
PersistentPreRunE: preRunReadConfig,
RunE: func(cmd *cobra.Command, args []string) error {
ctx := cmd.Context()
var opt option.ClientOption
var clientCredentialsOption option.ClientOption
if cfg.Google.CredentialsFile != "" {
opt = option.WithCredentialsFile(cfg.Google.CredentialsFile)
clientCredentialsOption = option.WithCredentialsFile(cfg.Google.CredentialsFile)
} else {
opt = option.WithCredentialsFile(cfg.Google.CredentialsJSON)
clientCredentialsOption = option.WithCredentialsJSON([]byte(cfg.Google.CredentialsJSON))
}
c, err := tagmanager.NewClient(
cmd.Context(),
cfg.Google.GTM.AccountID,
cfg.Google.GTM.Server.ContainerID,
cfg.Google.GTM.Server.WorkspaceID,
cfg.Google.GA4.MeasurementID,
tagmanager.ClientWithClientOptions(opt),
tagmanager.ClientWithRequestQuota(15),
tagmanager.ClientWithClientOptions(clientCredentialsOption),
)
if err != nil {
return err
}
logger.Info("- Folder:", logger.Args("name", c.FolderName()))
if _, err := c.UpsertFolder(ctx, c.FolderName()); err != nil {
if _, err := c.UpsertFolder(c.FolderName()); err != nil {
return err
}
logger.Info("- Variable:", logger.Args("name", "ga4-measurement-id"))
measurementID, err := c.UpsertConstantVariable(ctx, "ga4-measurement-id", c.MeasurementID())
measurementID, err := c.UpsertConstantVariable("ga4-measurement-id", c.MeasurementID())
if err != nil {
return err
}
logger.Info("- GTM client:", logger.Args("name", "Google Tag Manager Web Container"))
if _, err := c.UpsertGTMClient(ctx, "Google Tag Manager Web Container", cfg.Google.GTM.Web.MeasurementID); err != nil {
if _, err := c.UpsertGTMClient("Google Tag Manager Web Container", cfg.Google.GTM.Web.MeasurementID); err != nil {
return err
}
logger.Info("- GA4 client:", logger.Args("name", "Google Analytics GA4"))
ga4Client, err := c.UpsertGA4Client(ctx, "Google Analytics GA4")
ga4Client, err := c.UpsertGA4Client("Google Analytics GA4")
if err != nil {
return err
}
logger.Info("- GA4 trigger:", logger.Args("name", "Google Analytics GA4"))
ga4ClientTrigger, err := c.UpsertClientTrigger(ctx, "ga4", ga4Client.Name)
ga4ClientTrigger, err := c.UpsertClientTrigger("ga4", ga4Client)
if err != nil {
return err
}
logger.Info("- GA4 tag:", logger.Args("name", "Google Analytics GA4"))
if _, err := c.UpsertGA4ServerTag(ctx, "Google Analytics GA4", measurementID, ga4ClientTrigger); err != nil {
if _, err := c.UpsertGA4ServerTag("Google Analytics GA4", measurementID, ga4ClientTrigger); err != nil {
return err
}

View File

@ -5,6 +5,7 @@ import (
"github.com/foomo/sesamy-cli/pkg/tagmanager"
"github.com/spf13/cobra"
"google.golang.org/api/option"
tagmanager2 "google.golang.org/api/tagmanager/v2"
)
// tagmanagerWebCmd represents the web command
@ -13,13 +14,11 @@ var tagmanagerWebCmd = &cobra.Command{
Short: "Provision Google Tag Manager Web Container",
PersistentPreRunE: preRunReadConfig,
RunE: func(cmd *cobra.Command, args []string) error {
ctx := cmd.Context()
var opt option.ClientOption
var clientCredentialsOption option.ClientOption
if cfg.Google.CredentialsFile != "" {
opt = option.WithCredentialsFile(cfg.Google.CredentialsFile)
clientCredentialsOption = option.WithCredentialsFile(cfg.Google.CredentialsFile)
} else {
opt = option.WithCredentialsFile(cfg.Google.CredentialsJSON)
clientCredentialsOption = option.WithCredentialsJSON([]byte(cfg.Google.CredentialsJSON))
}
eventParameters, err := internal.GetEventParameters(cfg)
@ -28,35 +27,53 @@ var tagmanagerWebCmd = &cobra.Command{
}
c, err := tagmanager.NewClient(
cmd.Context(),
cfg.Google.GTM.AccountID,
cfg.Google.GTM.Web.ContainerID,
cfg.Google.GTM.Web.WorkspaceID,
cfg.Google.GA4.MeasurementID,
tagmanager.ClientWithClientOptions(opt),
tagmanager.ClientWithRequestQuota(15),
tagmanager.ClientWithClientOptions(clientCredentialsOption),
)
if err != nil {
return err
}
logger.Info("- Folder:", logger.Args("name", c.FolderName()))
if _, err := c.UpsertFolder(ctx, c.FolderName()); err != nil {
if _, err := c.UpsertFolder(c.FolderName()); err != nil {
return err
}
logger.Info("- Variable:", logger.Args("name", "ga4-measurement-id"))
measurementID, err := c.UpsertConstantVariable(ctx, "ga4-measurement-id", c.MeasurementID())
measurementID, err := c.UpsertConstantVariable("ga4-measurement-id", c.MeasurementID())
if err != nil {
return err
}
for key, value := range eventParameters {
logger.Info("- GA4 Trigger:", logger.Args("name", key, "parameters", value))
trigger, err := c.UpsertCustomEventTrigger(ctx, key)
for event, parameters := range eventParameters {
logger.Info("- GA4 Event Trigger:", logger.Args("name", event))
trigger, err := c.UpsertCustomEventTrigger(event)
if err != nil {
return err
}
logger.Info("- GA4 Tag:", logger.Args("name", key, "parameters", value))
if _, err := c.UpsertGA4WebTag(ctx, key, value, measurementID, trigger); err != nil {
eventSettingsVariables := make(map[string]*tagmanager2.Variable, len(parameters))
for _, parameter := range parameters {
logger.Info("- Event Model Variable:", logger.Args("name", parameter))
eventSettingsVariables[parameter], err = c.UpsertEventModelVariable(parameter)
if err != nil {
return err
}
}
logger.Info("- GT Event Settings Variable:", logger.Args("name", event))
eventSettings, err := c.UpsertGTEventSettingsVariable(event, eventSettingsVariables)
if err != nil {
return err
}
logger.Info("- GA4 Tag:", logger.Args("name", event, "parameters", parameters))
if _, err := c.UpsertGA4WebTag(event, eventSettings, measurementID, trigger); err != nil {
return err
}
}

3
go.mod
View File

@ -4,6 +4,7 @@ go 1.22.0
require (
github.com/fatih/structtag v1.2.0
github.com/graze/go-throttled v0.3.1
github.com/gzuidhof/tygo v0.2.14
github.com/mitchellh/mapstructure v1.5.0
github.com/pterm/pterm v0.12.79
@ -11,6 +12,8 @@ require (
github.com/spf13/viper v1.18.2
github.com/stoewer/go-strcase v1.3.0
github.com/stretchr/testify v1.9.0
github.com/yudppp/throttle v1.0.4
golang.org/x/time v0.5.0
golang.org/x/tools v0.19.0
google.golang.org/api v0.168.0
)

7
go.sum
View File

@ -89,6 +89,8 @@ github.com/gookit/color v1.4.2/go.mod h1:fqRyamkC1W8uxl+lxCQxOT09l/vYfZ+QeiX3rKQ
github.com/gookit/color v1.5.0/go.mod h1:43aQb+Zerm/BWh2GnrgOQm7ffz7tvQXEKV6BFMl7wAo=
github.com/gookit/color v1.5.4 h1:FZmqs7XOyGgCAxmWyPslpiok1k05wmY3SJTytgvYFs0=
github.com/gookit/color v1.5.4/go.mod h1:pZJOeOS8DM43rXbp4AZo1n9zCU2qjpcRko0b6/QJi9w=
github.com/graze/go-throttled v0.3.1 h1:Mr9hMy0GXnbFlOWQl6pjNyn8T+9/LWIv1hJndNhs9mo=
github.com/graze/go-throttled v0.3.1/go.mod h1:OYBew5YhHxQqZGjoa7M8NQLIj+ztV+Iv5xCvzK1sQLg=
github.com/gzuidhof/tygo v0.2.14 h1:QRBD6eby2SMyYzv8KzXA+yopPbEO6w2Qzuuqqp9z+vU=
github.com/gzuidhof/tygo v0.2.14/go.mod h1:s3lpnppkDixQQhMWD78yPtAmugMHENsPWpQYziUIpw0=
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
@ -175,6 +177,8 @@ github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSW
github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778/go.mod h1:2MuV+tbUrU1zIOPMxZ5EncGwgmMJsa+9ucAQZXxsObs=
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no=
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM=
github.com/yudppp/throttle v1.0.4 h1:n3dG5m/3PEZ03znkgMS3LaoLjJV6Oy+uPMqj+HwHesw=
github.com/yudppp/throttle v1.0.4/go.mod h1:pDK8agvkakfVmc0TWTupeQSY1a4VEpM1TNoDwky7Jlo=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
@ -257,6 +261,9 @@ golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=

View File

@ -3,6 +3,8 @@ package tagmanager
import (
"context"
"errors"
"sort"
"time"
"google.golang.org/api/option"
"google.golang.org/api/tagmanager/v2"
@ -14,13 +16,14 @@ var (
type (
Client struct {
notes string
accountID string
containerID string
workspaceID string
measurementID string
folderName string
clientOptions []option.ClientOption
notes string
accountID string
containerID string
workspaceID string
measurementID string
folderName string
clientOptions []option.ClientOption
requestThrottler *time.Ticker
// cache
service *tagmanager.Service
clients map[string]*tagmanager.Client
@ -48,6 +51,12 @@ func ClientWithFolderName(v string) ClientOption {
}
}
func ClientWithRequestQuota(v int) ClientOption {
return func(o *Client) {
o.requestThrottler = time.NewTicker((100 * time.Second) / time.Duration(v))
}
}
func ClientWithClientOptions(v ...option.ClientOption) ClientOption {
return func(o *Client) {
o.clientOptions = append(o.clientOptions, v...)
@ -58,7 +67,7 @@ func ClientWithClientOptions(v ...option.ClientOption) ClientOption {
// ~ Constructor
// ------------------------------------------------------------------------------------------------
func NewClient(accountID, containerID, workspaceID, measurementID string, opts ...ClientOption) (*Client, error) {
func NewClient(ctx context.Context, accountID, containerID, workspaceID, measurementID string, opts ...ClientOption) (*Client, error) {
inst := &Client{
accountID: accountID,
containerID: containerID,
@ -72,16 +81,7 @@ func NewClient(accountID, containerID, workspaceID, measurementID string, opts .
notes: "Managed by Sesamy. DO NOT EDIT.",
folderName: "Sesamy",
clientOptions: []option.ClientOption{
//// https://developers.google.com/tag-platform/tag-manager/api/v2/authorization#AboutAuthorization
//option.WithScopes(
// "https://www.googleapis.com/auth/tagmanager.readonly",
// "https://www.googleapis.com/auth/tagmanager.edit.containers",
// // https://www.googleapis.com/auth/tagmanager.delete.containers
// //"https://www.googleapis.com/auth/tagmanager.edit.containerversions",
// //"https://www.googleapis.com/auth/tagmanager.publish",
// // https://www.googleapis.com/auth/tagmanager.manage.users
// // https://www.googleapis.com/auth/tagmanager.manage.accounts
//),
option.WithRequestReason("Sesamy container provisioning"),
},
}
@ -89,6 +89,12 @@ func NewClient(accountID, containerID, workspaceID, measurementID string, opts .
opt(inst)
}
if value, err := tagmanager.NewService(ctx, inst.clientOptions...); err != nil {
return nil, err
} else {
inst.service = value
}
return inst, nil
}
@ -120,15 +126,11 @@ func (c *Client) FolderName() string {
return c.folderName
}
func (c *Client) Service(ctx context.Context) (*tagmanager.Service, error) {
if c.service == nil {
v, err := tagmanager.NewService(ctx, c.clientOptions...)
if err != nil {
return nil, err
}
c.service = v
func (c *Client) Service() *tagmanager.Service {
if c.requestThrottler != nil {
<-c.requestThrottler.C
}
return c.service, nil
return c.service
}
func (c *Client) AccountPath() string {
@ -143,14 +145,9 @@ func (c *Client) WorkspacePath() string {
return c.ContainerPath() + "/workspaces/" + c.workspaceID
}
func (c *Client) Client(ctx context.Context, name string) (*tagmanager.Client, error) {
func (c *Client) Client(name string) (*tagmanager.Client, error) {
if _, ok := c.clients[name]; !ok {
client, err := c.Service(ctx)
if err != nil {
return nil, err
}
r, err := client.Accounts.Containers.Workspaces.Clients.List(c.WorkspacePath()).Do()
r, err := c.Service().Accounts.Containers.Workspaces.Clients.List(c.WorkspacePath()).Do()
if err != nil {
return nil, err
}
@ -171,14 +168,9 @@ func (c *Client) Client(ctx context.Context, name string) (*tagmanager.Client, e
return c.clients[name], nil
}
func (c *Client) Folder(ctx context.Context, name string) (*tagmanager.Folder, error) {
func (c *Client) Folder(name string) (*tagmanager.Folder, error) {
if _, ok := c.folders[name]; !ok {
client, err := c.Service(ctx)
if err != nil {
return nil, err
}
r, err := client.Accounts.Containers.Workspaces.Folders.List(c.WorkspacePath()).Do()
r, err := c.Service().Accounts.Containers.Workspaces.Folders.List(c.WorkspacePath()).Do()
if err != nil {
return nil, err
}
@ -199,14 +191,9 @@ func (c *Client) Folder(ctx context.Context, name string) (*tagmanager.Folder, e
return c.folders[name], nil
}
func (c *Client) Variable(ctx context.Context, name string) (*tagmanager.Variable, error) {
func (c *Client) Variable(name string) (*tagmanager.Variable, error) {
if _, ok := c.variables[name]; !ok {
client, err := c.Service(ctx)
if err != nil {
return nil, err
}
r, err := client.Accounts.Containers.Workspaces.Variables.List(c.WorkspacePath()).Do()
r, err := c.Service().Accounts.Containers.Workspaces.Variables.List(c.WorkspacePath()).Do()
if err != nil {
return nil, err
}
@ -227,14 +214,9 @@ func (c *Client) Variable(ctx context.Context, name string) (*tagmanager.Variabl
return c.variables[name], nil
}
func (c *Client) Trigger(ctx context.Context, name string) (*tagmanager.Trigger, error) {
func (c *Client) Trigger(name string) (*tagmanager.Trigger, error) {
if _, ok := c.triggers[name]; !ok {
client, err := c.Service(ctx)
if err != nil {
return nil, err
}
r, err := client.Accounts.Containers.Workspaces.Triggers.List(c.WorkspacePath()).Do()
r, err := c.Service().Accounts.Containers.Workspaces.Triggers.List(c.WorkspacePath()).Do()
if err != nil {
return nil, err
}
@ -255,14 +237,9 @@ func (c *Client) Trigger(ctx context.Context, name string) (*tagmanager.Trigger,
return c.triggers[name], nil
}
func (c *Client) Tag(ctx context.Context, name string) (*tagmanager.Tag, error) {
func (c *Client) Tag(name string) (*tagmanager.Tag, error) {
if _, ok := c.tags[name]; !ok {
client, err := c.Service(ctx)
if err != nil {
return nil, err
}
r, err := client.Accounts.Containers.Workspaces.Tags.List(c.WorkspacePath()).Do()
r, err := c.Service().Accounts.Containers.Workspaces.Tags.List(c.WorkspacePath()).Do()
if err != nil {
return nil, err
}
@ -287,18 +264,13 @@ func (c *Client) Tag(ctx context.Context, name string) (*tagmanager.Tag, error)
// ~ Public methods
// ------------------------------------------------------------------------------------------------
func (c *Client) UpsertGA4Client(ctx context.Context, name string) (*tagmanager.Client, error) {
cache, err := c.Client(ctx, name)
func (c *Client) UpsertGA4Client(name string) (*tagmanager.Client, error) {
cache, err := c.Client(name)
if err != nil && !errors.Is(err, ErrNotFound) {
return nil, err
}
s, err := c.Service(ctx)
if err != nil {
return nil, err
}
folder, err := c.Folder(ctx, c.folderName)
folder, err := c.Folder(c.folderName)
if err != nil {
return nil, err
}
@ -331,29 +303,24 @@ func (c *Client) UpsertGA4Client(ctx context.Context, name string) (*tagmanager.
}
if cache == nil {
c.clients[name], err = s.Accounts.Containers.Workspaces.Clients.Create(c.WorkspacePath(), obj).Do()
c.clients[name], err = c.Service().Accounts.Containers.Workspaces.Clients.Create(c.WorkspacePath(), obj).Do()
} else {
c.clients[name], err = s.Accounts.Containers.Workspaces.Clients.Update(c.WorkspacePath()+"/clients/"+cache.ClientId, obj).Do()
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(ctx, name)
return c.Client(name)
}
func (c *Client) UpsertGTMClient(ctx context.Context, name, webContainerMeasurementID string) (*tagmanager.Client, error) {
cache, err := c.Client(ctx, 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
}
s, err := c.Service(ctx)
if err != nil {
return nil, err
}
folder, err := c.Folder(ctx, c.folderName)
folder, err := c.Folder(c.folderName)
if err != nil {
return nil, err
}
@ -402,28 +369,23 @@ func (c *Client) UpsertGTMClient(ctx context.Context, name, webContainerMeasurem
}
if cache == nil {
c.clients[name], err = s.Accounts.Containers.Workspaces.Clients.Create(c.WorkspacePath(), obj).Do()
c.clients[name], err = c.Service().Accounts.Containers.Workspaces.Clients.Create(c.WorkspacePath(), obj).Do()
} else {
c.clients[name], err = s.Accounts.Containers.Workspaces.Clients.Update(c.WorkspacePath()+"/clients/"+cache.ClientId, obj).Do()
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(ctx, name)
return c.Client(name)
}
func (c *Client) UpsertFolder(ctx context.Context, name string) (*tagmanager.Folder, error) {
cache, err := c.Folder(ctx, name)
func (c *Client) UpsertFolder(name string) (*tagmanager.Folder, error) {
cache, err := c.Folder(name)
if err != nil && !errors.Is(err, ErrNotFound) && !errors.Is(err, ErrNotFound) {
return nil, err
}
client, err := c.Service(ctx)
if err != nil {
return nil, err
}
obj := &tagmanager.Folder{
AccountId: c.accountID,
ContainerId: c.containerID,
@ -433,47 +395,42 @@ func (c *Client) UpsertFolder(ctx context.Context, name string) (*tagmanager.Fol
}
if cache == nil {
c.folders[name], err = client.Accounts.Containers.Workspaces.Folders.Create(c.WorkspacePath(), obj).Do()
c.folders[name], err = c.Service().Accounts.Containers.Workspaces.Folders.Create(c.WorkspacePath(), obj).Do()
} else {
c.folders[name], err = client.Accounts.Containers.Workspaces.Folders.Update(c.WorkspacePath()+"/folders/"+cache.FolderId, obj).Do()
c.folders[name], err = c.Service().Accounts.Containers.Workspaces.Folders.Update(c.WorkspacePath()+"/folders/"+cache.FolderId, obj).Do()
}
if err != nil {
return nil, err
}
return c.Folder(ctx, name)
return c.Folder(name)
}
func (c *Client) UpsertVariable(ctx context.Context, obj *tagmanager.Variable) (*tagmanager.Variable, error) {
cache, err := c.Variable(ctx, obj.Name)
func (c *Client) UpsertVariable(variable *tagmanager.Variable) (*tagmanager.Variable, error) {
cache, err := c.Variable(variable.Name)
if err != nil && !errors.Is(err, ErrNotFound) {
return nil, err
}
client, err := c.Service(ctx)
folder, err := c.Folder(c.folderName)
if err != nil {
return nil, err
}
folder, err := c.Folder(ctx, c.folderName)
if err != nil {
return nil, err
}
obj.ParentFolderId = folder.FolderId
variable.ParentFolderId = folder.FolderId
if cache == nil {
c.variables[obj.Name], err = client.Accounts.Containers.Workspaces.Variables.Create(c.WorkspacePath(), obj).Do()
c.variables[variable.Name], err = c.Service().Accounts.Containers.Workspaces.Variables.Create(c.WorkspacePath(), variable).Do()
} else {
c.variables[obj.Name], err = client.Accounts.Containers.Workspaces.Variables.Update(c.WorkspacePath()+"/variables/"+cache.VariableId, obj).Do()
c.variables[variable.Name], err = c.Service().Accounts.Containers.Workspaces.Variables.Update(c.WorkspacePath()+"/variables/"+cache.VariableId, variable).Do()
}
if err != nil {
return nil, err
}
return c.Variable(ctx, obj.Name)
return c.Variable(variable.Name)
}
func (c *Client) UpsertConstantVariable(ctx context.Context, name, value string) (*tagmanager.Variable, error) {
func (c *Client) UpsertConstantVariable(name, value string) (*tagmanager.Variable, error) {
obj := &tagmanager.Variable{
AccountId: c.accountID,
ContainerId: c.containerID,
@ -489,10 +446,10 @@ func (c *Client) UpsertConstantVariable(ctx context.Context, name, value string)
},
Type: "c",
}
return c.UpsertVariable(ctx, obj)
return c.UpsertVariable(obj)
}
func (c *Client) UpsertEventModelVariable(ctx context.Context, name string) (*tagmanager.Variable, error) {
func (c *Client) UpsertEventModelVariable(name string) (*tagmanager.Variable, error) {
obj := &tagmanager.Variable{
AccountId: c.accountID,
ContainerId: c.containerID,
@ -518,22 +475,64 @@ func (c *Client) UpsertEventModelVariable(ctx context.Context, name string) (*ta
},
Type: "v",
}
return c.UpsertVariable(ctx, obj)
return c.UpsertVariable(obj)
}
func (c *Client) UpsertCustomEventTrigger(ctx context.Context, name string) (*tagmanager.Trigger, error) {
name = "Event." + name
cache, err := c.Trigger(ctx, name)
func (c *Client) UpsertGTEventSettingsVariable(name string, variables map[string]*tagmanager.Variable) (*tagmanager.Variable, error) {
fullname := "GTEventSettings." + name
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: fullname,
Notes: c.notes,
Parameter: []*tagmanager.Parameter{
{
Key: "eventSettingsTable",
Type: "list",
List: list,
},
},
Type: "gtes",
}
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) {
return nil, err
}
client, err := c.Service(ctx)
if err != nil {
return nil, err
}
folder, err := c.Folder(ctx, c.folderName)
folder, err := c.Folder(c.folderName)
if err != nil {
return nil, err
}
@ -544,7 +543,7 @@ func (c *Client) UpsertCustomEventTrigger(ctx context.Context, name string) (*ta
WorkspaceId: c.workspaceID,
ParentFolderId: folder.FolderId,
Type: "customEvent",
Name: name,
Name: fullname,
Notes: c.notes,
CustomEventFilter: []*tagmanager.Condition{
{
@ -566,30 +565,25 @@ func (c *Client) UpsertCustomEventTrigger(ctx context.Context, name string) (*ta
}
if cache == nil {
c.triggers[name], err = client.Accounts.Containers.Workspaces.Triggers.Create(c.WorkspacePath(), obj).Do()
c.triggers[fullname], err = c.Service().Accounts.Containers.Workspaces.Triggers.Create(c.WorkspacePath(), obj).Do()
} else {
c.triggers[name], err = client.Accounts.Containers.Workspaces.Triggers.Update(c.WorkspacePath()+"/triggers/"+cache.TriggerId, obj).Do()
c.triggers[fullname], err = c.Service().Accounts.Containers.Workspaces.Triggers.Update(c.WorkspacePath()+"/triggers/"+cache.TriggerId, obj).Do()
}
if err != nil {
return nil, err
}
return c.Trigger(ctx, name)
return c.Trigger(fullname)
}
func (c *Client) UpsertClientTrigger(ctx context.Context, name, clientName string) (*tagmanager.Trigger, error) {
name = "Client." + name
cache, err := c.Trigger(ctx, name)
func (c *Client) UpsertClientTrigger(name string, client *tagmanager.Client) (*tagmanager.Trigger, error) {
fullname := "Client." + name
cache, err := c.Trigger(fullname)
if err != nil && !errors.Is(err, ErrNotFound) {
return nil, err
}
client, err := c.Service(ctx)
if err != nil {
return nil, err
}
folder, err := c.Folder(ctx, c.folderName)
folder, err := c.Folder(c.folderName)
if err != nil {
return nil, err
}
@ -600,7 +594,7 @@ func (c *Client) UpsertClientTrigger(ctx context.Context, name, clientName strin
WorkspaceId: c.workspaceID,
ParentFolderId: folder.FolderId,
Type: "always",
Name: name,
Name: fullname,
Notes: c.notes,
Filter: []*tagmanager.Condition{
{
@ -613,7 +607,7 @@ func (c *Client) UpsertClientTrigger(ctx context.Context, name, clientName strin
{
Key: "arg1",
Type: "template",
Value: clientName,
Value: client.Name,
},
},
Type: "equals",
@ -622,31 +616,26 @@ func (c *Client) UpsertClientTrigger(ctx context.Context, name, clientName strin
}
if cache == nil {
c.triggers[name], err = client.Accounts.Containers.Workspaces.Triggers.Create(c.WorkspacePath(), obj).Do()
c.triggers[fullname], err = c.Service().Accounts.Containers.Workspaces.Triggers.Create(c.WorkspacePath(), obj).Do()
} else {
c.triggers[name], err = client.Accounts.Containers.Workspaces.Triggers.Update(c.WorkspacePath()+"/triggers/"+cache.TriggerId, obj).Do()
c.triggers[fullname], err = c.Service().Accounts.Containers.Workspaces.Triggers.Update(c.WorkspacePath()+"/triggers/"+cache.TriggerId, obj).Do()
}
if err != nil {
return nil, err
}
return c.Trigger(ctx, name)
return c.Trigger(fullname)
}
func (c *Client) UpsertGA4WebTag(ctx context.Context, name string, parameters []string, measurementID *tagmanager.Variable, trigger *tagmanager.Trigger) (*tagmanager.Tag, error) {
name = "GA4." + 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(ctx, name)
cache, err := c.Tag(fullname)
if err != nil && !errors.Is(err, ErrNotFound) {
return nil, err
}
client, err := c.Service(ctx)
if err != nil {
return nil, err
}
folder, err := c.Folder(ctx, c.folderName)
folder, err := c.Folder(c.folderName)
if err != nil {
return nil, err
}
@ -657,7 +646,7 @@ func (c *Client) UpsertGA4WebTag(ctx context.Context, name string, parameters []
WorkspaceId: c.workspaceID,
FiringTriggerId: []string{trigger.TriggerId},
ParentFolderId: folder.FolderId,
Name: name,
Name: fullname,
Notes: c.notes,
Parameter: []*tagmanager.Parameter{
{
@ -665,11 +654,6 @@ func (c *Client) UpsertGA4WebTag(ctx context.Context, name string, parameters []
Key: "sendEcommerceData",
Value: "false",
},
{
Type: "template",
Key: "getEcommerceDataFrom",
Value: "dataLayer",
},
{
Type: "boolean",
Key: "enhancedUserId",
@ -678,68 +662,72 @@ func (c *Client) UpsertGA4WebTag(ctx context.Context, name string, parameters []
{
Type: "template",
Key: "eventName",
Value: trigger.Name,
Value: name,
},
{
Type: "template",
Key: "measurementIdOverride",
Value: "{{" + measurementID.Name + "}}",
},
{
Type: "template",
Key: "eventSettingsVariable",
Value: "{{" + eventSettings.Name + "}}",
},
},
Type: "gaawe",
}
for _, parameterName := range parameters {
if _, err := c.UpsertEventModelVariable(ctx, parameterName); err != nil {
return nil, err
}
obj.Parameter = append(obj.Parameter, &tagmanager.Parameter{
Type: "list",
Key: "eventSettingsTable",
List: []*tagmanager.Parameter{
{
Type: "map",
Map: []*tagmanager.Parameter{
{
Type: "template",
Key: "parameter",
Value: parameterName,
},
{
Type: "template",
Key: "parameterValue",
Value: "{{EventModel." + parameterName + "}}",
},
},
},
},
})
}
// 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[name], err = client.Accounts.Containers.Workspaces.Tags.Create(c.WorkspacePath(), obj).Do()
c.tags[fullname], err = c.Service().Accounts.Containers.Workspaces.Tags.Create(c.WorkspacePath(), obj).Do()
} else {
c.tags[name], err = client.Accounts.Containers.Workspaces.Tags.Update(c.WorkspacePath()+"/tags/"+cache.TagId, obj).Do()
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(ctx, name)
return c.Tag(fullname)
}
func (c *Client) UpsertGA4ServerTag(ctx context.Context, name string, measurementID *tagmanager.Variable, trigger *tagmanager.Trigger) (*tagmanager.Tag, error) {
cache, err := c.Tag(ctx, 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
}
client, err := c.Service(ctx)
if err != nil {
return nil, err
}
folder, err := c.Folder(ctx, c.folderName)
folder, err := c.Folder(c.folderName)
if err != nil {
return nil, err
}
@ -788,13 +776,13 @@ func (c *Client) UpsertGA4ServerTag(ctx context.Context, name string, measuremen
}
if cache == nil {
c.tags[name], err = client.Accounts.Containers.Workspaces.Tags.Create(c.WorkspacePath(), obj).Do()
c.tags[name], err = c.Service().Accounts.Containers.Workspaces.Tags.Create(c.WorkspacePath(), obj).Do()
} else {
c.tags[name], err = client.Accounts.Containers.Workspaces.Tags.Update(c.WorkspacePath()+"/tags/"+cache.TagId, obj).Do()
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(ctx, name)
return c.Tag(name)
}

View File

@ -18,9 +18,9 @@ import (
func TestNewClient_Server(t *testing.T) {
t.Skip()
ctx := context.TODO()
c, err := tagmanager.NewClient(
context.TODO(),
os.Getenv("TEST_ACCOUNT_ID"),
os.Getenv("TEST_SERVER_CONTAINER_ID"),
os.Getenv("TEST_SERVER_WORKSPACE_ID"),
@ -33,7 +33,7 @@ func TestNewClient_Server(t *testing.T) {
{ // --- Folders ---
t.Run("upsert folder", func(t *testing.T) {
obj, err := c.UpsertFolder(ctx, "Sesamy")
obj, err := c.UpsertFolder("Sesamy")
require.NoError(t, err)
dump(t, obj)
})
@ -41,7 +41,7 @@ func TestNewClient_Server(t *testing.T) {
{ // --- Variables ---
t.Run("upsert GTM client", func(t *testing.T) {
client, err := c.UpsertConstantVariable(ctx, "web-container-id", os.Getenv("TEST_WEB_CONTAINER_GID"))
client, err := c.UpsertConstantVariable("web-container-id", os.Getenv("TEST_WEB_CONTAINER_GID"))
if assert.NoError(t, err) {
dump(t, client)
}
@ -50,16 +50,14 @@ func TestNewClient_Server(t *testing.T) {
{ // --- Clients ---
t.Run("list clients", func(t *testing.T) {
client, err := c.Service(ctx)
require.NoError(t, err)
cmd := client.Accounts.Containers.Workspaces.Clients.List(c.WorkspacePath())
cmd := c.Service().Accounts.Containers.Workspaces.Clients.List(c.WorkspacePath())
if r, err := cmd.Do(); assert.NoError(t, err) {
dump(t, r)
}
})
t.Run("upsert GTM client", func(t *testing.T) {
client, err := c.UpsertGTMClient(ctx, "Google Tag Manager Web Container", "Constant.web-container-id")
client, err := c.UpsertGTMClient("Google Tag Manager Web Container", "Constant.web-container-id")
if assert.NoError(t, err) {
dump(t, client)
}
@ -68,9 +66,7 @@ func TestNewClient_Server(t *testing.T) {
{ // --- Triggers ---
t.Run("list triggers", func(t *testing.T) {
client, err := c.Service(ctx)
require.NoError(t, err)
cmd := client.Accounts.Containers.Workspaces.Triggers.List(c.WorkspacePath())
cmd := c.Service().Accounts.Containers.Workspaces.Triggers.List(c.WorkspacePath())
if r, err := cmd.Do(); assert.NoError(t, err) {
dump(t, r)
}
@ -79,9 +75,7 @@ func TestNewClient_Server(t *testing.T) {
{ // --- Tags ---
t.Run("list tags", func(t *testing.T) {
client, err := c.Service(ctx)
require.NoError(t, err)
cmd := client.Accounts.Containers.Workspaces.Tags.List(c.WorkspacePath())
cmd := c.Service().Accounts.Containers.Workspaces.Tags.List(c.WorkspacePath())
if r, err := cmd.Do(); assert.NoError(t, err) {
dump(t, r)
}
@ -91,9 +85,8 @@ func TestNewClient_Server(t *testing.T) {
func TestNewClient_Web(t *testing.T) {
t.Skip()
ctx := context.TODO()
c, err := tagmanager.NewClient(
context.TODO(),
os.Getenv("TEST_ACCOUNT_ID"),
os.Getenv("TEST_WEB_CONTAINER_ID"),
os.Getenv("TEST_WEB_WORKSPACE_ID"),
@ -106,9 +99,7 @@ func TestNewClient_Web(t *testing.T) {
{ // --- Containers ---
t.Run("list containers", func(t *testing.T) {
client, err := c.Service(ctx)
require.NoError(t, err)
cmd := client.Accounts.Containers.List(c.AccountPath())
cmd := c.Service().Accounts.Containers.List(c.AccountPath())
if r, err := cmd.Do(); assert.NoError(t, err) {
dump(t, r)
}
@ -117,9 +108,7 @@ func TestNewClient_Web(t *testing.T) {
{ // --- Workspaces ---
t.Run("list workspaces", func(t *testing.T) {
client, err := c.Service(ctx)
require.NoError(t, err)
cmd := client.Accounts.Containers.Workspaces.List(c.ContainerPath())
cmd := c.Service().Accounts.Containers.Workspaces.List(c.ContainerPath())
if r, err := cmd.Do(); assert.NoError(t, err) {
dump(t, r)
}
@ -130,18 +119,14 @@ func TestNewClient_Web(t *testing.T) {
{ // --- Folders ---
name := "Sesamy"
t.Run("list folders", func(t *testing.T) {
client, err := c.Service(ctx)
require.NoError(t, err)
cmd := client.Accounts.Containers.Workspaces.Folders.List(c.WorkspacePath())
cmd := c.Service().Accounts.Containers.Workspaces.Folders.List(c.WorkspacePath())
if r, err := cmd.Do(); assert.NoError(t, err) {
dump(t, r)
}
})
t.Run("create folder", func(t *testing.T) {
client, err := c.Service(ctx)
require.NoError(t, err)
cmd := client.Accounts.Containers.Workspaces.Folders.Create(c.WorkspacePath(), &gtagmanager.Folder{
cmd := c.Service().Accounts.Containers.Workspaces.Folders.Create(c.WorkspacePath(), &gtagmanager.Folder{
AccountId: c.AccountID(),
ContainerId: c.ContainerID(),
WorkspaceId: c.WorkspaceID(),
@ -154,9 +139,7 @@ func TestNewClient_Web(t *testing.T) {
})
t.Run("get folder", func(t *testing.T) {
client, err := c.Service(ctx)
require.NoError(t, err)
cmd := client.Accounts.Containers.Workspaces.Folders.List(c.WorkspacePath())
cmd := c.Service().Accounts.Containers.Workspaces.Folders.List(c.WorkspacePath())
if r, err := cmd.Do(); assert.NoError(t, err) {
for _, folder := range r.Folder {
if folder.Name == name {
@ -169,7 +152,7 @@ func TestNewClient_Web(t *testing.T) {
})
t.Run("upsert folder", func(t *testing.T) {
obj, err := c.UpsertFolder(ctx, name)
obj, err := c.UpsertFolder(name)
require.NoError(t, err)
t.Log("ID: " + obj.FolderId)
})
@ -178,18 +161,14 @@ func TestNewClient_Web(t *testing.T) {
{ // --- Variables ---
name := "ga4-measurement-id"
t.Run("list variables", func(t *testing.T) {
client, err := c.Service(ctx)
require.NoError(t, err)
cmd := client.Accounts.Containers.Workspaces.Variables.List(c.WorkspacePath())
cmd := c.Service().Accounts.Containers.Workspaces.Variables.List(c.WorkspacePath())
if r, err := cmd.Do(); assert.NoError(t, err) {
dump(t, r)
}
})
t.Run("create variable", func(t *testing.T) {
client, err := c.Service(ctx)
require.NoError(t, err)
cmd := client.Accounts.Containers.Workspaces.Variables.Create(c.WorkspacePath(), &gtagmanager.Variable{
cmd := c.Service().Accounts.Containers.Workspaces.Variables.Create(c.WorkspacePath(), &gtagmanager.Variable{
AccountId: c.AccountID(),
ContainerId: c.ContainerID(),
WorkspaceId: c.WorkspaceID(),
@ -211,9 +190,7 @@ func TestNewClient_Web(t *testing.T) {
})
t.Run("get variable", func(t *testing.T) {
client, err := c.Service(ctx)
require.NoError(t, err)
cmd := client.Accounts.Containers.Workspaces.Variables.List(c.WorkspacePath())
cmd := c.Service().Accounts.Containers.Workspaces.Variables.List(c.WorkspacePath())
if r, err := cmd.Do(); assert.NoError(t, err) {
for _, variable := range r.Variable {
if variable.Name == "Constant."+name {
@ -226,7 +203,7 @@ func TestNewClient_Web(t *testing.T) {
})
t.Run("upsert variable", func(t *testing.T) {
obj, err := c.UpsertConstantVariable(ctx, name, c.MeasurementID())
obj, err := c.UpsertConstantVariable(name, c.MeasurementID())
require.NoError(t, err)
t.Log("ID: " + obj.VariableId)
})
@ -235,18 +212,14 @@ func TestNewClient_Web(t *testing.T) {
{ // --- Triggers ---
name := "login"
t.Run("list triggers", func(t *testing.T) {
client, err := c.Service(ctx)
require.NoError(t, err)
cmd := client.Accounts.Containers.Workspaces.Triggers.List(c.WorkspacePath())
cmd := c.Service().Accounts.Containers.Workspaces.Triggers.List(c.WorkspacePath())
if r, err := cmd.Do(); assert.NoError(t, err) {
dump(t, r)
}
})
t.Run("create trigger", func(t *testing.T) {
client, err := c.Service(ctx)
require.NoError(t, err)
cmd := client.Accounts.Containers.Workspaces.Triggers.Create(c.WorkspacePath(), &gtagmanager.Trigger{
cmd := c.Service().Accounts.Containers.Workspaces.Triggers.Create(c.WorkspacePath(), &gtagmanager.Trigger{
AccountId: c.AccountID(),
ContainerId: c.ContainerID(),
WorkspaceId: c.WorkspaceID(),
@ -278,9 +251,7 @@ func TestNewClient_Web(t *testing.T) {
})
t.Run("get trigger", func(t *testing.T) {
client, err := c.Service(ctx)
require.NoError(t, err)
cmd := client.Accounts.Containers.Workspaces.Triggers.List(c.WorkspacePath())
cmd := c.Service().Accounts.Containers.Workspaces.Triggers.List(c.WorkspacePath())
if r, err := cmd.Do(); assert.NoError(t, err) {
for _, trigger := range r.Trigger {
if trigger.Name == "Event."+name {
@ -293,7 +264,7 @@ func TestNewClient_Web(t *testing.T) {
})
t.Run("upsert trigger", func(t *testing.T) {
obj, err := c.UpsertCustomEventTrigger(ctx, name)
obj, err := c.UpsertCustomEventTrigger(name)
require.NoError(t, err)
t.Log("ID: " + obj.TriggerId)
})
@ -302,18 +273,14 @@ func TestNewClient_Web(t *testing.T) {
{ // --- Tags ---
name := "login"
t.Run("list tags", func(t *testing.T) {
client, err := c.Service(ctx)
require.NoError(t, err)
cmd := client.Accounts.Containers.Workspaces.Tags.List(c.WorkspacePath())
cmd := c.Service().Accounts.Containers.Workspaces.Tags.List(c.WorkspacePath())
if r, err := cmd.Do(); assert.NoError(t, err) {
dump(t, r)
}
})
t.Run("create tag", func(t *testing.T) {
client, err := c.Service(ctx)
require.NoError(t, err)
cmd := client.Accounts.Containers.Workspaces.Tags.Create(c.WorkspacePath(), &gtagmanager.Tag{
cmd := c.Service().Accounts.Containers.Workspaces.Tags.Create(c.WorkspacePath(), &gtagmanager.Tag{
AccountId: c.AccountID(),
ContainerId: c.ContainerID(),
WorkspaceId: c.WorkspaceID(),
@ -379,11 +346,11 @@ func TestNewClient_Web(t *testing.T) {
Method string `json:"method"`
}
//t.Run("upsert tag", func(t *testing.T) {
// t.Run("upsert tag", func(t *testing.T) {
// obj, err := c.UpsertGA4WebTag(ctx, "login", eventParameters(Login{}))
// require.NoError(t, err)
// t.Log("ID: " + obj.TagId)
//})
// })
}
}