Skip to content

Instantly share code, notes, and snippets.

@mbaersch
Last active August 29, 2024 21:34
Show Gist options
  • Save mbaersch/68424c513f6fc263dc944fb306053560 to your computer and use it in GitHub Desktop.
Save mbaersch/68424c513f6fc263dc944fb306053560 to your computer and use it in GitHub Desktop.
Tagless Request Proxy - Forward redacted GET request to any destination (Custom Client Template for server-side Google Tag Manager)

Tagless Request Proxy

Custom Client Template for server-side Google Tag Manager

Send incoming GET requests to custom endpoint and optionally change and add parameters. Does not need any tags but optionally creates an event and runs the container.

Usage

Create a new client template in ssGTM and import .tpl file. Add a destination URL for your desired endpoint. The client will forward all incoming requests to the defined endpoint path (default: /fwd).

Options

You can define a custom endpoint path for the client.

As a default, the client will forward all data (status, headers, body) from the destination in the client's response. If you do not want the sender to receive such details from the destination, activate the option to set a pixel response instead.

Additionally, you can decide if the client should create an event and run the container in order to trigger tags.

The event will have the event_name request_forwarded and contain keys for the destination_url including all parameters and a response_data key with info about status, headers and body from the destination response.

The client offers a table for adding additional paramaters or editing / redactong existing ones.

___TERMS_OF_SERVICE___
By creating or modifying this file you agree to Google Tag Manager's Community
Template Gallery Developer Terms of Service available at
https://developers.google.com/tag-manager/gallery-tos (or such other URL as
Google may provide), as modified from time to time.
___INFO___
{
"type": "CLIENT",
"id": "cvt_temp_public_id",
"version": 1,
"securityGroups": [],
"displayName": "Tagless Request Proxy",
"brand": {
"id": "brand_dummy",
"displayName": ""
},
"description": "send incoming GET requests to custom endpoint and optionally change and add parameters. Does not need any tags but optionally creates an event and runs the container.",
"containerContexts": [
"SERVER"
]
}
___TEMPLATE_PARAMETERS___
[
{
"type": "TEXT",
"name": "endpointUrl",
"displayName": "Destination Endpoint",
"simpleValueType": true,
"valueValidators": [
{
"type": "NON_EMPTY"
}
],
"help": "Enter URL to forward incoming request parameters to."
},
{
"type": "TEXT",
"name": "endpointPath",
"displayName": "Custom Client Path (optional)",
"simpleValueType": true,
"help": "Standard path for this client is \"/fwd\". You can enter a different path for activation here."
},
{
"type": "CHECKBOX",
"name": "setPixelResponse",
"checkboxText": "Return 1x1 Pixel",
"simpleValueType": true,
"help": "If checked, the response from the destination will be ignored and a pixel response will be sent instead. Otherwise the client will forward the destination`s response to the request source."
},
{
"type": "CHECKBOX",
"name": "genEvent",
"checkboxText": "Create Event Data",
"simpleValueType": true,
"defaultValue": true,
"help": "If activated, the client will create a \"request_forwarded\" event and adds keys for destinationUrl and response_data. You can check this option if any tags should run whenever a request gets forwarded (e. g. for logging purposes)."
},
{
"type": "GROUP",
"name": "grpEdit",
"displayName": "Edit Parameters",
"groupStyle": "NO_ZIPPY",
"subParams": [
{
"type": "PARAM_TABLE",
"name": "paramTable",
"displayName": "Edit, redact or add new parameters to outgoing request",
"paramTableColumns": [
{
"param": {
"type": "TEXT",
"name": "paramName",
"displayName": "Parameter Name",
"simpleValueType": true
},
"isUnique": true
},
{
"param": {
"type": "TEXT",
"name": "paramValue",
"displayName": "Parameter Value",
"simpleValueType": true
},
"isUnique": false
}
]
}
]
}
]
___SANDBOXED_JS_FOR_SERVER___
const claimRequest = require('claimRequest');
const returnResponse = require('returnResponse');
const sendHttpRequest = require('sendHttpRequest');
const setPixelResponse = require('setPixelResponse');
const getRequestHeader = require('getRequestHeader');
const getRequestPath = require('getRequestPath');
const getRequestQueryParameters = require("getRequestQueryParameters");
const setResponseBody = require("setResponseBody");
const runContainer = require("runContainer");
const Object = require("Object");
if (getRequestPath() === data.endpointPath||'/fwd') {
claimRequest();
let params = getRequestQueryParameters(),
serviceUrl = data.endpointUrl;
//change params or add new items
if (data.paramTable && data.paramTable.count > 0)
data.paramTable.forEach(x => {
params[x.paramName] = x.paramValue;
});
var paramStr = "";
for(var prm of Object.entries(params)) {
paramStr += paramStr === "" ? "" : "&";
paramStr += prm.key + "=" + prm.value;
}
const destUrl = serviceUrl + "?" + paramStr;
if (serviceUrl)
sendHttpRequest(
destUrl, (statusCode, headers, body) => {
if (data.setPixelResponse) setPixelResponse(); else setResponseBody(body);
if (data.genEvent) {
var event = { event_name: "request_forwarded",
destinationUrl: destUrl,
response_data: {
status: statusCode,
headers: headers,
body: body
}
};
runContainer(event, () => {
returnResponse();
});
} else
returnResponse();
},
{method: 'GET', timeout: 1000}
);
}
___SERVER_PERMISSIONS___
[
{
"instance": {
"key": {
"publicId": "read_request",
"versionId": "1"
},
"param": [
{
"key": "requestAccess",
"value": {
"type": 1,
"string": "any"
}
},
{
"key": "headerAccess",
"value": {
"type": 1,
"string": "any"
}
},
{
"key": "queryParameterAccess",
"value": {
"type": 1,
"string": "any"
}
}
]
},
"clientAnnotations": {
"isEditedByUser": true
},
"isRequired": true
},
{
"instance": {
"key": {
"publicId": "return_response",
"versionId": "1"
},
"param": []
},
"isRequired": true
},
{
"instance": {
"key": {
"publicId": "access_response",
"versionId": "1"
},
"param": [
{
"key": "writeResponseAccess",
"value": {
"type": 1,
"string": "any"
}
},
{
"key": "writeHeaderAccess",
"value": {
"type": 1,
"string": "specific"
}
}
]
},
"clientAnnotations": {
"isEditedByUser": true
},
"isRequired": true
},
{
"instance": {
"key": {
"publicId": "send_http",
"versionId": "1"
},
"param": [
{
"key": "allowedUrls",
"value": {
"type": 1,
"string": "any"
}
}
]
},
"clientAnnotations": {
"isEditedByUser": true
},
"isRequired": true
},
{
"instance": {
"key": {
"publicId": "run_container",
"versionId": "1"
},
"param": []
},
"isRequired": true
}
]
___TESTS___
scenarios: []
___NOTES___
Created on 29.8.2024, 23:21:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment