diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 8393d11..fdac198 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -41,6 +41,7 @@ jobs: files: | dist/clickstream-web.min.js dist/clickstream-web.min.js.map + gtm-template/ClickstreamAnalytics-gtm-template.tpl tag_name: "v${{ env.NEW_VERSION }}" prerelease: true generate_release_notes: true diff --git a/README.md b/README.md index 248b22b..164792e 100644 --- a/README.md +++ b/README.md @@ -209,6 +209,19 @@ ClickstreamAnalytics.updateConfigure({ }); ``` +## Implementing Clickstream Web SDK in Google Tag Manager Using Template + +1. Download the Clickstream SDK template file (.tpl) from the [SDK Release Page](https://github.com/awslabs/clickstream-web/releases). +2. Refer to the Google Tag Manager [Import Guide](https://developers.google.com/tag-platform/tag-manager/templates#export_and_import) for instructions on importing the .tpl file as a custom template in your tag manager console. +3. Refer to the [Use your new tag](https://developers.google.com/tag-platform/tag-manager/templates#use_your_new_tag) to add ClickstreamAnalytics tag to your container. +4. The ClickstreamAnalytics tag currently supports four tag types: + * Initialize SDK + * Record Custom Event + * Set User ID + * Set User Attribute + + Note: Ensure that you initialize the SDK tag first before use other ClickstreamAnalytics tag types. + ## How to integrate and test locally ### Integrate the `.tgz` file diff --git a/gtm-template/ClickstreamAnalytics-gtm-template.tpl b/gtm-template/ClickstreamAnalytics-gtm-template.tpl new file mode 100644 index 0000000..624cb21 --- /dev/null +++ b/gtm-template/ClickstreamAnalytics-gtm-template.tpl @@ -0,0 +1,729 @@ +___INFO___ + +{ + "type": "TAG", + "id": "cvt_temp_public_id", + "version": 1, + "securityGroups": [], + "displayName": "ClickstreamAnalytics", + "brand": { + "id": "brand_dummy", + "displayName": "", + "thumbnail": "data:image/png;base64,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" + }, + "description": "", + "containerContexts": [ + "WEB" + ] +} + + +___TEMPLATE_PARAMETERS___ + +[ + { + "type": "SELECT", + "name": "tagType", + "displayName": "Tag Type", + "selectItems": [ + { + "value": "init", + "displayValue": "Initialize SDK" + }, + { + "value": "record", + "displayValue": "Record Custom Event" + }, + { + "value": "setUserId", + "displayValue": "Set User ID" + }, + { + "value": "setUserAttributes", + "displayValue": "Set User Attributes" + } + ], + "simpleValueType": true, + "help": "Choose the Tag type for Clickstream Analytics", + "defaultValue": "init" + }, + { + "type": "TEXT", + "name": "appId", + "displayName": "App ID", + "simpleValueType": true, + "valueValidators": [ + { + "type": "NON_EMPTY" + } + ], + "enablingConditions": [ + { + "paramName": "tagType", + "paramValue": "init", + "type": "EQUALS" + } + ] + }, + { + "type": "TEXT", + "name": "endpoint", + "displayName": "Endpoint URL", + "simpleValueType": true, + "valueValidators": [ + { + "type": "NON_EMPTY" + } + ], + "enablingConditions": [ + { + "paramName": "tagType", + "paramValue": "init", + "type": "EQUALS" + } + ] + }, + { + "type": "GROUP", + "name": "globalAttributeGroup", + "displayName": "Add Global Attributes", + "groupStyle": "ZIPPY_CLOSED", + "subParams": [ + { + "type": "SIMPLE_TABLE", + "name": "globalAttributes", + "simpleTableColumns": [ + { + "defaultValue": "", + "displayName": "Name", + "name": "name", + "type": "TEXT" + }, + { + "defaultValue": "", + "displayName": "Value", + "name": "value", + "type": "TEXT" + } + ] + } + ], + "enablingConditions": [ + { + "paramName": "tagType", + "paramValue": "init", + "type": "EQUALS" + } + ] + }, + { + "type": "GROUP", + "name": "configurationGroup", + "displayName": "Configuration", + "groupStyle": "ZIPPY_CLOSED", + "subParams": [ + { + "type": "RADIO", + "name": "sendMode", + "radioItems": [ + { + "value": "Immediate", + "displayValue": "Immediate" + }, + { + "value": "Batch", + "displayValue": "Batch" + } + ], + "simpleValueType": true, + "defaultValue": "Immediate", + "displayName": "Send Event Mode" + }, + { + "type": "RADIO", + "name": "pageType", + "radioItems": [ + { + "value": "SPA", + "displayValue": "SPA" + }, + { + "value": "multiPageApp", + "displayValue": "multiPageApp" + } + ], + "simpleValueType": true, + "defaultValue": "SPA", + "displayName": "Application Page Type" + }, + { + "type": "LABEL", + "name": "presetEvents", + "displayName": "Preset Events Setting" + }, + { + "type": "CHECKBOX", + "name": "isTrackPageViewEvents", + "checkboxText": "isTrackPageViewEvents", + "simpleValueType": true, + "defaultValue": true + }, + { + "type": "CHECKBOX", + "name": "isTrackUserEngagementEvents", + "checkboxText": "isTrackUserEngagementEvents", + "simpleValueType": true, + "defaultValue": true + }, + { + "type": "CHECKBOX", + "name": "isTrackClickEvents", + "checkboxText": "isTrackClickEvents", + "simpleValueType": true, + "defaultValue": true + }, + { + "type": "CHECKBOX", + "name": "isTrackSearchEvents", + "checkboxText": "isTrackSearchEvents", + "simpleValueType": true, + "defaultValue": true + }, + { + "type": "CHECKBOX", + "name": "isTrackScrollEvents", + "checkboxText": "isTrackScrollEvents", + "simpleValueType": true, + "defaultValue": true + }, + { + "type": "CHECKBOX", + "name": "isTrackAppStartEvents", + "checkboxText": "isTrackAppStartEvents", + "simpleValueType": true, + "defaultValue": false + }, + { + "type": "CHECKBOX", + "name": "isTrackAppEndEvents", + "checkboxText": "isTrackAppEndEvents", + "simpleValueType": true, + "defaultValue": false + }, + { + "type": "CHECKBOX", + "name": "isLogEvents", + "checkboxText": "isLogEvents", + "simpleValueType": true, + "defaultValue": false, + "displayName": "Whether log events in console for debugging" + }, + { + "type": "TEXT", + "name": "sendEventsInterval", + "displayName": "Send Events Interval (ms)", + "simpleValueType": true, + "defaultValue": 5000 + }, + { + "type": "TEXT", + "name": "sessionTimeoutDuration", + "displayName": "Session Timeout Duration (ms)", + "simpleValueType": true, + "defaultValue": 1800000 + } + ], + "enablingConditions": [ + { + "paramName": "tagType", + "paramValue": "init", + "type": "EQUALS" + } + ] + }, + { + "type": "TEXT", + "name": "eventName", + "displayName": "Event Name", + "simpleValueType": true, + "enablingConditions": [ + { + "paramName": "tagType", + "paramValue": "record", + "type": "EQUALS" + } + ] + }, + { + "type": "SIMPLE_TABLE", + "name": "attributes", + "displayName": "Add Attribute", + "simpleTableColumns": [ + { + "defaultValue": "", + "displayName": "Name", + "name": "name", + "type": "TEXT" + }, + { + "defaultValue": "", + "displayName": "Value", + "name": "value", + "type": "TEXT" + } + ], + "enablingConditions": [ + { + "paramName": "tagType", + "paramValue": "record", + "type": "EQUALS" + } + ] + }, + { + "type": "TEXT", + "name": "userId", + "displayName": "User Id", + "simpleValueType": true, + "enablingConditions": [ + { + "paramName": "tagType", + "paramValue": "setUserId", + "type": "EQUALS" + } + ] + }, + { + "type": "SIMPLE_TABLE", + "name": "userAttributes", + "displayName": "User Attribute", + "simpleTableColumns": [ + { + "defaultValue": "", + "displayName": "Name", + "name": "name", + "type": "TEXT" + }, + { + "defaultValue": "", + "displayName": "Value", + "name": "value", + "type": "TEXT" + } + ], + "enablingConditions": [ + { + "paramName": "tagType", + "paramValue": "setUserAttributes", + "type": "EQUALS" + } + ] + } +] + + +___SANDBOXED_JS_FOR_WEB_TEMPLATE___ + +// Enter your template code here. +const log = require('logToConsole'); +log('data =', data); + +const callInWindow = require('callInWindow'); +const injectScript = require('injectScript'); +const callLater = require('callLater'); +const makeNumber = require('makeNumber'); + +const tagType = data.tagType; +const onLoadClickstreamSuccess = function () { + callLater(function () { + if (tagType === "init") { + let globalAttributes = {}; + if (data.globalAttributes) { + globalAttributes = data.globalAttributes.reduce((obj, item) => { + obj[item.name] = item.value; + return obj; + }, {}); + } + const initParams = { + appId: data.appId, + endpoint: data.endpoint, + sendMode: data.sendMode, + pageType: data.pageType, + isLogEvents: data.isLogEvents, + isTrackClickEvents: data.isTrackClickEvents, + isTrackPageViewEvents: data.isTrackPageViewEvents, + isTrackUserEngagementEvents: data.isTrackUserEngagementEvents, + isTrackAppStartEvents: data.isTrackAppStartEvents, + isTrackAppEndEvents: data.isTrackAppEndEvents, + isTrackScrollEvents: data.isTrackScrollEvents, + isTrackSearchEvents: data.isTrackSearchEvents, + sendEventsInterval: makeNumber(data.sendEventsInterval), + sessionTimeoutDuration: makeNumber(data.sessionTimeoutDuration), + globalAttributes: globalAttributes, + }; + callInWindow("ClickstreamAnalytics.init", initParams); + } else if (tagType === "record") { + const eventName = data.eventName; + const attributes = data.attributes.reduce((obj, item) => { + obj[item.name] = item.value; + return obj; + }, {}); + callInWindow("ClickstreamAnalytics.record", { + name: eventName, + attributes: attributes + }); + } else if (tagType === "setUserId") { + let userId = data.userId; + if (userId === "" || userId === "null") { + userId = null; + } + callInWindow("ClickstreamAnalytics.setUserId", userId); + } else if (tagType === "setUserAttributes") { + const userAttributes = data.userAttributes.reduce((obj, item) => { + obj[item.name] = item.value; + return obj; + }, {}); + callInWindow("ClickstreamAnalytics.setUserAttributes", userAttributes); + } + + data.gtmOnSuccess(); + }); +}; + +const url = "https://github.com/awslabs/clickstream-web/releases/download/v0.9.1/clickstream-web.min.js"; +injectScript(url, onLoadClickstreamSuccess, data.gtmOnFailure, 'ClickstreamAnalytics-web'); + + +___WEB_PERMISSIONS___ + +[ + { + "instance": { + "key": { + "publicId": "logging", + "versionId": "1" + }, + "param": [ + { + "key": "environments", + "value": { + "type": 1, + "string": "all" + } + } + ] + }, + "clientAnnotations": { + "isEditedByUser": true + }, + "isRequired": true + }, + { + "instance": { + "key": { + "publicId": "access_globals", + "versionId": "1" + }, + "param": [ + { + "key": "keys", + "value": { + "type": 2, + "listItem": [ + { + "type": 3, + "mapKey": [ + { + "type": 1, + "string": "key" + }, + { + "type": 1, + "string": "read" + }, + { + "type": 1, + "string": "write" + }, + { + "type": 1, + "string": "execute" + } + ], + "mapValue": [ + { + "type": 1, + "string": "ClickstreamAnalytics" + }, + { + "type": 8, + "boolean": true + }, + { + "type": 8, + "boolean": true + }, + { + "type": 8, + "boolean": true + } + ] + }, + { + "type": 3, + "mapKey": [ + { + "type": 1, + "string": "key" + }, + { + "type": 1, + "string": "read" + }, + { + "type": 1, + "string": "write" + }, + { + "type": 1, + "string": "execute" + } + ], + "mapValue": [ + { + "type": 1, + "string": "ClickstreamAnalytics.init" + }, + { + "type": 8, + "boolean": true + }, + { + "type": 8, + "boolean": true + }, + { + "type": 8, + "boolean": true + } + ] + }, + { + "type": 3, + "mapKey": [ + { + "type": 1, + "string": "key" + }, + { + "type": 1, + "string": "read" + }, + { + "type": 1, + "string": "write" + }, + { + "type": 1, + "string": "execute" + } + ], + "mapValue": [ + { + "type": 1, + "string": "ClickstreamAnalytics.record" + }, + { + "type": 8, + "boolean": true + }, + { + "type": 8, + "boolean": true + }, + { + "type": 8, + "boolean": true + } + ] + }, + { + "type": 3, + "mapKey": [ + { + "type": 1, + "string": "key" + }, + { + "type": 1, + "string": "read" + }, + { + "type": 1, + "string": "write" + }, + { + "type": 1, + "string": "execute" + } + ], + "mapValue": [ + { + "type": 1, + "string": "ClickstreamAnalytics.setUserId" + }, + { + "type": 8, + "boolean": true + }, + { + "type": 8, + "boolean": true + }, + { + "type": 8, + "boolean": true + } + ] + }, + { + "type": 3, + "mapKey": [ + { + "type": 1, + "string": "key" + }, + { + "type": 1, + "string": "read" + }, + { + "type": 1, + "string": "write" + }, + { + "type": 1, + "string": "execute" + } + ], + "mapValue": [ + { + "type": 1, + "string": "ClickstreamAnalytics.setUserAttributes" + }, + { + "type": 8, + "boolean": true + }, + { + "type": 8, + "boolean": true + }, + { + "type": 8, + "boolean": true + } + ] + }, + { + "type": 3, + "mapKey": [ + { + "type": 1, + "string": "key" + }, + { + "type": 1, + "string": "read" + }, + { + "type": 1, + "string": "write" + }, + { + "type": 1, + "string": "execute" + } + ], + "mapValue": [ + { + "type": 1, + "string": "ClickstreamAnalytics.setGlobalAttributes" + }, + { + "type": 8, + "boolean": true + }, + { + "type": 8, + "boolean": true + }, + { + "type": 8, + "boolean": true + } + ] + } + ] + } + } + ] + }, + "clientAnnotations": { + "isEditedByUser": true + }, + "isRequired": true + }, + { + "instance": { + "key": { + "publicId": "inject_script", + "versionId": "1" + }, + "param": [ + { + "key": "urls", + "value": { + "type": 2, + "listItem": [ + { + "type": 1, + "string": "https://github.com/awslabs/*" + } + ] + } + } + ] + }, + "clientAnnotations": { + "isEditedByUser": true + }, + "isRequired": true + } +] + + +___TESTS___ + +scenarios: +- name: test init + code: |- + const mockData = { + // Mocked field values + }; + + // Call runCode to run the template's code. + runCode(mockData); + + // Verify that the tag finished successfully. + assertApi('gtmOnSuccess').wasCalled(); +- name: Quick Test + code: runCode(); +setup: '' + + +___NOTES___ + +Created on 2024/3/1 16:38:53 + + diff --git a/release.sh b/release.sh index c718c95..21a3ecb 100755 --- a/release.sh +++ b/release.sh @@ -6,3 +6,4 @@ regex="[0-9]\+\.[0-9]\+\.[0-9]\+" sed -i "s/\"version\": \"${regex}\"/\"version\": \"${version}\"/g" package.json sed -i "s/aws-clickstream-web-${regex}.tgz/aws-clickstream-web-${version}.tgz/g" README.md +sed -i "s#v${regex}/clickstream-web.min.js#v${version}/clickstream-web.min.js#g" gtm-template/ClickstreamAnalytics-gtm-template.tpl