Plantillas personalizadas en GTM: un ejemplo

A finales de mayo, Google introdujo una nueva función en el Administrador de etiquetas de Google (GTM): plantillas personalizadas o plantillas personalizadas. Veamos por qué es necesario, cómo usarlo, cuáles son las diferencias con las etiquetas HTML y las variables de JavaScript.

Como ejemplo, considere crear una Plantilla personalizada para un píxel de retargeting dinámico VKontakte y personalizar aún más las etiquetas GTM a través de él.



Palabras simples sobre plantillas personalizadas
Crear una plantilla personalizada
• pestaña Información
• pestaña Campos
• pestaña Código
• pestaña Permisos
Personalización y prueba de la etiqueta en la plantilla personalizada creada
• Página vista
• AddToCart
• Prueba de minería
Conclusión

Palabras simples sobre plantillas personalizadas


Las plantillas personalizadas son plantillas mediante las cuales los usuarios pueden crear nuevas etiquetas o variables. GTM tiene plantillas listas para usar (en la sección Destacado o Recomendado), por ejemplo, la etiqueta de Google Analytics, Google Optimize y otras. Ahora podemos complementarlos con nuestras plantillas. Una vez creados, aparecerán en la pestaña Personalizado:



La diferencia clave de las etiquetas HTML y las variables JS es que cuando un usuario crea una etiqueta o variable de acuerdo con una plantilla preparada, no interactúa con el código JS.

El código de la plantilla de usuario está escrito por el desarrollador o analista web en la etapa de su creación. Luego, al crear una etiqueta o variable de acuerdo con una plantilla de usuario, toda la interacción se lleva a cabo a través de la interfaz (que también se configura al crear una plantilla de usuario):



En consecuencia, en comparación con escribir una etiqueta HTML o una variable JS, personalizar una etiqueta o variable de acuerdo con una plantilla de usuario se vuelve un orden de magnitud más fácil, ya que esto no requiere conocimientos y habilidades para trabajar con JavaScript.

Otra gran ventaja de las plantillas personalizadas es que la probabilidad de "poner" un sitio se reduce en un orden de magnitud debido a un error en el código JS de la etiqueta.

En nuestro ejemplo, para configurar la etiqueta de retargeting dinámico "VKontakte", ya no necesita ponerse en contacto con los desarrolladores: todo se puede configurar de forma independiente, incluso la transferencia de datos sobre productos (cuando el comercio electrónico avanzado de Google está configurado en el sitio), teniendo solo experiencia con GTM.

Crear una plantilla personalizada


Como estamos creando una plantilla de etiqueta, debemos ir a la sección Plantillas y hacer clic en el botón Nuevo en la sección Plantillas de etiqueta.



Después de eso, se abre el Editor de plantillas:



En el lado izquierdo del editor está la ventana de configuración, en el lado derecho está la ventana de vista previa y la consola. Hay cuatro pestañas en la ventana de configuración que son necesarias para crear y trabajar con la plantilla.

Pestaña Información


La información de la etiqueta se completa en esta pestaña: nombre, descripción, icono. Esta es la información que veremos al crear una nueva etiqueta en la lista de plantillas:



Hay requisitos para el icono de etiqueta: formato PNG, JPEG o GIF, una resolución de al menos 64x64 píxeles y un tamaño de no más de 50 KB.

Pestaña Campos


Esta sección crea la interfaz de nuestra plantilla. La interfaz consta de varios campos y formularios con los que el usuario interactúa en la etapa de creación de una nueva etiqueta o variable.

En el futuro, la información que ingresó el usuario al crear la etiqueta usando la interfaz se usa en el código de la plantilla.

Para agregar un nuevo elemento, haga clic en el botón Agregar campo. Aparece la ventana para seleccionar el tipo de elemento:



GTM le permite seleccionar los siguientes tipos de elementos de interfaz:

  • cuadro de texto
  • menú desplegable
  • casilla de verificación ;
  • interruptores
  • tabla simple , aquí puede editar cada celda.
  • tabla extendida , solo puede editar una fila, este tipo de tabla es conveniente para crear un diccionario a partir de pares clave-valor;
  • grupo de elementos , le permite agrupar varios tipos en un grupo;
  • el acceso directo se usa para agregar texto a la interfaz; no requiere que el usuario ingrese ningún dato.

Después de agregar un elemento, debe darle un nombre descriptivo, que luego se utilizará en el código. Este es un tipo de nombre de variable: debe ser comprensible y revelar la esencia del elemento de interfaz creado. Por ejemplo, el nombre "ID" no significa nada específico, pero el nombre "pixelIDs" ya muestra que las ID de píxeles ingresadas por el usuario se almacenan en este elemento:



A continuación, vaya a la configuración de cada elemento y active las propiedades necesarias.
En diferentes situaciones, se requieren diferentes propiedades del elemento de interfaz, por lo que de forma predeterminada están todas ocultas y necesitamos activar las que se necesitan ahora:



Para diferentes tipos de elementos, las propiedades disponibles difieren, indicaré los más utilizados, que son casi todos los elementos:

1. Nombre para mostrar . Este es el nombre que el usuario verá en la interfaz al crear la etiqueta:



2. Valor de ejemplo . Esta es una pista para el usuario sobre qué valores ingresar en el campo:



3. Texto de ayuda . Este es el texto que el usuario verá si pasa el cursor sobre el ícono de ayuda del elemento:



4. Reglas para la verificación de datos . En esta propiedad, puede establecer ciertas reglas para verificar los datos ingresados ​​por el usuario en el campo y, si es necesario, el texto de error que aparece cuando intenta guardar una etiqueta con datos que no pasaron la prueba.

Por ejemplo, puede especificar que el campo se debe completar. El segundo ejemplo: necesita obtener una dirección de correo electrónico del usuario, luego puede verificar que los datos ingresados ​​por el usuario deben coincidir con la expresión regular . * @. * \ .. * .



Para especificar el texto de error que aparece si los datos ingresados ​​no cumplen con las reglas de verificación, debe activar la configuración avanzada de reglas:





Además, en la configuración avanzada, puede especificar las condiciones bajo las cuales se activa esta regla (el campo Habilitar condición).

5. Términos de inclusión . Estas son las condiciones bajo las cuales el usuario tendrá este elemento de interfaz.

Por ejemplo, para no sobrecargar la plantilla con elementos de interfaz, puede hacer aparecer los elementos necesarios cuando la casilla de verificación está seleccionada. Es decir, suponga que si un usuario desea configurar la transferencia de datos del producto en un píxel (esto es posible con el sitio avanzado de comercio electrónico de Google configurado en el sitio), luego selecciona la casilla de verificación "Usar dataLayer para transferir datos del producto", y después de marcar la casilla, aparecen elementos en la interfaz de la etiqueta requerido para configurar dicha transferencia. Si la casilla no está marcada, no hay elementos en la interfaz.



Observo que aquí es necesario indicar el nombre del elemento, que tuvo que asignarse inmediatamente después de agregarlo.

A medida que agrega configuraciones y crea una interfaz, todos los cambios se pueden ver y probar de inmediato en la ventana de vista previa:



Pestaña Código


Esta pestaña es un editor de código.

El código de las plantillas personalizadas de GTM está escrito en JavaScript ES6 simplificado y se ejecuta en un entorno aislado donde toda la comunicación con datos globales (es decir, directamente con la página) se realiza a través de la API. No hay objetos globales, como ventanas o documentos, en él, respectivamente, los métodos habituales también. Por ejemplo, constructores (nuevo objeto y similares), setTimeout, parseInt, delete, etc. - Todo esto no funcionará en la plantilla personalizada.

Pero hay una API para todo esto. Y, por lo tanto, escribir código para la Plantilla personalizada debe comenzar con el hecho de que definimos las API que utilizaremos en nuestro código:

// API //     const copyFromWindow = require('copyFromWindow'); //     const setInWindow = require('setInWindow'); //      const injectScript = require('injectScript'); //    const callInWindow = require('callInWindow'); //  ,     ,    const makeTableMap = require('makeTableMap'); //   URL  const getUrl = require('getUrl'); //    const getQueryParameters = require('getQueryParameters'); //     const makeInteger = require('makeInteger'); //    const makeString = require('makeString'); //  setTimeout const callLater = require('callLater'); //  console.log const logToConsole = require('logToConsole'); 

Consulte la Ayuda del desarrollador de Google para obtener una lista completa de las API con documentación detallada.

Te mostraré ejemplos de cómo trabajar con la API:
Descripción de la acciónJs clásicoAPI de plantilla personalizada
Salida de la consolaconsole.log ('Hola');logToConsole ('Hola');
Establecer temporizadorsetTimeout (función, 100);callLater (función);
Convertir a cadenaCadena (1234);makeString (1234);
Conversión a enteroparseInt ('1234', 10);makeInteger ('1234');
Anfitrión de la páginawindow.location.hostnamegetUrl ('host');

Como puede ver en la tabla de ejemplo, después de definir la API, debe usarla en lugar de las construcciones JS estándar.

Después de haber definido la API, es conveniente definir un objeto con la configuración que ingresó el usuario. Esto también se puede hacer después, por ejemplo, durante el código ejecutable, solicitando los datos necesarios de la configuración del usuario. Pero si definimos el objeto de configuración desde el principio, entonces trabajar con el código se vuelve más fácil y más comprensible, ya que todas las configuraciones del usuario se almacenan en un objeto separado.

Para obtener datos de un elemento de interfaz, debe usar la construcción de datos.

{{nombre del elemento}}:

 //    const settings = { //  event: data.event, //ID  () pixelIDs: data.pixelIDs, //ID - (  1 -) priceListId: data.priceListId, //   -? fewPriceLists: data.fewPriceLists, //ID - (    ) priceListIds: data.priceListIds === undefined ? data.priceListIds : makeTableMap(data.priceListIds,'hostname','priceListId'), //  ecommerce   ? ecommerceUse: data.ecommerceUse, // ecommerce   eventEcommerce: data.eventEcommerce, //     siteSearchQueryParam: data.siteSearchQueryParam }; 

Nota: si pasa indefinido al método makeTableMap, causará un error de script, por lo que utilizo una construcción con un operador ternario (construcción abreviada if-else) para filtrar dichos scripts.

Sobre el método makeTableMap.
Si la interfaz utiliza una tabla extendida, los datos que contiene se almacenan de esta forma:

 [ 'key': 'k1', 'value': 'v1'}, 'key': 'k2', 'value': 'v2'} ] 

Después de procesar con el método makeTableMap, los datos se convierten en un objeto regular con pares clave-valor:

 { 'k1': 'v1', 'k2': 'v2' } 


Otro requisito para el código de plantilla personalizada: si la etiqueta se ejecuta con éxito, debe llamar al método data.gtmOnSuccess () y, en caso de error, llame al método data.gtmOnFailure ().

Por ejemplo, en mi código, se llama al método data.gtmOnSuccess () después de que la solicitud se haya enviado correctamente, y se llama al método data.gtmOnFailure () si la descarga falla en la página del script externo VK openapi.js.

Después de definir la API y definir el objeto con la configuración, puede comenzar a escribir un algoritmo para calcular el píxel.

Lo principal para recordar aquí es:

• Si necesita obtener una variable global, use el método de la API copyFromWindow.

 copyFromWindow('VK'); //VK -   ,     

• Si necesita establecer una variable global, utilizamos el método de API setInWindow.

 setInWindow('openapiInject', 1); //openapiInject -   ,    //1 - ,    . 

• Si necesita ejecutar una función global, usamos el método de API callInWindow.

 callInWindow('VK.Retargeting.Init', p); //VK.Retargeting.Init -   ,    //p - ,      

• Si necesita agregar un script externo a la página, use el método API injectScript.

 injectScript('https://vk.com/js/api/openapi.js?159', pixel.setVkAsyncInit(), data.gtmOnFailure, 'vkPixel'); //https://vk.com/js/api/openapi.js?159 -  ,      //pixel.setVkAsyncInit() - ,        //data.gtmOnFailure - ,        //vkPixel -  ,  ,   URL  .    ,   JavaScript       

• Si necesita obtener la URL (o parte de ella), use el método getUrl API.

 getUrl('host'); //host -  URL,  .  ,  host: protocol, port, path, extension, fragment, query. 

Como escribí anteriormente, la plantilla personalizada admite JS ES6. Es recomendable utilizar esta sintaxis, ya que acorta el código y lo hace más legible, y el trabajo de JS es más predecible y similar a otros lenguajes de programación.

Más información sobre la sintaxis de JS ES6
Lo principal que es deseable usar son las funciones de flecha y las declaraciones de variables const y let en lugar de var.

Una variable declarada a través de const es una constante cuyo valor no se puede cambiar.

Una variable declarada a través de let difiere de una variable declarada a través de var de la siguiente manera:

  • let no se agrega al objeto de ventana global;
  • la visibilidad se limita al bloque de declaración;
  • Las variables declaradas a través de let no se pueden volver a declarar.

Las funciones de flecha son una abreviatura de las funciones habituales:

 //1.   const func1 = function() { return 'test'; } //    const func1 = () => 'test'; //2.   const func2 = function(arg) { if (arg > 0) return 'plus'; else return 'minus'; } //    const func2 = arg => { if (arg > 0) return 'plus'; else return 'minus'; } //3.   const func3 = function(arg1, arg2){ if (arg1 > arg2) return arg1; else return arg2; } //    const func3 = (arg1, arg2) => { if (arg1 > arg2) return arg1; else return arg2; } 


Ahora que entendemos cómo usar la API de plantilla personalizada, podemos escribir el código de operación de la etiqueta usando la sintaxis de JavaScript ES6.

Mi código contiene métodos para iniciar un píxel, instalar VK openapi.js, recuperar datos de productos de dataLayer (con el sitio de comercio electrónico avanzado de Google configurado), procesar estos datos para llevarlos al formulario necesario para enviarlos al píxel de retargeting de VKontakte y el método de envío de eventos.

El método de activación de píxeles admite tres escenarios:

  1. El píxel se ejecuta en una página donde falta openapi.js.
  2. El píxel se ejecuta en la página donde hay openapi.js, pero aún no se ha cargado.
  3. El píxel se inicia en la página con openapi.js cargado.

El código completo de mi plantilla GTM personalizada para el píxel de retargeting dinámico VKontakte
 //api const copyFromWindow = require('copyFromWindow'); const setInWindow = require('setInWindow'); const injectScript = require('injectScript'); const callInWindow = require('callInWindow'); const makeTableMap = require('makeTableMap'); const getUrl = require('getUrl'); const getQueryParameters = require('getQueryParameters'); const makeInteger = require('makeInteger'); const makeString = require('makeString'); const callLater = require('callLater'); //    const settings = { event: data.event, pixelIDs: data.pixelIDs, priceListId: data.priceListId, fewPriceLists: data.fewPriceLists, priceListIds: data.priceListIds === undefined ? data.priceListIds : makeTableMap(data.priceListIds,'hostname','priceListId'), ecommerceUse: data.ecommerceUse, eventEcommerce: data.eventEcommerce, siteSearchQueryParam: data.siteSearchQueryParam }; //       const pixel = { //    getPageHostname: () => getUrl('host'), //    VK getVK: () => copyFromWindow('VK'), //    VK setVkAsyncInit: () => { setInWindow('vkAsyncInit', pixel.sendEvent); }, //       getSiteSearchPhrase: () => { if (settings.event === 'view_search') return getQueryParameters(settings.siteSearchQueryParam); else return undefined; }, //      getEventParams: (products, currencyCode, revenue) => { let eventParamsClean= {}; let eventParams = { products: eventProducts.getProductParams(products), category_ids: eventProducts.getCategoryString(products), currency_code: currencyCode, total_price: eventProducts.getTotalPrice(products, revenue), search_string: pixel.getSiteSearchPhrase() }; if (eventParams.products !== undefined) eventParamsClean.products = eventParams.products; if (eventParams.category_ids !== undefined) eventParamsClean.category_ids = eventParams.category_ids; if (eventParams.currency_code !== undefined) eventParamsClean.currency_code = eventParams.currency_code; if (eventParams.total_price !== undefined) eventParamsClean.total_price = eventParams.total_price; if (eventParams.search_string !== undefined) eventParamsClean.search_string = eventParams.search_string; return eventParamsClean; }, //  - getPriceListId: hostname => { if (settings.fewPriceLists) return settings.priceListIds[hostname]; else return settings.priceListId; }, //  openapi.js openapiInit: () => { injectScript('https://vk.com/js/api/openapi.js?159', pixel.setVkAsyncInit(), data.gtmOnFailure, 'vkPixel'); setInWindow('openapiInject', 1); }, //   sendEvent: () => { if (settings.event === 'hit') { settings.pixelIDs.split(',').forEach(p => { callInWindow('VK.Retargeting.Init',p); callInWindow('VK.Retargeting.Hit'); }); } else { const pricelist = pixel.getPriceListId(pixel.getPageHostname()); const name = settings.event; let products = []; if(settings.ecommerceUse) products = name === 'view_home' || name === 'view_category' || name === 'view_search' || name === 'view_other' ? settings.eventEcommerce : settings.eventEcommerce.products; else products = undefined; const currencyCode = settings.ecommerceUse ? settings.eventEcommerce.currencyCode : undefined; const revenue = (settings.ecommerceUse && name === 'purchase') ? settings.eventEcommerce.actionField.revenue : undefined; const eventParams = settings.ecommerceUse ? pixel.getEventParams(products, currencyCode, revenue) : undefined; settings.pixelIDs.split(',').forEach(p => { callInWindow('VK.Retargeting.Init',p); callInWindow('VK.Retargeting.ProductEvent', pricelist, name, eventParams); }); }, //   start: () => { if (pixel.getVK() === undefined && copyFromWindow('openapiInject') !== 1) { pixel.openapiInit(); data.gtmOnSuccess(); } else if (pixel.getVK() === undefined && copyFromWindow('openapiInject') === 1) { if (pixel.count < 50) { callLater(pixel.start); pixel.count++; } else return; } else { pixel.sendEvent(); data.gtmOnSuccess(); }, //   count: 0 }; //       const eventProducts = { //    products   getProductParams: products => { let arr = []; products.forEach(i => { let productParamsClean = {}; let productParams = { id: makeString(i.id), group_id: makeString(i.brand), price: makeInteger(i.price * 100) / 100 }; if (productParams.id !== 'undefined') productParamsClean.id = productParams.id; if (productParams.group_id !== 'undefined') productParamsClean.group_id = productParams.group_id; if (productParams.price !== 0) productParamsClean.price = productParams.price; arr.push(productParamsClean); }); return arr; }, //       'a,b,c'       getCategoryString: products => { let categoryId = ''; let check = []; products.forEach(i => { if(check.indexOf(i.category) === -1) { check.push(i.category); categoryId += ',' + i.category; }); return categoryId.slice(1); }, //     getTotalPrice: (products, revenue) => { let sumPrice = 0; if (revenue !== undefined ) return makeInteger(revenue * 100) / 100; else { products.forEach(i => { if (i.hasOwnProperty('quantity')) sumPrice += (makeInteger(i.price * 100) / 100) * makeInteger(i.quantity); else sumPrice += makeInteger(i.price * 100) / 100; }); return sumPrice; }; //  pixel.start(); 


Pestaña de permisos


Después de escribir el código de etiqueta, queda la etapa final: emitir permisos para interactuar con los datos globales de la página. Esto se hace solo en la pestaña Permisos.

Dado que el código se ejecuta en un entorno aislado y la interacción con los datos globales se produce a través de la API, para cada método de la API (cuando sea necesario) debemos especificar manualmente los permisos para ciertas acciones.

Esto se hace para enfocar el trabajo con los datos de la página global de la manera más cuidadosa posible y, por lo tanto, minimizar las posibilidades de "poner" el sitio en un error en el código de nuestra plantilla.

Para los métodos API utilizados en mi código, se deben emitir tres tipos de permisos:



1. Accede a las variables globales : lee, escribe, ejecuta el acceso a las variables globales que se utilizan en nuestro código. Las variables deben agregarse manualmente y para cada una de ellas indicar lo que permitimos hacer.



Por ejemplo, la variable VK solo se puede leer, vkAsyncInit se puede leer y redefinir, y el método VK.Retargeting.Hit solo se puede ejecutar.

2. Lee la URL . Aquí debe especificar qué partes de la URL pueden recibir. Permito que se reciba cualquier parte de la URL:



Pero si lo desea, puede especificar cualquier específico:



3. Inyecta scripts . Aquí es necesario registrar las direcciones desde las cuales puede descargar scripts externos. En mi código, solo se carga un script con VK openapi.js, especifico su dirección:



