feat: support custom templates across multiple providers

Add the ability to specify custom template paths for various providers (e.g., Pinterest, Facebook, Umami, and more). Includes logic for resolving and provisioning templates, defaulting to embedded ones when not specified. Updated related documentation.
This commit is contained in:
Kevin Franklin Kim
2026-09-16 08:03:31 +02:00
parent d3f221e726
commit cfef82ee2d
41 changed files with 683 additions and 48 deletions
+50 -2
View File
@@ -193,6 +193,12 @@ googleTag:
googleAnalytics:
# Enable provider
enabled: true
# Custom tag template settings
templates:
# Path to a custom json request value variable template file, defaults to the embedded one
jsonRequestValueVariable: ''
# Path to a custom gtag client template file, defaults to the embedded one
gtagClient: ''
# Google Consent settings
googleConsent:
# Enable consent mode
@@ -294,6 +300,10 @@ umami:
websiteId: ''
# Endpoint url of the umami api
endpointUrl: https://umami.your-domain.com
# Custom tag template settings
templates:
# Path to a custom tag template file, defaults to the embedded one
tag: ''
# Google Consent settings
googleConsent:
# Enable consent mode
@@ -320,6 +330,12 @@ criteo:
partnerId: 123456
# Criteo applicaiton id
applicationId: com.foomo
# Custom tag template settings
templates:
# Path to a custom events api tag template file, defaults to the manually installed one
eventsApiTag: ''
# Path to a custom user identification template file, defaults to the manually installed one
userIdentification: ''
# Google Tag Manager server container settings
serverContainer:
# Path to the go.mod file
@@ -347,6 +363,10 @@ facebook:
apiAccessToken: ''
# Code used to verify that your server events are received correctly by Conversions API
testEventToken: ''
# Custom tag template settings
templates:
# Path to a custom conversions api tag template file, defaults to the manually installed one
conversionsApiTag: ''
# Google Tag Manager server container settings
# Google Consent settings
googleConsent:
@@ -377,6 +397,14 @@ emarsys:
enabled: true
# Emarsys merchant id
merchantId: ''
# Custom tag template settings
templates:
# Path to a custom web extend tag template file, defaults to the embedded one
webExtendTag: ''
# Path to a custom initialization client template file, defaults to the embedded one
initializationClient: ''
# Path to a custom initialization tag template file, defaults to the embedded one
initializationTag: ''
# Google Consent settings
googleConsent:
# Enable consent mode
@@ -403,6 +431,10 @@ tracify:
token: ''
# Tracify customer site id
customerSiteId: ''
# Custom tag template settings
templates:
# Path to a custom tag template file, defaults to the embedded one
tag: ''
# Google Consent settings
googleConsent:
# Enable consent mode
@@ -436,6 +468,10 @@ cookiebot:
# Name of the manually installed Cookiebot CMP tag template
# "https://tagmanager.google.com/gallery/#/owners/cybotcorp/templates/gtm-templates-cookiebot-cmp
templateName: Cookiebot CMP
# Custom tag template settings
templates:
# Path to a custom cmp tag template file, defaults to the manually installed one
tag: ''
# Cookiebot id
cookiebotId: ''
# CDN Region (eu, com)
@@ -463,6 +499,12 @@ cookiebot:
utm:
# Enable provider
enabled: true
# Custom tag template settings
templates:
# Path to a custom attribution variable template file, defaults to the embedded one
attributionVariable: ''
# Path to a custom cookie writer tag template file, defaults to the embedded one
cookieWriterTag: ''
# Google Consent settings
googleConsent:
# Enable consent mode
@@ -476,8 +518,10 @@ mixpanel:
enabled: true
# Project Token
projectToken: ''
# Lookup the manually installed "Mixpanel" tag template instead of provisioning it
lookupTagTemplate: false
# Custom tag template settings
templates:
# Path to a custom tag template file, defaults to the embedded one
tag: ''
# Google Consent settings
googleConsent:
# Enable consent mode
@@ -517,6 +561,10 @@ pinterest:
apiAccessToken: ''
# Enable test mode
testModeEnabled: false
# Custom tag template settings
templates:
# Path to a custom conversions tag template file, defaults to the manually installed one
tag: ''
# Google Consent settings
googleConsent:
# Enable consent mode
+9 -6
View File
@@ -8,8 +8,8 @@ Thank you for your interest in contributing to our project! This guide will help
2. Create a new branch: `git checkout -b feature/your-feature-name`
3. Make your changes
4. Check and fix code style and formatting issues: `make lint`
5. Run checks: `make test`
6. Build the project: `make build`
5. Run tests: `make test`
6. Run final checks: `make check`
7. Commit your changes using the conventions below
8. Push your branch to your fork
9. Open a pull request
@@ -29,10 +29,13 @@ We follow [Conventional Commits](https://www.conventionalcommits.org/) for clear
## Pull Request Guidelines
1. Update documentation if needed
2. Ensure all tests pass
3. Address any feedback from code reviews
4. Once approved, your PR will be merged
1. Adhere to the coding and style guidelines of the project
2. Perform a self-review of your own code
3. Comment your code, particularly in hard-to-understand areas
4. Make corresponding changes to the documentation
5. Ensure all tests pass
6. Address any feedback from code reviews
7. Once approved, your PR will be merged
## Code of Conduct & Security
+3
View File
@@ -8,6 +8,8 @@ Cookiebot CMP integration. The CLI does **not** install the Cookiebot tag templa
cookiebot:
enabled: true
templateName: Cookiebot CMP # must match the imported template's name
templates:
tag: ''
cookiebotId: ''
cdnRegion: eu # eu or com
urlPassthrough: false
@@ -29,3 +31,4 @@ cookiebot:
| `urlPassthrough` | Pass identifiers via URL parameters when consent is denied. |
| `advertiserConsentModeEnabled` | Enable advertiser consent mode signals. |
| `regionSettings[]` | Per-region default consent states. Leave `region` blank for the global default. |
| `templates.tag` | Path to a custom CMP tag template file. Empty (default) looks up the manually installed template. Overrides `templateName` lookup. |
+5
View File
@@ -10,6 +10,9 @@ criteo:
callerId: 123
partnerId: 123456
applicationId: com.foomo
templates:
eventsApiTag: ''
userIdentification: ''
serverContainer:
directory: .
packages:
@@ -30,3 +33,5 @@ criteo:
| `partnerId` | Criteo partner ID. |
| `applicationId` | Application identifier (often the reversed-domain form). |
| `serverContainer.packages` | Events to forward to Criteo. |
| `templates.eventsApiTag` | Path to a custom Events API tag template file. Empty (default) looks up the manually installed template. |
| `templates.userIdentification` | Path to a custom User Identification template file. Empty (default) looks up the manually installed template. |
+7
View File
@@ -8,6 +8,10 @@ Emarsys server-side integration.
emarsys:
enabled: true
merchantId: ''
templates:
webExtendTag: ''
initializationClient: ''
initializationTag: ''
googleConsent:
enabled: true
mode: analytics_storage
@@ -26,3 +30,6 @@ emarsys:
| `merchantId` | Emarsys merchant ID. |
| `googleConsent.mode` | Defaults to `analytics_storage`. |
| `serverContainer.packages` | Events to forward to Emarsys. |
| `templates.webExtendTag` | Path to a custom web extend tag template file. Empty (default) provisions the embedded template. |
| `templates.initializationClient` | Path to a custom initialization client template file. Empty (default) provisions the embedded template. |
| `templates.initializationTag` | Path to a custom initialization tag template file. Empty (default) provisions the embedded template. |
+3
View File
@@ -10,6 +10,8 @@ facebook:
pixelId: ''
apiAccessToken: ''
testEventToken: ''
templates:
conversionsApiTag: ''
googleConsent:
enabled: true
mode: ad_storage
@@ -36,6 +38,7 @@ facebook:
| `testEventToken` | Optional — use Meta's test events tool to verify the payload. |
| `googleConsent.mode` | Defaults to `ad_storage`. |
| `serverContainer.packages` | Events to send via Conversions API. |
| `templates.conversionsApiTag` | Path to a custom Conversions API tag template file. Empty (default) looks up the manually installed template. |
## Test events
+5
View File
@@ -8,6 +8,9 @@ GA4 web + server-side tagging.
googleAnalytics:
enabled: true
propertyId: '' # used by `sesamy open ga`
templates:
jsonRequestValueVariable: ''
gtagClient: ''
googleConsent:
enabled: true
mode: analytics_storage
@@ -41,3 +44,5 @@ googleAnalytics:
| `googleGTagJSOverride.ecommerceItems` | Normalize ecommerce items in the override. |
| `webContainer.packages` | Events handled in the web container. |
| `serverContainer.packages` | Events handled in the server container. |
| `templates.jsonRequestValueVariable` | Path to a custom JSON request value variable template file. Empty (default) provisions the embedded template. |
| `templates.gtagClient` | Path to a custom gtag client template file. Empty (default) provisions the embedded template. |
+3
View File
@@ -8,6 +8,8 @@ Microsoft Ads (Bing UET) server-side conversion tracking.
microsoftAds:
enabled: true
tagId: ''
templates:
conversionTag: ''
googleConsent:
enabled: true
mode: ad_storage
@@ -30,6 +32,7 @@ microsoftAds:
| `googleConsent.mode` | Defaults to `ad_storage`. |
| `conversion.serverContainer.settings.<event>` | List of `{ conversionLabel }` pairs — one tag per entry. |
| `conversion.serverContainer.packages` | Events to wire conversion tags for. |
| `templates.conversionTag` | Path to a custom conversion tag template file. Empty (default) provisions the embedded template. |
::: tip
Field names are based on the current schema. Run `sesamy config -c sesamy.yaml` to see the resolved values your build will use.
+14 -5
View File
@@ -10,7 +10,8 @@ Track tags send UTM attribution data, so the [UTM](./utm) provider must be enabl
mixpanel:
enabled: true
projectToken: ''
lookupTagTemplate: false
templates:
tag: ''
googleConsent:
enabled: true
mode: analytics_storage
@@ -38,7 +39,7 @@ mixpanel:
| Field | Purpose |
|-------|---------|
| `projectToken` | Mixpanel project token. |
| `lookupTagTemplate` | When `true`, look up an existing `Mixpanel` tag template instead of provisioning the built-in one. Defaults to `false`. |
| `templates.tag` | Path to a custom tag template file. Empty (default) provisions the embedded template. |
| `googleConsent.mode` | Defaults to `analytics_storage`. |
| `serverContainer.userId` | Event-data property holding the user ID, forwarded to Mixpanel. |
| `serverContainer.track.packages` | Events to forward to Mixpanel's `/track` endpoint. |
@@ -47,6 +48,14 @@ mixpanel:
By default the `Mixpanel` tag template is provisioned by the CLI — no manual template install required.
Set `lookupTagTemplate: true` to use a template you manage yourself instead. The CLI then looks up a
template named `Mixpanel` in the server container and fails if it is missing — install the
[Mixpanel](https://github.com/stape-io/mixpanel-tag) template by stape-io from the GTM gallery first.
Set `templates.tag` to the path of a template file to provision your own instead:
```yaml
mixpanel:
templates:
tag: ./templates/mixpanel.tpl
```
The file is uploaded verbatim as the template named `Mixpanel`, so it must be a complete GTM template
(`___INFO___`, `___TEMPLATE_PARAMETERS___`, `___SANDBOXED_JS_FOR_SERVER___`, …). Use the
[Mixpanel](https://github.com/stape-io/mixpanel-tag) template by stape-io as a starting point.
+3
View File
@@ -10,6 +10,8 @@ pinterest:
advertiserId: ''
apiAccessToken: ''
testModeEnabled: false
templates:
tag: ''
googleConsent:
enabled: true
mode: analytics_storage
@@ -34,3 +36,4 @@ pinterest:
| `testModeEnabled` | Send events with the `test` flag set — won't count toward live data. |
| `googleConsent.mode` | Defaults to `analytics_storage`. |
| `serverContainer.packages` | Events to send. |
| `templates.tag` | Path to a custom conversions tag template file. Empty (default) looks up the manually installed template. |
+3
View File
@@ -9,6 +9,8 @@ tracify:
enabled: true
token: ''
customerSiteId: ''
templates:
tag: ''
googleConsent:
enabled: true
mode: analytics_storage
@@ -29,3 +31,4 @@ tracify:
| `customerSiteId` | Tracify customer site identifier. |
| `googleConsent.mode` | Defaults to `analytics_storage`. |
| `serverContainer.packages` | Events to forward. |
| `templates.tag` | Path to a custom tag template file. Empty (default) provisions the embedded template. |
+3
View File
@@ -10,6 +10,8 @@ umami:
domain: your-domain.com
websiteId: ''
endpointUrl: https://umami.your-domain.com
templates:
tag: ''
googleConsent:
enabled: true
mode: analytics_storage
@@ -29,3 +31,4 @@ umami:
| `endpointUrl` | Base URL of your Umami instance. |
| `googleConsent.mode` | Defaults to `analytics_storage`. |
| `serverContainer.packages` | Events to forward. |
| `templates.tag` | Path to a custom tag template file. Empty (default) provisions the embedded template. |
+5
View File
@@ -7,6 +7,9 @@ UTM attribution for the server container. Persists the incoming UTM parameters i
```yaml
utm:
enabled: true
templates:
attributionVariable: ''
cookieWriterTag: ''
googleConsent:
enabled: true
mode: ad_storage
@@ -15,6 +18,8 @@ utm:
| Field | Purpose |
|-------|---------|
| `googleConsent.mode` | Defaults to `ad_storage`. |
| `templates.attributionVariable` | Path to a custom attribution variable template file. Empty (default) provisions the embedded template. |
| `templates.cookieWriterTag` | Path to a custom cookie writer tag template file. Empty (default) provisions the embedded template. |
## What gets provisioned
+7
View File
@@ -15,4 +15,11 @@ type Cookiebot struct {
AdvertiserConsentModeEnabled bool `json:"advertiserConsentModeEnabled" yaml:"advertiserConsentModeEnabled"`
// Default Consent state
RegionSettings []CookiebotRegionSetting `json:"regionSettings" yaml:"regionSettings"`
// Custom tag template settings
Templates CookiebotTemplates `json:"templates" yaml:"templates"`
}
type CookiebotTemplates struct {
// Path to a custom cmp tag template file, defaults to the manually installed one
Tag string `json:"tag" yaml:"tag"`
}
+9
View File
@@ -13,8 +13,17 @@ type Criteo struct {
PartnerID string `json:"partnerId" yaml:"partnerId"`
// Criteo application id
ApplicationID string `json:"applicationId" yaml:"applicationId"`
// Custom tag template settings
Templates CriteoTemplates `json:"templates" yaml:"templates"`
// Google Consent settings
GoogleConsent GoogleConsent `json:"googleConsent" yaml:"googleConsent"`
// Google Tag Manager server container settings
ServerContainer contemplate.Config `json:"serverContainer" yaml:"serverContainer"`
}
type CriteoTemplates struct {
// Path to a custom events api tag template file, defaults to the manually installed one
EventsAPITag string `json:"eventsApiTag" yaml:"eventsApiTag"`
// Path to a custom user identification template file, defaults to the manually installed one
UserIdentification string `json:"userIdentification" yaml:"userIdentification"`
}
+11
View File
@@ -13,6 +13,8 @@ type Emarsys struct {
TestMode bool `json:"testMode" yaml:"testMode"`
// Enable debug mode
DebugMode bool `json:"debugMode" yaml:"debugMode"`
// Custom tag template settings
Templates EmarsysTemplates `json:"templates" yaml:"templates"`
// Google Consent settings
GoogleConsent GoogleConsent `json:"googleConsent" yaml:"googleConsent"`
// Google Tag Manager web container settings
@@ -20,3 +22,12 @@ type Emarsys struct {
// Google Tag Manager server container settings
ServerContainer contemplate.Config `json:"serverContainer" yaml:"serverContainer"`
}
type EmarsysTemplates struct {
// Path to a custom web extend tag template file, defaults to the embedded one
WebExtendTag string `json:"webExtendTag" yaml:"webExtendTag"`
// Path to a custom initialization client template file, defaults to the embedded one
InitializationClient string `json:"initializationClient" yaml:"initializationClient"`
// Path to a custom initialization tag template file, defaults to the embedded one
InitializationTag string `json:"initializationTag" yaml:"initializationTag"`
}
+6
View File
@@ -11,6 +11,8 @@ type (
PixelID string `json:"pixelId" yaml:"pixelId"`
APIAccessToken string `json:"apiAccessToken" yaml:"apiAccessToken"`
TestEventToken string `json:"testEventToken" yaml:"testEventToken"`
// Custom tag template settings
Templates FacebookTemplates `json:"templates" yaml:"templates"`
// Google Consent settings
GoogleConsent GoogleConsent `json:"googleConsent" yaml:"googleConsent"`
// Google Tag Manager server container settings
@@ -20,6 +22,10 @@ type (
contemplate.Config `json:",inline" yaml:",squash"`
Settings map[string]FacebookConversionAPITag `json:"settings" yaml:"settings"`
}
FacebookTemplates struct {
// Path to a custom conversions api tag template file, defaults to the manually installed one
ConversionsAPITag string `json:"conversionsApiTag" yaml:"conversionsApiTag"`
}
)
func (s *FacebookServerContainer) Setting(eventName string) FacebookConversionAPITag {
+9
View File
@@ -17,8 +17,17 @@ type GoogleAnalytics struct {
GoogleGTagJSOverride GoogleAnalyticsGTagJSOverride `json:"googleGTagJSOverride" yaml:"googleGTagJSOverride"`
// Enable mpv2 user data transformation (experimental)
EnableMPv2UserDataTransformation bool `json:"enableMPv2UserDataTransformation" yaml:"enableMPv2UserDataTransformation"`
// Custom tag template settings
Templates GoogleAnalyticsTemplates `json:"templates" yaml:"templates"`
// Google Tag Manager web container settings
WebContainer contemplate.Config `json:"webContainer" yaml:"webContainer"`
// Google Tag Manager server container settings
ServerContainer contemplate.Config `json:"serverContainer" yaml:"serverContainer"`
}
type GoogleAnalyticsTemplates struct {
// Path to a custom json request value variable template file, defaults to the embedded one
JSONRequestValueVariable string `json:"jsonRequestValueVariable" yaml:"jsonRequestValueVariable"`
// Path to a custom gtag client template file, defaults to the embedded one
GTagClient string `json:"gtagClient" yaml:"gtagClient"`
}
+7
View File
@@ -9,4 +9,11 @@ type MicrosoftAds struct {
TagID string `json:"tagId" yaml:"tagId"`
// Microsoft Ads Conversion settings
Conversion MicrosoftAdsConversion `json:"conversion" yaml:"conversion"`
// Custom tag template settings
Templates MicrosoftAdsTemplates `json:"templates" yaml:"templates"`
}
type MicrosoftAdsTemplates struct {
// Path to a custom conversion tag template file, defaults to the embedded one
ConversionTag string `json:"conversionTag" yaml:"conversionTag"`
}
+6 -2
View File
@@ -10,12 +10,16 @@ type (
Enabled bool `json:"enabled" yaml:"enabled"`
// Mixpanel project token
ProjectToken string `json:"projectToken" yaml:"projectToken"`
// Lookup tag template instead of provisioning it
LookupTagTemplate bool `json:"lookupTagTemplate" yaml:"lookupTagTemplate"`
// Google Consent settings
GoogleConsent GoogleConsent `json:"googleConsent" yaml:"googleConsent"`
// Google Tag Manager server container settings
ServerContainer MixpanelServerContainer `json:"serverContainer" yaml:"serverContainer"`
// Custom tag template settings
Templates MixpanelTemplates `json:"templates" yaml:"templates"`
}
MixpanelTemplates struct {
// Path to a custom tag template file, defaults to the embedded one
Tag string `json:"tag" yaml:"tag"`
}
MixpanelServerContainer struct {
UserID string `json:"userId" yaml:"userId"`
+7
View File
@@ -13,8 +13,15 @@ type Pinterest struct {
APIAccessToken string `json:"apiAccessToken" yaml:"apiAccessToken"`
// Enable test mode
TestModeEnabled bool `json:"testModeEnabled" yaml:"testModeEnabled"`
// Custom tag template settings
Templates PinterestTemplates `json:"templates" yaml:"templates"`
// Google Consent settings
GoogleConsent GoogleConsent `json:"googleConsent" yaml:"googleConsent"`
// Google Tag Manager server container settings
ServerContainer contemplate.Config `json:"serverContainer" yaml:"serverContainer"`
}
type PinterestTemplates struct {
// Path to a custom conversions tag template file, defaults to the manually installed one
Tag string `json:"tag" yaml:"tag"`
}
+7
View File
@@ -13,8 +13,15 @@ type Tracify struct {
CustomerSiteID string `json:"customerSiteId" yaml:"customerSiteId"`
// Enable stating mode
StagingModeEnabled bool `json:"stagingModeEnabled" yaml:"stagingModeEnabled"`
// Custom tag template settings
Templates TracifyTemplates `json:"templates" yaml:"templates"`
// Google Consent settings
GoogleConsent GoogleConsent `json:"googleConsent" yaml:"googleConsent"`
// Google Tag Manager server container settings
ServerContainer contemplate.Config `json:"serverContainer" yaml:"serverContainer"`
}
type TracifyTemplates struct {
// Path to a custom tag template file, defaults to the embedded one
Tag string `json:"tag" yaml:"tag"`
}
+7
View File
@@ -10,8 +10,15 @@ type Umami struct {
Domain string `json:"domain" yaml:"domain"`
WebsiteID string `json:"websiteId" yaml:"websiteId"`
EndpointURL string `json:"endpointUrl" yaml:"endpointUrl"`
// Custom tag template settings
Templates UmamiTemplates `json:"templates" yaml:"templates"`
// Google Consent settings
GoogleConsent GoogleConsent `json:"googleConsent" yaml:"googleConsent"`
// Google Tag Manager server container settings
ServerContainer contemplate.Config `json:"serverContainer" yaml:"serverContainer"`
}
type UmamiTemplates struct {
// Path to a custom tag template file, defaults to the embedded one
Tag string `json:"tag" yaml:"tag"`
}
+9
View File
@@ -3,6 +3,15 @@ package config
type Utm struct {
// Enable provider
Enabled bool `json:"enabled" yaml:"enabled"`
// Custom tag template settings
Templates UtmTemplates `json:"templates" yaml:"templates"`
// Google Consent settings
GoogleConsent GoogleConsent `json:"googleConsent" yaml:"googleConsent"`
}
type UtmTemplates struct {
// Path to a custom attribution variable template file, defaults to the embedded one
AttributionVariable string `json:"attributionVariable" yaml:"attributionVariable"`
// Path to a custom cookie writer tag template file, defaults to the embedded one
CookieWriterTag string `json:"cookieWriterTag" yaml:"cookieWriterTag"`
}
+5 -1
View File
@@ -6,7 +6,9 @@ import (
"github.com/foomo/sesamy-cli/pkg/config"
"github.com/foomo/sesamy-cli/pkg/provider/cookiebot/web/tag"
"github.com/foomo/sesamy-cli/pkg/tagmanager"
commontemplate "github.com/foomo/sesamy-cli/pkg/tagmanager/common/template"
"github.com/pkg/errors"
tagmanager2 "google.golang.org/api/tagmanager/v2"
)
func Web(ctx context.Context, tm *tagmanager.TagManager, cfg config.Cookiebot) error {
@@ -16,7 +18,9 @@ func Web(ctx context.Context, tm *tagmanager.TagManager, cfg config.Cookiebot) e
}
{ // create event tags
temmplate, err := tm.LookupTemplate(ctx, cfg.TemplateName)
temmplate, err := commontemplate.ResolveOrLookup(ctx, tm, cfg.Templates.Tag, cfg.TemplateName, func() (*tagmanager2.CustomTemplate, error) {
return tm.LookupTemplate(ctx, cfg.TemplateName)
})
if err != nil {
return errors.Wrapf(err, "Failed to lookup `%s`, please install the `%s` gallery tag template first (%s)", cfg.TemplateName, "Cookiebot CMP", "https://tagmanager.google.com/gallery/#/owners/cybotcorp/templates/gtm-templates-cookiebot-cmp")
}
+5 -1
View File
@@ -10,9 +10,11 @@ import (
"github.com/foomo/sesamy-cli/pkg/provider/googleconsent"
googleconsentvariable "github.com/foomo/sesamy-cli/pkg/provider/googleconsent/server/variable"
"github.com/foomo/sesamy-cli/pkg/tagmanager"
commontemplate "github.com/foomo/sesamy-cli/pkg/tagmanager/common/template"
commonvariable "github.com/foomo/sesamy-cli/pkg/tagmanager/common/variable"
"github.com/foomo/sesamy-cli/pkg/utils"
"github.com/pkg/errors"
tagmanager2 "google.golang.org/api/tagmanager/v2"
)
func Server(ctx context.Context, l *slog.Logger, tm *tagmanager.TagManager, cfg config.Criteo) error {
@@ -21,7 +23,9 @@ func Server(ctx context.Context, l *slog.Logger, tm *tagmanager.TagManager, cfg
return err
}
template, err := tm.LookupTemplate(ctx, NameCriteoEventsAPITemplate)
template, err := commontemplate.ResolveOrLookup(ctx, tm, cfg.Templates.EventsAPITag, NameCriteoEventsAPITemplate, func() (*tagmanager2.CustomTemplate, error) {
return tm.LookupTemplate(ctx, NameCriteoEventsAPITemplate)
})
if err != nil {
if errors.Is(err, tagmanager.ErrNotFound) {
l.Warn("Please install the 'Criteo Events API' Tag Template manually first")
+5 -1
View File
@@ -8,7 +8,9 @@ import (
"github.com/foomo/sesamy-cli/pkg/config"
client "github.com/foomo/sesamy-cli/pkg/provider/criteo/web/tag"
"github.com/foomo/sesamy-cli/pkg/tagmanager"
commontemplate "github.com/foomo/sesamy-cli/pkg/tagmanager/common/template"
commonvariable "github.com/foomo/sesamy-cli/pkg/tagmanager/common/variable"
tagmanager2 "google.golang.org/api/tagmanager/v2"
)
func Web(ctx context.Context, l *slog.Logger, tm *tagmanager.TagManager, cfg config.Criteo) error {
@@ -17,7 +19,9 @@ func Web(ctx context.Context, l *slog.Logger, tm *tagmanager.TagManager, cfg con
return err
}
template, err := tm.LookupTemplate(ctx, NameCriteoUserIdentificationTemplate)
template, err := commontemplate.ResolveOrLookup(ctx, tm, cfg.Templates.UserIdentification, NameCriteoUserIdentificationTemplate, func() (*tagmanager2.CustomTemplate, error) {
return tm.LookupTemplate(ctx, NameCriteoUserIdentificationTemplate)
})
if err != nil {
if errors.Is(err, tagmanager.ErrNotFound) {
l.Warn("Please install the 'Criteo User Identification' template manually first")
+13 -2
View File
@@ -12,6 +12,7 @@ import (
"github.com/foomo/sesamy-cli/pkg/provider/googleconsent"
googleconsentvariable "github.com/foomo/sesamy-cli/pkg/provider/googleconsent/server/variable"
"github.com/foomo/sesamy-cli/pkg/tagmanager"
commontemplate "github.com/foomo/sesamy-cli/pkg/tagmanager/common/template"
commonvariable "github.com/foomo/sesamy-cli/pkg/tagmanager/common/variable"
"github.com/foomo/sesamy-cli/pkg/utils"
"github.com/pkg/errors"
@@ -29,12 +30,22 @@ func Server(ctx context.Context, l *slog.Logger, tm *tagmanager.TagManager, cfg
return err
}
tagTemplate, err := tm.UpsertCustomTemplate(ctx, template.NewEmarsysWebExtendTag(NameServerEmarsysWebExtendTagTemplate))
webExtendTemplate, err := commontemplate.Resolve(cfg.Templates.WebExtendTag, NameServerEmarsysWebExtendTagTemplate, template.NewEmarsysWebExtendTag(NameServerEmarsysWebExtendTagTemplate))
if err != nil {
return err
}
clientTemplate, err := tm.UpsertCustomTemplate(ctx, template.NewEmarsysInitializationClient(NameServerEmarsysInitalizationClientTemplate))
tagTemplate, err := tm.UpsertCustomTemplate(ctx, webExtendTemplate)
if err != nil {
return err
}
initializationClientTemplate, err := commontemplate.Resolve(cfg.Templates.InitializationClient, NameServerEmarsysInitalizationClientTemplate, template.NewEmarsysInitializationClient(NameServerEmarsysInitalizationClientTemplate))
if err != nil {
return err
}
clientTemplate, err := tm.UpsertCustomTemplate(ctx, initializationClientTemplate)
if err != nil {
return err
}
+7 -1
View File
@@ -10,6 +10,7 @@ import (
"github.com/foomo/sesamy-cli/pkg/provider/googletag"
commonvariable "github.com/foomo/sesamy-cli/pkg/provider/googletag/web/variable"
"github.com/foomo/sesamy-cli/pkg/tagmanager"
commontemplate "github.com/foomo/sesamy-cli/pkg/tagmanager/common/template"
commontrigger "github.com/foomo/sesamy-cli/pkg/tagmanager/common/trigger"
"github.com/pkg/errors"
)
@@ -21,7 +22,12 @@ func Web(ctx context.Context, tm *tagmanager.TagManager, cfg config.Emarsys) err
}
{ // create initialization tag
tagTemplate, err := tm.UpsertCustomTemplate(ctx, template.NewEmarsysInitializationTag(NameWebEmarsysInitalizationTagTemplate))
initializationTemplate, err := commontemplate.Resolve(cfg.Templates.InitializationTag, NameWebEmarsysInitalizationTagTemplate, template.NewEmarsysInitializationTag(NameWebEmarsysInitalizationTagTemplate))
if err != nil {
return err
}
tagTemplate, err := tm.UpsertCustomTemplate(ctx, initializationTemplate)
if err != nil {
return err
}
+4 -1
View File
@@ -10,6 +10,7 @@ import (
"github.com/foomo/sesamy-cli/pkg/provider/googleconsent"
googleconsentvariable "github.com/foomo/sesamy-cli/pkg/provider/googleconsent/server/variable"
"github.com/foomo/sesamy-cli/pkg/tagmanager"
commontemplate "github.com/foomo/sesamy-cli/pkg/tagmanager/common/template"
commonvariable "github.com/foomo/sesamy-cli/pkg/tagmanager/common/variable"
"github.com/foomo/sesamy-cli/pkg/utils"
"github.com/pkg/errors"
@@ -43,7 +44,9 @@ func Server(ctx context.Context, l *slog.Logger, tm *tagmanager.TagManager, cfg
}
}
template, err := tm.LookupTemplate(ctx, NameConversionsAPITagTemplate)
template, err := commontemplate.ResolveOrLookup(ctx, tm, cfg.Templates.ConversionsAPITag, NameConversionsAPITagTemplate, func() (*tagmanager2.CustomTemplate, error) {
return tm.LookupTemplate(ctx, NameConversionsAPITagTemplate)
})
if errors.Is(err, tagmanager.ErrNotFound) {
l.Warn("Please install the 'Conversions API Tag' by 'facebookincubator' template manually first")
return err
+13 -2
View File
@@ -13,6 +13,7 @@ import (
"github.com/foomo/sesamy-cli/pkg/provider/googletag"
"github.com/foomo/sesamy-cli/pkg/provider/googletagmanager"
"github.com/foomo/sesamy-cli/pkg/tagmanager"
commontemplate "github.com/foomo/sesamy-cli/pkg/tagmanager/common/template"
servertemplate "github.com/foomo/sesamy-cli/pkg/tagmanager/server/template"
servertransformation "github.com/foomo/sesamy-cli/pkg/tagmanager/server/transformation"
servertrigger "github.com/foomo/sesamy-cli/pkg/tagmanager/server/trigger"
@@ -61,7 +62,12 @@ func Server(ctx context.Context, tm *tagmanager.TagManager, cfg config.GoogleAna
}
if cfg.EnableMPv2UserDataTransformation {
userDataTemplate, err := tm.UpsertCustomTemplate(ctx, servertemplate.NewJSONRequestValue(NameJSONRequestValueTemplate))
jsonRequestValueTemplate, err := commontemplate.Resolve(cfg.Templates.JSONRequestValueVariable, NameJSONRequestValueTemplate, servertemplate.NewJSONRequestValue(NameJSONRequestValueTemplate))
if err != nil {
return err
}
userDataTemplate, err := tm.UpsertCustomTemplate(ctx, jsonRequestValueTemplate)
if err != nil {
return err
}
@@ -87,7 +93,12 @@ func Server(ctx context.Context, tm *tagmanager.TagManager, cfg config.GoogleAna
}
if cfg.GoogleGTagJSOverride.Enabled {
template, err := tm.UpsertCustomTemplate(ctx, googleanalyticstemplate.NewGoogleGTagClient(NameGoogleGTagClientTemplate))
gtagClientTemplate, err := commontemplate.Resolve(cfg.Templates.GTagClient, NameGoogleGTagClientTemplate, googleanalyticstemplate.NewGoogleGTagClient(NameGoogleGTagClientTemplate))
if err != nil {
return err
}
template, err := tm.UpsertCustomTemplate(ctx, gtagClientTemplate)
if err != nil {
return err
}
+7 -1
View File
@@ -11,6 +11,7 @@ import (
"github.com/foomo/sesamy-cli/pkg/provider/microsoftads/server/template"
"github.com/foomo/sesamy-cli/pkg/provider/microsoftads/server/trigger"
"github.com/foomo/sesamy-cli/pkg/tagmanager"
commontemplate "github.com/foomo/sesamy-cli/pkg/tagmanager/common/template"
commonvariable "github.com/foomo/sesamy-cli/pkg/tagmanager/common/variable"
"github.com/foomo/sesamy-cli/pkg/utils"
"github.com/pkg/errors"
@@ -28,7 +29,12 @@ func Server(ctx context.Context, l *slog.Logger, tm *tagmanager.TagManager, cfg
}
if cfg.Conversion.Enabled {
tagTemplate, err := tm.UpsertCustomTemplate(ctx, template.NewConversionTag(NameConversionsTagTemplate))
conversionTemplate, err := commontemplate.Resolve(cfg.Templates.ConversionTag, NameConversionsTagTemplate, template.NewConversionTag(NameConversionsTagTemplate))
if err != nil {
return err
}
tagTemplate, err := tm.UpsertCustomTemplate(ctx, conversionTemplate)
if err != nil {
return err
}
+8 -12
View File
@@ -13,6 +13,7 @@ import (
"github.com/foomo/sesamy-cli/pkg/provider/mixpanel/server/trigger"
utmprovider "github.com/foomo/sesamy-cli/pkg/provider/utm"
"github.com/foomo/sesamy-cli/pkg/tagmanager"
commontemplate "github.com/foomo/sesamy-cli/pkg/tagmanager/common/template"
commonvariable "github.com/foomo/sesamy-cli/pkg/tagmanager/common/variable"
"github.com/foomo/sesamy-cli/pkg/tagmanager/server/variable"
"github.com/foomo/sesamy-cli/pkg/utils"
@@ -31,19 +32,14 @@ func Server(ctx context.Context, l *slog.Logger, tm *tagmanager.TagManager, cfg
return err
}
var template *tagmanager2.CustomTemplate
if cfg.LookupTagTemplate {
if template, err = tm.LookupTemplate(ctx, NameTagTemplate); err != nil {
if errors.Is(err, tagmanager.ErrNotFound) {
l.Warn("Please install the 'Mixpanel' by stape-io Tag Template manually first")
}
tagTemplate, err := commontemplate.Resolve(cfg.Templates.Tag, NameTagTemplate, mixpaneltemplate.NewMixpanelTag(NameTagTemplate))
if err != nil {
return err
}
return err
}
} else {
if template, err = tm.UpsertCustomTemplate(ctx, mixpaneltemplate.NewMixpanelTag(NameTagTemplate)); err != nil {
return err
}
template, err := tm.UpsertCustomTemplate(ctx, tagTemplate)
if err != nil {
return err
}
projectToken, err := tm.UpsertVariable(ctx, folder, commonvariable.NewConstant(NamePrjectTokenConstant, cfg.ProjectToken))
+5 -1
View File
@@ -10,8 +10,10 @@ import (
containertag "github.com/foomo/sesamy-cli/pkg/provider/pinterest/server/tag"
"github.com/foomo/sesamy-cli/pkg/provider/pinterest/server/trigger"
"github.com/foomo/sesamy-cli/pkg/tagmanager"
commontemplate "github.com/foomo/sesamy-cli/pkg/tagmanager/common/template"
"github.com/foomo/sesamy-cli/pkg/utils"
"github.com/pkg/errors"
tagmanager2 "google.golang.org/api/tagmanager/v2"
)
func Server(ctx context.Context, l *slog.Logger, tm *tagmanager.TagManager, cfg config.Pinterest) error {
@@ -20,7 +22,9 @@ func Server(ctx context.Context, l *slog.Logger, tm *tagmanager.TagManager, cfg
return err
}
template, err := tm.LookupTemplate(ctx, NameTagTemplate)
template, err := commontemplate.ResolveOrLookup(ctx, tm, cfg.Templates.Tag, NameTagTemplate, func() (*tagmanager2.CustomTemplate, error) {
return tm.LookupTemplate(ctx, NameTagTemplate)
})
if err != nil {
if errors.Is(err, tagmanager.ErrNotFound) {
l.Warn("Please install the 'Pinterest API for Conversions Tag' Tag Template manually first")
+7 -1
View File
@@ -11,6 +11,7 @@ import (
"github.com/foomo/sesamy-cli/pkg/provider/tracify/server/template"
"github.com/foomo/sesamy-cli/pkg/provider/tracify/server/trigger"
"github.com/foomo/sesamy-cli/pkg/tagmanager"
commontemplate "github.com/foomo/sesamy-cli/pkg/tagmanager/common/template"
commonvariable "github.com/foomo/sesamy-cli/pkg/tagmanager/common/variable"
"github.com/foomo/sesamy-cli/pkg/utils"
"github.com/pkg/errors"
@@ -33,7 +34,12 @@ func Server(ctx context.Context, l *slog.Logger, tm *tagmanager.TagManager, cfg
return err
}
tagTemplate, err := tm.UpsertCustomTemplate(ctx, template.NewTracifyTag(NameTracifyServerTagTemplate))
tracifyTemplate, err := commontemplate.Resolve(cfg.Templates.Tag, NameTracifyServerTagTemplate, template.NewTracifyTag(NameTracifyServerTagTemplate))
if err != nil {
return err
}
tagTemplate, err := tm.UpsertCustomTemplate(ctx, tracifyTemplate)
if err != nil {
return err
}
+7 -1
View File
@@ -10,6 +10,7 @@ import (
containertemplate "github.com/foomo/sesamy-cli/pkg/provider/umami/server/template"
"github.com/foomo/sesamy-cli/pkg/provider/umami/server/trigger"
"github.com/foomo/sesamy-cli/pkg/tagmanager"
commontemplate "github.com/foomo/sesamy-cli/pkg/tagmanager/common/template"
"github.com/foomo/sesamy-cli/pkg/utils"
"github.com/pkg/errors"
)
@@ -20,7 +21,12 @@ func Server(ctx context.Context, tm *tagmanager.TagManager, cfg config.Umami) er
return err
}
template, err := tm.UpsertCustomTemplate(ctx, containertemplate.NewUmami(Name))
umamiTemplate, err := commontemplate.Resolve(cfg.Templates.Tag, Name, containertemplate.NewUmami(Name))
if err != nil {
return err
}
template, err := tm.UpsertCustomTemplate(ctx, umamiTemplate)
if err != nil {
return err
}
+13 -2
View File
@@ -11,6 +11,7 @@ import (
"github.com/foomo/sesamy-cli/pkg/provider/utm/server/trigger"
containervariable "github.com/foomo/sesamy-cli/pkg/provider/utm/server/variable"
"github.com/foomo/sesamy-cli/pkg/tagmanager"
commontemplate "github.com/foomo/sesamy-cli/pkg/tagmanager/common/template"
"github.com/pkg/errors"
)
@@ -20,7 +21,12 @@ func Server(ctx context.Context, tm *tagmanager.TagManager, cfg config.Utm) erro
return err
}
variableTemplate, err := tm.UpsertCustomTemplate(ctx, containertemplate.NewUtmAttribution(NameUtmAttributionVariableTemplate))
attributionTemplate, err := commontemplate.Resolve(cfg.Templates.AttributionVariable, NameUtmAttributionVariableTemplate, containertemplate.NewUtmAttribution(NameUtmAttributionVariableTemplate))
if err != nil {
return err
}
variableTemplate, err := tm.UpsertCustomTemplate(ctx, attributionTemplate)
if err != nil {
return err
}
@@ -29,7 +35,12 @@ func Server(ctx context.Context, tm *tagmanager.TagManager, cfg config.Utm) erro
return err
}
tagTemplate, err := tm.UpsertCustomTemplate(ctx, containertemplate.NewUtmAttributionCookieWriter(NameUtmAttributionCookieWriterTemplate))
cookieWriterTemplate, err := commontemplate.Resolve(cfg.Templates.CookieWriterTag, NameUtmAttributionCookieWriterTemplate, containertemplate.NewUtmAttributionCookieWriter(NameUtmAttributionCookieWriterTemplate))
if err != nil {
return err
}
tagTemplate, err := tm.UpsertCustomTemplate(ctx, cookieWriterTemplate)
if err != nil {
return err
}
@@ -0,0 +1,57 @@
package template
import (
"context"
"os"
"github.com/pkg/errors"
"google.golang.org/api/tagmanager/v2"
)
// NewFromFile loads a custom template from the given path. The file contents are
// used verbatim, so it must be a complete GTM template.
func NewFromFile(name, filename string) (*tagmanager.CustomTemplate, error) {
data, err := os.ReadFile(filename)
if err != nil {
return nil, errors.Wrap(err, "failed to read tag template: "+filename)
}
return &tagmanager.CustomTemplate{
Name: name,
TemplateData: string(data),
}, nil
}
// Resolve returns the template loaded from filename, or embedded if filename is empty.
func Resolve(filename, name string, embedded *tagmanager.CustomTemplate) (*tagmanager.CustomTemplate, error) {
if filename == "" {
return embedded, nil
}
return NewFromFile(name, filename)
}
// Upserter provisions a custom template, e.g. tagmanager.TagManager.
type Upserter interface {
UpsertCustomTemplate(ctx context.Context, item *tagmanager.CustomTemplate) (*tagmanager.CustomTemplate, error)
}
// ResolveOrLookup provisions the template from filename when set, otherwise it falls
// back to lookup, which is used by providers relying on a manually installed template.
func ResolveOrLookup(
ctx context.Context,
tm Upserter,
filename, name string,
lookup func() (*tagmanager.CustomTemplate, error),
) (*tagmanager.CustomTemplate, error) {
if filename == "" {
return lookup()
}
item, err := NewFromFile(name, filename)
if err != nil {
return nil, err
}
return tm.UpsertCustomTemplate(ctx, item)
}
@@ -0,0 +1,153 @@
package template_test
import (
"context"
"os"
"path/filepath"
"testing"
"github.com/foomo/sesamy-cli/pkg/tagmanager/common/template"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"google.golang.org/api/tagmanager/v2"
)
func TestNewFromFile(t *testing.T) {
t.Parallel()
tests := []struct {
name string
data string
filename string
wantErr bool
}{
{
name: "reads template verbatim",
data: "___INFO___\n\n{\n \"type\": \"TAG\"\n}\n",
filename: "mixpanel.tpl",
},
{
name: "keeps percent verbs untouched",
data: "___INFO___ 100% \"displayName\": \"%s\"\n",
filename: "verbs.tpl",
},
{
name: "missing file",
filename: "does-not-exist.tpl",
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
path := filepath.Join(t.TempDir(), tt.filename)
if !tt.wantErr {
require.NoError(t, os.WriteFile(path, []byte(tt.data), 0o600))
}
actual, err := template.NewFromFile("Mixpanel", path)
if tt.wantErr {
require.Error(t, err)
assert.Nil(t, actual)
return
}
require.NoError(t, err)
assert.Equal(t, "Mixpanel", actual.Name)
assert.Equal(t, tt.data, actual.TemplateData)
})
}
}
func TestResolve(t *testing.T) {
t.Parallel()
embedded := &tagmanager.CustomTemplate{Name: "Embedded", TemplateData: "___INFO___ embedded"}
t.Run("empty path returns embedded", func(t *testing.T) {
t.Parallel()
actual, err := template.Resolve("", "Custom", embedded)
require.NoError(t, err)
assert.Same(t, embedded, actual)
})
t.Run("path overrides embedded", func(t *testing.T) {
t.Parallel()
path := filepath.Join(t.TempDir(), "custom.tpl")
require.NoError(t, os.WriteFile(path, []byte("___INFO___ custom"), 0o600))
actual, err := template.Resolve(path, "Custom", embedded)
require.NoError(t, err)
assert.Equal(t, "Custom", actual.Name)
assert.Equal(t, "___INFO___ custom", actual.TemplateData)
})
t.Run("missing path errors", func(t *testing.T) {
t.Parallel()
actual, err := template.Resolve(filepath.Join(t.TempDir(), "nope.tpl"), "Custom", embedded)
require.Error(t, err)
assert.Nil(t, actual)
})
}
type upserterStub struct {
called bool
item *tagmanager.CustomTemplate
}
func (u *upserterStub) UpsertCustomTemplate(_ context.Context, item *tagmanager.CustomTemplate) (*tagmanager.CustomTemplate, error) {
u.called = true
u.item = item
return item, nil
}
func TestResolveOrLookup(t *testing.T) {
t.Parallel()
looked := &tagmanager.CustomTemplate{Name: "Gallery", TemplateData: "___INFO___ gallery"}
lookup := func() (*tagmanager.CustomTemplate, error) { return looked, nil }
t.Run("empty path looks up without upserting", func(t *testing.T) {
t.Parallel()
tm := &upserterStub{}
actual, err := template.ResolveOrLookup(t.Context(), tm, "", "Custom", lookup)
require.NoError(t, err)
assert.Same(t, looked, actual)
assert.False(t, tm.called, "must not provision when no override is set")
})
t.Run("path upserts instead of looking up", func(t *testing.T) {
t.Parallel()
path := filepath.Join(t.TempDir(), "custom.tpl")
require.NoError(t, os.WriteFile(path, []byte("___INFO___ custom"), 0o600))
tm := &upserterStub{}
actual, err := template.ResolveOrLookup(t.Context(), tm, path, "Custom", lookup)
require.NoError(t, err)
require.True(t, tm.called, "must provision the custom template")
assert.Equal(t, "Custom", actual.Name)
assert.Equal(t, "___INFO___ custom", actual.TemplateData)
})
t.Run("missing path errors without upserting", func(t *testing.T) {
t.Parallel()
tm := &upserterStub{}
actual, err := template.ResolveOrLookup(t.Context(), tm, filepath.Join(t.TempDir(), "nope.tpl"), "Custom", lookup)
require.Error(t, err)
assert.Nil(t, actual)
assert.False(t, tm.called)
})
}
+2 -2
View File
@@ -928,8 +928,8 @@ func (t *TagManager) UpsertCustomTemplate(ctx context.Context, item *tagmanager.
} else if strings.Trim(item.TemplateData, "\n") == strings.Trim(cache.TemplateData, "\n") {
l.Info("└ ✔︎ OK", "id", cache.TemplateId)
} else {
edits := myers.ComputeEdits(span.URIFromPath("item.txt"), item.TemplateData, cache.TemplateData)
diff := gotextdiff.ToUnified("item.txt", "cache.txt", item.TemplateData, edits)
edits := myers.ComputeEdits(span.URIFromPath("item.tpl"), cache.TemplateData, item.TemplateData)
diff := gotextdiff.ToUnified("item.tpl", "cache.tpl", cache.TemplateData, edits)
l.Info("└ 🔄 Update", "id", cache.TemplateId)
l.Info(fmt.Sprint(diff))
+174 -4
View File
@@ -187,6 +187,10 @@
"regionSettings": {
"$ref": "#/$defs/[]config.CookiebotRegionSetting",
"description": "Default Consent state"
},
"templates": {
"$ref": "#/$defs/github.com.foomo.sesamy-cli.pkg.config.CookiebotTemplates",
"description": "Custom tag template settings"
}
},
"additionalProperties": false,
@@ -222,6 +226,16 @@
"additionalProperties": false,
"type": "object"
},
"github.com.foomo.sesamy-cli.pkg.config.CookiebotTemplates": {
"properties": {
"tag": {
"type": "string",
"description": "Path to a custom cmp tag template file, defaults to the manually installed one"
}
},
"additionalProperties": false,
"type": "object"
},
"github.com.foomo.sesamy-cli.pkg.config.Criteo": {
"properties": {
"enabled": {
@@ -240,6 +254,10 @@
"type": "string",
"description": "Criteo application id"
},
"templates": {
"$ref": "#/$defs/github.com.foomo.sesamy-cli.pkg.config.CriteoTemplates",
"description": "Custom tag template settings"
},
"googleConsent": {
"$ref": "#/$defs/github.com.foomo.sesamy-cli.pkg.config.GoogleConsent",
"description": "Google Consent settings"
@@ -252,6 +270,20 @@
"additionalProperties": false,
"type": "object"
},
"github.com.foomo.sesamy-cli.pkg.config.CriteoTemplates": {
"properties": {
"eventsApiTag": {
"type": "string",
"description": "Path to a custom events api tag template file, defaults to the manually installed one"
},
"userIdentification": {
"type": "string",
"description": "Path to a custom user identification template file, defaults to the manually installed one"
}
},
"additionalProperties": false,
"type": "object"
},
"github.com.foomo.sesamy-cli.pkg.config.Emarsys": {
"properties": {
"enabled": {
@@ -270,6 +302,10 @@
"type": "boolean",
"description": "Enable debug mode"
},
"templates": {
"$ref": "#/$defs/github.com.foomo.sesamy-cli.pkg.config.EmarsysTemplates",
"description": "Custom tag template settings"
},
"googleConsent": {
"$ref": "#/$defs/github.com.foomo.sesamy-cli.pkg.config.GoogleConsent",
"description": "Google Consent settings"
@@ -286,6 +322,24 @@
"additionalProperties": false,
"type": "object"
},
"github.com.foomo.sesamy-cli.pkg.config.EmarsysTemplates": {
"properties": {
"webExtendTag": {
"type": "string",
"description": "Path to a custom web extend tag template file, defaults to the embedded one"
},
"initializationClient": {
"type": "string",
"description": "Path to a custom initialization client template file, defaults to the embedded one"
},
"initializationTag": {
"type": "string",
"description": "Path to a custom initialization tag template file, defaults to the embedded one"
}
},
"additionalProperties": false,
"type": "object"
},
"github.com.foomo.sesamy-cli.pkg.config.Facebook": {
"properties": {
"enabled": {
@@ -301,6 +355,10 @@
"testEventToken": {
"type": "string"
},
"templates": {
"$ref": "#/$defs/github.com.foomo.sesamy-cli.pkg.config.FacebookTemplates",
"description": "Custom tag template settings"
},
"googleConsent": {
"$ref": "#/$defs/github.com.foomo.sesamy-cli.pkg.config.GoogleConsent",
"description": "Google Consent settings"
@@ -342,6 +400,16 @@
"additionalProperties": false,
"type": "object"
},
"github.com.foomo.sesamy-cli.pkg.config.FacebookTemplates": {
"properties": {
"conversionsApiTag": {
"type": "string",
"description": "Path to a custom conversions api tag template file, defaults to the manually installed one"
}
},
"additionalProperties": false,
"type": "object"
},
"github.com.foomo.sesamy-cli.pkg.config.GoogleAPI": {
"properties": {
"credentials": {
@@ -466,6 +534,10 @@
"type": "boolean",
"description": "Enable mpv2 user data transformation (experimental)"
},
"templates": {
"$ref": "#/$defs/github.com.foomo.sesamy-cli.pkg.config.GoogleAnalyticsTemplates",
"description": "Custom tag template settings"
},
"webContainer": {
"$ref": "#/$defs/github.com.foomo.gocontemplate.pkg.contemplate.Config",
"description": "Google Tag Manager web container settings"
@@ -496,6 +568,20 @@
"additionalProperties": false,
"type": "object"
},
"github.com.foomo.sesamy-cli.pkg.config.GoogleAnalyticsTemplates": {
"properties": {
"jsonRequestValueVariable": {
"type": "string",
"description": "Path to a custom json request value variable template file, defaults to the embedded one"
},
"gtagClient": {
"type": "string",
"description": "Path to a custom gtag client template file, defaults to the embedded one"
}
},
"additionalProperties": false,
"type": "object"
},
"github.com.foomo.sesamy-cli.pkg.config.GoogleConsent": {
"properties": {
"enabled": {
@@ -659,6 +745,10 @@
"conversion": {
"$ref": "#/$defs/github.com.foomo.sesamy-cli.pkg.config.MicrosoftAdsConversion",
"description": "Microsoft Ads Conversion settings"
},
"templates": {
"$ref": "#/$defs/github.com.foomo.sesamy-cli.pkg.config.MicrosoftAdsTemplates",
"description": "Custom tag template settings"
}
},
"additionalProperties": false,
@@ -705,6 +795,16 @@
"additionalProperties": false,
"type": "object"
},
"github.com.foomo.sesamy-cli.pkg.config.MicrosoftAdsTemplates": {
"properties": {
"conversionTag": {
"type": "string",
"description": "Path to a custom conversion tag template file, defaults to the embedded one"
}
},
"additionalProperties": false,
"type": "object"
},
"github.com.foomo.sesamy-cli.pkg.config.Mixpanel": {
"properties": {
"enabled": {
@@ -715,10 +815,6 @@
"type": "string",
"description": "Mixpanel project token"
},
"lookupTagTemplate": {
"type": "boolean",
"description": "Lookup tag template instead of provisioning it"
},
"googleConsent": {
"$ref": "#/$defs/github.com.foomo.sesamy-cli.pkg.config.GoogleConsent",
"description": "Google Consent settings"
@@ -726,6 +822,10 @@
"serverContainer": {
"$ref": "#/$defs/github.com.foomo.sesamy-cli.pkg.config.MixpanelServerContainer",
"description": "Google Tag Manager server container settings"
},
"templates": {
"$ref": "#/$defs/github.com.foomo.sesamy-cli.pkg.config.MixpanelTemplates",
"description": "Custom tag template settings"
}
},
"additionalProperties": false,
@@ -756,6 +856,16 @@
"additionalProperties": false,
"type": "object"
},
"github.com.foomo.sesamy-cli.pkg.config.MixpanelTemplates": {
"properties": {
"tag": {
"type": "string",
"description": "Path to a custom tag template file, defaults to the embedded one"
}
},
"additionalProperties": false,
"type": "object"
},
"github.com.foomo.sesamy-cli.pkg.config.Pinterest": {
"properties": {
"enabled": {
@@ -774,6 +884,10 @@
"type": "boolean",
"description": "Enable test mode"
},
"templates": {
"$ref": "#/$defs/github.com.foomo.sesamy-cli.pkg.config.PinterestTemplates",
"description": "Custom tag template settings"
},
"googleConsent": {
"$ref": "#/$defs/github.com.foomo.sesamy-cli.pkg.config.GoogleConsent",
"description": "Google Consent settings"
@@ -786,6 +900,16 @@
"additionalProperties": false,
"type": "object"
},
"github.com.foomo.sesamy-cli.pkg.config.PinterestTemplates": {
"properties": {
"tag": {
"type": "string",
"description": "Path to a custom conversions tag template file, defaults to the manually installed one"
}
},
"additionalProperties": false,
"type": "object"
},
"github.com.foomo.sesamy-cli.pkg.config.Tracify": {
"properties": {
"enabled": {
@@ -804,6 +928,10 @@
"type": "boolean",
"description": "Enable stating mode"
},
"templates": {
"$ref": "#/$defs/github.com.foomo.sesamy-cli.pkg.config.TracifyTemplates",
"description": "Custom tag template settings"
},
"googleConsent": {
"$ref": "#/$defs/github.com.foomo.sesamy-cli.pkg.config.GoogleConsent",
"description": "Google Consent settings"
@@ -816,6 +944,16 @@
"additionalProperties": false,
"type": "object"
},
"github.com.foomo.sesamy-cli.pkg.config.TracifyTemplates": {
"properties": {
"tag": {
"type": "string",
"description": "Path to a custom tag template file, defaults to the embedded one"
}
},
"additionalProperties": false,
"type": "object"
},
"github.com.foomo.sesamy-cli.pkg.config.TypeScript": {
"properties": {
"directory": {
@@ -846,6 +984,10 @@
"endpointUrl": {
"type": "string"
},
"templates": {
"$ref": "#/$defs/github.com.foomo.sesamy-cli.pkg.config.UmamiTemplates",
"description": "Custom tag template settings"
},
"googleConsent": {
"$ref": "#/$defs/github.com.foomo.sesamy-cli.pkg.config.GoogleConsent",
"description": "Google Consent settings"
@@ -858,12 +1000,26 @@
"additionalProperties": false,
"type": "object"
},
"github.com.foomo.sesamy-cli.pkg.config.UmamiTemplates": {
"properties": {
"tag": {
"type": "string",
"description": "Path to a custom tag template file, defaults to the embedded one"
}
},
"additionalProperties": false,
"type": "object"
},
"github.com.foomo.sesamy-cli.pkg.config.Utm": {
"properties": {
"enabled": {
"type": "boolean",
"description": "Enable provider"
},
"templates": {
"$ref": "#/$defs/github.com.foomo.sesamy-cli.pkg.config.UtmTemplates",
"description": "Custom tag template settings"
},
"googleConsent": {
"$ref": "#/$defs/github.com.foomo.sesamy-cli.pkg.config.GoogleConsent",
"description": "Google Consent settings"
@@ -872,6 +1028,20 @@
"additionalProperties": false,
"type": "object"
},
"github.com.foomo.sesamy-cli.pkg.config.UtmTemplates": {
"properties": {
"attributionVariable": {
"type": "string",
"description": "Path to a custom attribution variable template file, defaults to the embedded one"
},
"cookieWriterTag": {
"type": "string",
"description": "Path to a custom cookie writer tag template file, defaults to the embedded one"
}
},
"additionalProperties": false,
"type": "object"
},
"map[string][]config.GoogleAdsConversionTracking": {
"additionalProperties": {
"$ref": "#/$defs/[]config.GoogleAdsConversionTracking"