Do not speak Spanish? Read this post in English.

Jueves, 20 d junio d 2013.

Haz tus conversiones más ricas: Guarda tus campañas y landings de Google analytics en tu propia base de datos

Sin duda las dimensiones de campaña y las landings de Google Analytics son de la información más útil y recurrente que vamos a usar en la mayoría de nuestros análisis. Esto es porque estas dimensiones nos hablan no solo de lo que sucede en la página sino de lo que trajo al usuario a la misma. Ahí tenemos a todas las variables de campaña que, bien etiquetadas, nos indicarán exactamente que publicidad vio el usuario y, aún sin etiquetar, nos hablarán de URLs de referencia, buscadores, keywords, etc. Por otro lado la landing page nos informa de lo primero que vio el usuario y por lo tanto que página fue la que le atrajo y provocó o no el rebote.

Esta información es tan útil cuando trabajamos con webs con conversiones reales (formularios, procesos de compra, etc.) que nos resulta imprescindible encontrar una vía por la que poder dividir nuestras distintas conversiones por estos criterios. Para cualquier análisis que hagamos, por pequeño que sea, necesitaremos trabajar estas variables asociadas a nuestras conversiones. Sin embargo solemos tener una dificultad, muchas veces inesperada: Tenemos la información muy bien estructurada en analytics, pero con conversiones no exactas y poco nutridas en datos y por el otro lado usamos una base de datos perfecta para guardar estas conversiones pero que no almacena un solo dato sobre analítica web. Para colmo, cuando empezamos a sacar datos de un lado y de otro nos damos cuenta de lo evidente: no tenemos el mismo número de conversiones en Google Analytics que en nuestra base de datos.

Los datos de analitica web y los reales nunca cuadran

Lo primero que tenemos que saber es que esta situación es normal. En nuestro desarrollo web nosotros tenemos herramientas para controlar exactamente lo que sucede con la misma. Si un usuario rellena un formulario nosotros lo recogemos y lo guardamos en Base de datos. Salvo errores de programación esto es casi perfecto y por lo tanto nuestra base de datos se convierte en la fuente real de nuestro negocio.

En cambio, con herramientas de analítica web el proceso es más complejo e inestable y se añaden muchos factores que empeoran la calidad de la información:

  • Añadimos un javascript a nuestras páginas vistas: aquí está el primer problema. Para empezar tenemos que asegurarnos de que lo hemos añadido a todas las páginas de la web y que efectivamente exista una página vista para capturar cada dato. Luego tenemos todas esas páginas que un usuario llega a ver pero tan poco tiempo que no da tiempo a javascript a ejecutar analytics (y que suponen datos perdidos) y por ultimo errores de javascript, ya sean provocados por nosotros o por algún plugin que tenga el usuario instalado
  • Luego tenemos que añadir a esto el sistema de almacenamiento y consulta de datos de analytics. Ahí no todo es perfecto y algún dato se pierde al ser guardado. Pero no solo eso, sino que si nuestras consultas son de más de 250.000 visitas entraremos en muestreo de datos, un sistema por el cual, para ahorrar procesos, analytics decide no consultar todo el tráfico, sino solo un porcentaje y extrapolar nuestros resultados a partir de este. El muestreo realmente puede hacer mucho daño a nuestros análisis si no se controla, pero esta es otra historia

Al final lo que nos interesa es saber que no es nada raro si para un periodo nuestra base de datos dice que tenemos 2.365 conversiones y analytics tan solo guarda 2.280. Quizás alguien se lleve las manos a la cabeza, pero esto es lo que va a pasar en casi todos los casos. Y esto significa que si necesitamos hablar de conversiones exactas DEBEMOS usar siempre nuestra base de datos y no Analytics.

No se trata de no usar las conversiones de Analytics sino de que usemos estas para consultas sobre evolución, porcentajes de conversión, etc. (analítica web, vamos) y no tanto para llevar la contabilidad de nuestra empresa o los resultados finales de negocio.

Dicho esto ya vemos el problema que va a suponer realizar ciertos análisis para la mayor parte de las empresas: cuando necesito dar datos exactos, ¿cómo asigno las campañas a mis conversiones?

Métodos más usados para cruzar base de datos y analytics

Para poder cruzar bien nuestra base de datos, que seguramente es más rica en información que nuestro analytics, tenemos que hacer algo. Os voy a resumir varias técnicas posibles, aunque ya os adelanto que sólo la última será la que solucione el problema de los datos inexactos entre base de datos y analytics:

Por Objetivos + Extrapolando a mano

Una de las opciones más comunes es generar un objetivo para poder seguir las conversiones realizadas en la página. Estos objetivos como decíamos no serán exactos, pero luego podremos arreglar el dato extrapolando los resultados a los reales.

Imaginemos el siguiente caso (con numeros simplificados):

Analytics me dice que tengo 200 conversiones repartidas de la siguiente forma:

100 - organic
50 - referral
50 - direct

Pero se por mi propia base de datos que en realidad he conseguido 204 conversiones. Eso significa que deberé extrapolar mis datos de analytics y mis conversiones reales serían:

102 - organic
51 - referral
51 - direct

Sencillo, ¿verdad? Pues esto es todo lo que puedo hacer con este sistema. Mi problema vendrá cuando quiera cruzar datos de la conversión con las campañas pues no podré. Por ejemplo, imaginemos que uno de los datos que me indica el usuario en el formulario es su sexo. ¿Cómo puedo saber cuantas mujeres entraron por buscadores o directamente? Pues no puedo saberlo...

Con Ecommerce + API

Sin duda, los datos de eCommerce son mucho más ricos que los de los objetivos. Esto es básicamente porque los objetivos son solo métricas, marcadores numéricos sobre otras dimensiones de las que dispone el usuario. En cambio el eCommerce es un hit que nos permite incluir varias dimensiones y métricas nuevas. Esta información nueva es tan útil que muchas veces incluimos ecommerce en muchas webs que no son ecommerce. El ejemplo más común son los contactos realizados o los leads captados que en multitud de ocasiones capturamos en eCommerce como un producto ficticio que siempre vale 1€ y así podemos acceder a nuevos datos en nuestro analytics.

El ecommerce nos puede solucionar los problemas por dos vias: Por un lado nos aportará nuevas dimensiones por las que cruzar datos directamente en analytics como son la categoría y el nombre de producto pero más importante aun es la posibilidad de indicar el ID de Transacción al enviar los datos.

¿por qué es tan interesante este ID? Pues porque nos va a permitir sacar nuestras conversiones por ID fuera de analytics (vía API) con los datos que deseemos. Por ejemplo, podemos sacar un informe de ID's de conversión + información de campaña.

Si lo hemos hecho bien, seguramente este ID coincidirá con el ID de registro en nuestra base de datos, lo que significará que este ID de transacción será el puente para poder unir cualquiera de tus datos de analytics a tus conversiones.

Sin embargo, esto seguirá siendo inexacto. Veremos como al leer nuestros Id's de analytics nos encontraremos con esto:

analytics_transID

Que significa que estamos perdiendo algún ID en nuestro Ecommerce. Por alguno de los citados motivos, Analytics no está dándonos este ID, por lo que cuando lo encontremos en base de datos no podremos cruzarlo y deberemos volver a extrapolar una vez realizada nuestra unión de datos, tal cual lo hacíamos con los objetivos.

Añadiendo los datos de analytics a nuestra propia base de datos

Por último, la opción ganadora, será la que más trabajo nos de pero también la que más calidad de datos nos reporte. Se tratará de tomar el camino inverso: en lugar de intentar añadir los datos de base de datos a los de analytics, intentaremos que los datos de analytics sean capturados directamente en base de datos.

Para ello tenemos 2 opciones:

Hacerlo con programación en el servidor

Y replicando el trabajo que ya realiza analytics pero en las tripas de nuestro código. Así cuando un usuario llegue a una página nuestro servidor debería capturar en cookie o sesión datos como la variable utm_medium, la landing page, el referrer, etc... No solo eso, sino deberemos programar cómo sacar las keywords si el referrer es un buscador y cómo recoger los datos de cpc (especialmente de adwords, donde el autoetiquetado dejará de valernos).

Es un tema complejo que requiere trabajo y programadores que estén acostumbrados al uso de cookies y a capturar valores de la visita del usuario. Sin embargo la información que podemos capturar y asociar a nuestras conversiones de esta forma es realmente interesante y a la larga puede llegar a sernos muy útil.

El problema de este sistema es como decía que hay que programarlo todo a medida. Yo tengo mis clases creadas para ello, pero muchas son demasiado personales como para ponéroslas en el blog, quizás algún día os ponga algo medianamente automático creado con PHP o para WordPress pero de momento el código de este tipo que tengo es propietario (me lo encargaron hacer y por lo tanto no puedo ponerlo público) y no puedo haceros el trabajo.

Sin embargo no es extremadamente complejo, algunas funciones, algunos cientos de líneas y lo tenéis.

Hacerlo con javascript

Una solución mucho más fácil de implementar es realizar este añadido con javacript y aprovechando la propia información de analytics. La ventaja de hacerlo así es que nos podemos aprovechar de lo que ya captura Google Analytics para guardar exactamente el mismo valor que ellos recogen y no tener que averiguar por ingeniería inversa como conseguirlo en nuestro servidor.

Lo ideal es conseguir que ante cualquier formulario que pueda enviar el usuario, envíe, junto con los datos que el mismo ha rellenado, toda la información que nos interese de Google Analytics. Así a la hora de guardar los datos en base de datos nuestro servidor dispondrá de primera mano tanto de los datos del usuario como de los de analytics.

Por lo tanto, lo que os propongo es crear en todos los formularios de vuestra web campos ocultos que se autocompleten con esta información. Por ejemplo imaginemos un formulario extremadamente sencillo:

<form action="..." method="get">
<p><input name="email" type="email" value="" /></p>
<p><input type="submit" value="Enviar" /></p>
</form>

Deberíamos conseguir que en realidad tuviese los datos de campaña ocultos en el mismo:

<form action="..." method="get">
<p><input name="email" type="email" value="" /></p>
<p><input type="submit" value="Enviar" /></p>
<input type="hidden" name="ga[medium]" value="organic" />
<input type="hidden" name="ga[source]" value="google" />
<input type="hidden" name="ga[campaignName]" value="(not set)" />
<input type="hidden" name="ga[term]" value="seo on page" />
<input type="hidden" name="ga[content]" value="(not set)" />
<input type="hidden" name="ga[landing]" value="/" />
</form>

Esto lo solucionaría todo, ¿verdad?

Bien, os voy a mostrar un código javascript ya hecho, que conseguirá en 3 sencillos pasos que podáis provocar este mismo efecto y así guardar las campañas y la landing page de analytics a vuestras bases de datos directamente:

Paso 1: El código

Lo primero es añadir el código a todas vuestras páginas. No es un código especialmente ligero pero si os molesta siempre podéis crear un archivo aparte con el mismo y llamarlo como script separado. Como Analytics espera a que todos los scripts se carguen antes de ejecutarse, no supondrá un problema hacerlo de esta forma.

// Add Campaign & Landing Data To All Forms
// By Iñaki Huerta : http://blog.ikhuerta.com/haz-tus-conversiones-mas-ricas-guarda-tus-campanas-y-landings-de-analytics-en-tu-propia-base-de-datos
var gaLanding;
if ( gaLanding =  document.cookie.match( /_gal=([^;]+)(;.+)?$/ ) ) gaLanding = gaLanding[1];
else { gaLanding = location.pathname; document.cookie = '_gal='+location.pathname+';path=/'; }
gaCampData = {
  data : false,
  getData : function () {  
    this.data = {  source : '(not set)', campaign : '(not set)', medium : '(not set)', term : '(not set)', content : '(not set)', gc : '' , landing : '(not set)'};
    if (document.cookie.length>0)
    {
      var cs=document.cookie.indexOf('__utmz=');
      if (cs!=-1)
      {
        cs=cs + 8;
        var ce=document.cookie.indexOf(";",cs);
        if (ce==-1) ce=document.cookie.length;
        this.data.gc = unescape(document.cookie.substring(cs,ce));
        var z = this.data.gc.split('.'); 
        if(z.length >= 4)
        {
          var y = z[4].split('|');
          for(i=0; i<y.length; i++)
          {
            if(y[i].indexOf('utmcsr=') >= 0) this.data.source = y[i].substring(y[i].indexOf('=')+1);
            if(y[i].indexOf('utmccn=') >= 0) this.data.campaign = y[i].substring(y[i].indexOf('=')+1);
            if(y[i].indexOf('utmcmd=') >= 0) this.data.medium = y[i].substring(y[i].indexOf('=')+1);
            if(y[i].indexOf('utmctr=') >= 0) this.data.term = y[i].substring(y[i].indexOf('=')+1);
            if(y[i].indexOf('utmcct=') >= 0) this.data.content = y[i].substring(y[i].indexOf('=')+1);
          }
          this.data.landing = gaLanding;
        }
      }
    }
  },
  get : function ( campVar source, medium, campaign, term, content ) {
    if ( this.data == false ) this.getData();
    return (this.data[ campVar ]) ? this.data[ campVar ] : false;
  },
  addToAllForms : function (mediumId, sourceId, campaignId, termId, contentId, landingId) {
    if (typeof mediumId == 'undefined') mediumId = 'medium';
    if (typeof sourceId == 'undefined') sourceId = 'source';
    if (typeof campaignId == 'undefined') campaignId = 'campaignName';
    if (typeof termId == 'undefined') termId = 'term';
    if (typeof contentId == 'undefined') contentId = 'content';
    if (typeof landingId == 'undefined') landingId = 'landingPage';
    var forms = document.getElementsByTagName('form');
    for (var i=0;i<forms.length;i++)
    {
      var newHTML   = '<input type="hidden" id="'+mediumId+'" name="ga['+mediumId+']" value="'+this.get('medium')+'" />';
      newHTML   += '<input type="hidden" id="'+sourceId+'" name="ga['+sourceId+']" value="'+this.get('source')+'" />';
      newHTML   += '<input type="hidden" id="'+campaignId+'" name="ga['+campaignId+']" value="'+this.get('campaign')+'" />';
      newHTML   += '<input type="hidden" id="'+termId+'" name="ga['+termId+']" value="'+this.get('term')+'" />';
      newHTML   += '<input type="hidden" id="'+contentId+'" name="ga['+contentId+']" value="'+this.get('content')+'" />';
      newHTML   += '<input type="hidden" id="'+landingId+'" name="ga['+landingId+']" value="'+this.get('landing')+'" />';
      forms[i].innerHTML = forms[i].innerHTML + newHTML;
      // Use $_REQUEST['ga']['medium'] to get medium
    }
  }
}