Eso es todo, la configuración de la plantilla personalizada está completa, puede guardar la plantilla y proceder a la prueba.

Personalización y prueba de la etiqueta en la plantilla personalizada creada


Como ejemplo, crearemos dos etiquetas de retargeting dinámico “VKontakte” utilizando la Plantilla personalizada creada: pageview y addToCart.

Vista de página


Entraremos en el contenedor GTM necesario, crearemos una nueva etiqueta, seleccionaremos el tipo de etiqueta VK Pixel en la sección Personalizada:



Completamos el nombre de la etiqueta, seleccionamos el evento que se va a rastrear, seleccionamos Hit (esta es una vista de página estándar), en el campo "ID de píxel", indica la ID de dos píxeles a los que se enviarán los datos, separados por una coma y configuramos el disparador de Todas las páginas:



Guarda la etiqueta creada.

AddToCart


Crear una etiqueta para un evento y agregar un producto al carrito será un poco más complicado que una etiqueta Hit.

Primero, debe transferir los productos que se agregan a la cesta. Como escribí anteriormente, esto es posible con el comercio electrónico avanzado de Google configurado en el sitio. En este caso, los datos del producto se toman de dataLayer.

Para hacer esto, necesitamos crear la variable dataLayer en GTM, que almacenará el objeto de comercio electrónico para el evento addToCart. La configuración variable se ve así:



En segundo lugar, debe crear un activador que active la etiqueta cuando ocurra el evento addToCart de comercio electrónico (el activador activará la etiqueta al presionar el DataLayer con el evento addToCart):



Después de crear una variable con un objeto de comercio electrónico y un activador, puede comenzar a crear la etiqueta:



En orden:

  1. Como evento rastreado, seleccione Agregar al carrito.
  2. Completamos la ID separada por comas de dos píxeles a los que se deben transferir los datos.
  3. Establezca la casilla de verificación "Usar múltiples listas de precios": para Moscú y San Petersburgo, en nuestro ejemplo, es necesario usar diferentes listas de precios.
  4. Complete la tabla con las listas de precios.
  5. Establezca la casilla de verificación "Usar comercio electrónico para transferir productos y parámetros".
  6. En el objeto de comercio electrónico de este evento, especifique la variable creada anteriormente.
  7. Configuramos el disparador para el evento monitoreado, en este caso: AddToCart.
  8. Guardar.

Prueba de minería


Para verificar el funcionamiento de los píxeles del retargeting dinámico en VKontakte, debe activar el modo Vista previa en GTM, vaya a nuestro sitio web y abra la sección Red en la consola del navegador e ingrese 'rtrg' en el campo Filtro:


Después de eso, actualizamos la página y deberíamos tener dos solicitudes: el evento Hit enviado en dos píxeles:



El estado 200 significa que el servidor envía y recibe solicitudes con éxito.

También en la ventana Vista previa de GTM, vemos que nuestra etiqueta creada funcionó correctamente para el evento Vista de página.

Para verificar el evento Agregar al carrito, agregue el producto al carrito y en la consola tenemos dos solicitudes más:



En la ventana Vista previa de GTM, vemos que la segunda etiqueta funcionó correctamente. Los datos del producto de dataLayer se extrajeron y procesaron correctamente, también se sustituyó la lista de precios correcta.

Para el segundo host, la lista de precios también se sustituye correctamente:



Las etiquetas para otros eventos se configuran y verifican de la misma manera.

Conclusión


Las plantillas personalizadas están cambiando el paradigma familiar de usar GTM. Todos están acostumbrados a las etiquetas HTML y las variables JS, pero ahora hay una gran alternativa.

Es suficiente crear una plantilla personalizada de alta calidad una vez, y luego cualquiera que esté familiarizado con GTM puede usarla.

Dada la capacidad de compartir las plantillas creadas, creo que deberían ganar popularidad entre los usuarios.

Puede descargar la plantilla de píxel de retargeting dinámico personalizado de VKontakte, que examinamos en este artículo.

Para importar una plantilla, debe crear una nueva plantilla personalizada y seleccionar Importar en el menú:



Material preparado por mí para ppc.world

Source: https://habr.com/ru/post/458788/


All Articles