Commit 4b2825ce authored by Pedro Eduardo Trujillo's avatar Pedro Eduardo Trujillo
Browse files

Remodela tracking de eventos, comienza migración

Elimina el tipo de eventos definidos hasta el momento, que ya no se
ajustan a los estándares actuales.

Refactoriza y simplifica el componente de Analytics para recibir eventos
listos para ser enviados hacia Google Tag Manager. En lugar de redefinir
estructuras complejas por tipos de eventos, espera recibir el contenido
a publicar como un objeto, aunque dejando abierta la posibilidad de
modificar algo por si fuera necesario hacer adaptaciones futuras de
manera genérica. Además, soporta múltiples eventos pendientes en cola,
para ser enviados si el usuario acepta el uso de cookies.

Implementa envío de evento para cambio de capa base del mapa siguiendo
el nuevo método de GTM, a modo de prueba para seguir recuperando el
resto (entre los que sigan resultando de interés).
parent f1cfb872
Loading
Loading
Loading
Loading
+0 −5
Original line number Diff line number Diff line
@@ -248,11 +248,6 @@ define([
				return;
			}

			this._emitEvt('TRACK', {
				type: TRACK.type.page,
				info: route + locationQuery
			});

			this._emitEvt('MODULE_CHANGED', {
				route: route
			});
+44 −175
Original line number Diff line number Diff line
define([
	"dojo/_base/declare"
	, "dojo/_base/lang"
	, "src/component/base/_Module"
	'dojo/_base/declare'
	, 'dojo/_base/lang'
	, 'src/component/base/_Module'
], function(
	declare
	, lang
	, _Module
) {
	// Constantes para trakear acciones
	// TODO: sacar a un fichero externo (Necesita ser global)
	globalThis.TRACK = {
		'type': {
			'event': 'event',
			'page': 'pageview',
			'exception': 'exception'
		},
		'category': {
			'button': 'button',
			'check': 'checkBox',
			'layer': 'layer',
			'search': 'search'
		},
		'action': {
			'click': 'click',
			'dblClick': 'dblClick',
			'send': 'send'
		}
	};

	return declare(_Module, {
		//	summary:
		//		Módulo para trakear visualizaciones de páginas, eventos y otras acciones
		//	description:
		//		Escucha los canales de PageView... y envía a google analytics la información
		//		recibida además de otras posibilidades [ logs, alertas...].
		//		Módulo para hacer seguimiento de las acciones de los usuarios con el fin de extraer métricas.

		//	_cookiesAccepted: Boolean
		//		Flag que indica si se han aceptado las cookies.
		//	_pendingPageView: Object
		//		Guarda pageView pendiente para trakear cuando sea posible (cookies aceptadas)
		//	_pendingEventFired: Object
		//		Guarda eventFired pendiente para trakear cuando sea posible
		//	_pendingExceptionCaught: Object
		//		Guarda la excepción pendiente para trakear cuando sea posible
		//	_pendingEvents: Array
		//		Guarda eventos pendientes de envío (para cuando las cookies sean aceptadas)

		constructor: function(args) {

			this.config = {
				// own events
				events: {
					ACCEPT_COOKIES: "acceptCookies",
					COOKIES_STATE: "cookiesState"
					ACCEPT_COOKIES: 'acceptCookies',
					COOKIES_STATE: 'cookiesState'
				},
				// own actions
				actions: {
					ACCEPT_COOKIES: "acceptCookies",
					COOKIES_STATE: "cookiesState",
					COOKIES_ACCEPTED: "cookiesAccepted",
					PAGE_VIEW: "pageView",
					EVENT: "event",
					EXCEPTION: "event"
					ACCEPT_COOKIES: 'acceptCookies',
					COOKIES_STATE: 'cookiesState',
					COOKIES_ACCEPTED: 'cookiesAccepted'
				},
				// mediator params
				ownChannel: "analytics",
				ownChannel: 'analytics',
				_cookiesAccepted: false,
				_pendingPageView: null,
				_pendingEventFired: null,
				_pendingExceptionCaught: null
				_pendingEvents: []
			};

			lang.mixin(this, this.config, args);
@@ -74,11 +43,11 @@ define([
		_defineSubscriptions: function () {

			this.subscriptionsConfig.push({
				channel : this._buildChannel(this.credentialsChannel, this.actions.COOKIES_ACCEPTED),
				callback: "_subCookiesAccepted"
				channel : this._buildChannel(this.credentialsChannel, 'COOKIES_ACCEPTED'),
				callback: '_subCookiesAccepted'
			},{
				channel : this.getChannel("TRACK"),
				callback: "_subTrack"
				channel : this.getChannel('TRACK'),
				callback: '_subTrack'
			});
		},

@@ -86,170 +55,70 @@ define([

			this.publicationsConfig.push({
				event: 'ACCEPT_COOKIES',
				channel: this._buildChannel(this.credentialsChannel, this.actions.ACCEPT_COOKIES),
				callback: "_pubCookies"
				channel: this._buildChannel(this.credentialsChannel, 'ACCEPT_COOKIES')
			},{
				event: 'COOKIES_STATE',
				channel: this._buildChannel(this.credentialsChannel, this.actions.COOKIES_STATE),
				callback: "_pubCookies"
				channel: this._buildChannel(this.credentialsChannel, 'COOKIES_STATE')
			});
		},

		_subCookiesAccepted: function() {
			//	summary:
			//		Se ejecuta este callback cuando se recibe vía mediator
			//		que las cookies han sido aceptadas, por lo que se ejecutan
			//		los tracks pendientes
			//	tags:
			//		private

			this._cookiesAccepted = true;

			if (this._pendingPageView) {
				this._trackPageView(this._pendingPageView);
				delete this._pendingPageView;
			}

			if (this._pendingEventFired) {
				this._trackEventFired(this._pendingEventFired);
				delete this._pendingEventFired;
			}
			this._pendingEvents.forEach(lang.hitch(this, this._trackEvent));

			if (this._pendingExceptionCaught) {
				this._trackExceptionCaught(this._pendingExceptionCaught);
				delete this._pendingExceptionCaught;
			}
			this._pendingEvents = [];
		},

		_subTrack: function(/*Object*/ request) {
			//	summary:
			//		Se ejecuta este callback cuando se recibe vía mediator
			//		la petición de un track, dependiendo el tipo se envía a
			//		la función que lo procesará
			//	tags:
			//		private
		_subTrack: function(/*Object*/ req) {

			if (!this._cookiesAccepted) {
				this._pendingEvents.push(req);
				this._emitEvt('COOKIES_STATE');
				return;
			}

			if (request.type === TRACK.type.page) {
				this._pageView(request.info);
			}

			if (request.type === TRACK.type.event) {
				this._eventFired(request.info);
			}

			if (request.type === TRACK.type.exception) {
				this._exceptionCaught(request.info);
			}
		},

		_pageView: function(/*Object*/ pageInfo) {
			//	summary:
			//		Procesa la petición de trackear una página
			//	tags:
			//		private

			if (this._cookiesAccepted) {
				this._trackPageView(pageInfo);
			} else {
				this._pendingPageView = pageInfo;
			}
		},

		_eventFired: function(/*Object*/ eventInfo) {
			//	summary:
			//		Procesa la petición de trackear un evento
			//	tags:
			//		private

			if (!this._cookiesAccepted) {
				this._emitEvt('ACCEPT_COOKIES');
				this._pendingEventFired = eventInfo;
			} else {
				this._trackEventFired(eventInfo);
			}
			this._trackEvent(req);
		},

		_exceptionCaught: function(/*Object*/ exceptionInfo) {
		_trackEvent: function(/*Object*/ eventInfo) {
			//	summary:
			//		Procesa la petición de trackear una excepción
			//		Permite registrar un evento en Google Tag Manager.
			//	tags:
			//		private
			//	eventInfo:
			//		Objeto con la información del evento a registrar.

			if (this._cookiesAccepted) {
				this._trackExceptionCaught(exceptionInfo);
			} else {
				this._pendingExceptionCaught = exceptionInfo;
			if (!this._gtmIsAvailable()) {
				console.warn('Google Tag Manager was not available when tried to track event', event);
				return;
			}
		},

		_pubCookies: function(channel) {

			this._publish(channel);
			this._pushEvent(this._getFinalEvent(eventInfo));
		},

		_gtagIsAvailable: function() {
		_gtmIsAvailable: function() {

			return typeof gtag !== 'undefined';
			return typeof globalThis.dataLayer !== 'undefined';
		},

		_trackPageView: function(/*Object*/ pageInfo) {
		_pushEvent: function(/*Object*/ event) {
			//	summary:
			//		Permite trakear una página vista en google analytics
			//		Hace la publicación final del evento en Google Tag Manager.
			//	tags:
			//		private
			//	pageInfo:
			//		Puede ser un string con la url de la página o un objeto con más información
			//		pj. page, title, version...

			if (this._gtagIsAvailable()) {
				gtag('event', 'page_view', {
					page_path: '/' + pageInfo
				});
			}
		},

		_trackEventFired: function(/*Object*/ eventInfo) {
			//	summary:
			//		Permite trakear un evento en google analytics
			//	tags:
			//		private
			//	eventInfo.category:
			//		Categoría del evento. ej: Button
			//	eventInfo.action
			//		Acción del evento. ej: Click
			//	eventInfo.label
			//		Etiqueta de la categoría. ej: Botón de login
			//	eventInfo.value
			//		Valor del evento
			//	** label y value son opcionales

			if (this._gtagIsAvailable()) {
				gtag('event', eventInfo.action, {
					event_category: eventInfo.category,
					event_label: eventInfo.label,
					value: eventInfo.value
				});
			}
			globalThis.dataLayer.push(event);
		},

		_trackExceptionCaught: function(/*Object*/ exceptionInfo) {
		_getFinalEvent: function(/*Object*/ eventInfo) {
			//	summary:
			//		Permite trakear un evento en google analytics
			//		Permite transformar el objeto que define al evento antes de su envío a Google Tag Manager.
			//	tags:
			//		private
			//	exceptionInfo
			//		Objecto con información de la excepción. ej: exDescription, exFatal(boolen)...

			if (this._gtagIsAvailable()) {
				gtag('event', 'exception', {
					description: exceptionInfo.exDescription,
					fatal: !!exceptionInfo.exFatal
				});
			}
			return eventInfo;
		}
	});
});
+0 −9
Original line number Diff line number Diff line
@@ -349,15 +349,6 @@ define([
				return;
			}

			this._emitEvt('TRACK', {
				type: TRACK.type.event,
				info: {
					category: TRACK.category.layer,
					action: TRACK.action.click,
					label: 'Layer loaded: ' + atlasItem.name
				}
			});

			var atlasLayerItem = this._getAtlasLayerItemToInject(atlasItem);

			this._emitEvt('INJECT_ITEM', {
+0 −9
Original line number Diff line number Diff line
@@ -72,15 +72,6 @@ define([
		_showPlaceNames: function() {

			this._publish(this.placeNames.getChannel("SHOW"));

			this._emitEvt('TRACK', {
				type: TRACK.type.event,
				info: {
					category: TRACK.category.button,
					action: TRACK.action.click,
					label: "showPlaceNames"
				}
			});
		},

		_hidePlaceNames: function() {
+0 −9
Original line number Diff line number Diff line
@@ -113,15 +113,6 @@ define([
				return;
			}

			this._emitEvt('TRACK', {
				type: TRACK.type.event,
				info: {
					category: TRACK.category.layer,
					action: TRACK.action.click,
					label: this.layerId + " [lat:" + lat + ", lng:" + lng + "]"
				}
			});

			this._emitEvt('LAYER_QUERYING', {
				layerId: this.layerId
			});
Loading