Este código, simplemente prepara las funciones para poder realizar las acciones que queremos, nada más, así que tenemos que dar un par de pasos más...

Paso 2: Crear los campos de campaña y landing en todos los formularios tras la carga de analytics

El siguiente paso será ejecutar el código para que genere estos nuevos campos. Un aviso: Es extremadamente importante tener en cuenta cuando lo ejecutamos: Este código va a ir a buscar a las Cookies de Analytics la información de nuestras campañas por lo que es esencial que estas cookies hayan sido ya creadas. Por esto, debemos garantizar que lanzamos el código después de que analytics haya terminado de crear y manipular todos sus datos, es decir, tras el _trackPageview.

Así que deberemos transformar algo como esto:

var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-12345678-9']);
_gaq.push(['_trackPageview']);

En esto:

var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-12345678-9']);
_gaq.push(['_trackPageview']);
_gaq.push( function () { gaCampData.addToAllForms();  } );

Con esto provocaremos que tras ejecutarse analytics se añada a cualquier formulario la información sobre campaña y landing page del usuario. Yo os estoy mostrando como lanzar la función gaCampData.addToAllForms() por defecto, que generará los campos con sus nombres tal cual vienen dados. Los más dados a javascript en cambio verán fácilmente como manipular los nombres de estos campos e incluso como añadir sin demasiada complejidad algún campo nuevo que les pudiese interesar capturar en base de datos. El código es largo, pero no complejo.

Paso 3. Guardar en base de datos

Una vez tenemos en todos nuestros formularios los datos de campaña, solo nos queda recogerlos en el servidor y guardarlos en base de datos. Ni que decir, que habrá que cambiar las tablas de base de datos para crear los 6 nuevos campos a almacenar, pero aparte de eso y del propio guardado lo que hay que saber es como recuperar esos datos.

Los datos serán enviados como un "array" dentro de la variable "ga". Se respeta el método de envío del propio formulario, por lo que se usará POST o GET dependiendo de como estuviese codificado inicialmente el formulario.

Así pues, la formar de recoger los datos en cada lenguaje variará pero en PHP sería tan simple como esto:

$googleAnalyticsData = $_REQUEST['ga'];
// y para ver los datos antes de guardarlos
var_dump($googleAnalyticsData);

Esto nos provocará la impresión de todos nuestros datos de campaña y nuestra landing page para que veamos exactamnete que variables usar en el código de guardado.

Así que tan solo tendremos que alterar nuestro INSERT en base de datos y añadir cada uno de estos datos.

Conclusión

Poder disfrutar de datos de analítica web asociados a nuestros datos reales de negocio y no extrapolados es un autentico lujo. Una vez tengamos estos datos podremos sacar muchos informes sobre nuestras conversiones incluso prescindiendo de Google Analytics y de su API. Estos informes serán más ricos y más realistas que los que podríamos sacar tan solo con Analytics.

Sin embargo, dar estos pasos nos va a suponer cierto esfuerzo. Incluso con el método con javascript el guardado no será automático por lo que hay que trabajar un poco antes de obtener un resultado. Esto no estará al alcance de todo el mundo (no todo el mundo sabe programar, ni alterar su guardado en base de datos) pero es una posibilidad que hay que contemplar.

Por otro lado, hay que tener en cuenta para qué queremos los datos y qué tipo de información realmente requerimos de ellos. Extrapolar a bajo nivel no es pecado, solo es más confuso para algunas personas. Sobretodo con conversiones pequeñas tener que decirle a un cliente que "10,33" de sus conversiones provienen de SEO (porque al extrapolar nos han salido decimales) es algo complicado, pero no es algo que nos vaya a impedir trabajar.

Realmente los datos que perdemos de nuestras conversiones no son tantos, las conclusiones van a ser las mismas con o sin ellos, simplemente os animo a poder redondear las cifras y a sacar información de forma más directa y clara: directamente de vuestras bases de datos.

Temas Relacionados: analitica web

Autor:

Anímate y deja tu comentario

Esto son experimentos, no preguntes ;) prueba metadescription Prueba title