Do not speak Spanish? Read this post in English.

Jueves, 26 d julio d 2012.

Google Analytics API V3 con Google API PHP Client y Service Account

Estos días he vivido una pequeña crisis interna. Resulta que las primeras versiones de la API de analytics "La Data Export API" han quedado obsoletas y por lo tanto todos los scripts que solía usar (que estaban basados en esa API) simplemente han dejado de funcionar.

¿Qué hacer? Lo suyo sería haber sido precavido, seguir los blogs de Google con cuidado y haber previsto esta caducidad, pero ahora el daño ya está hecho: tengo que actualizar la forma de sacar los datos de Analytics.

Google nos brinda distintas versiones para sus APIs pero la ultima de ellas ha significado un auténtico cambio en muchos conceptos. Ya no se trata simplemente de crear un script de conexión y sacar los datos, ahora hay que seguir un proceso bastante cerrado (algo que los amantes de la seguridad aplaudirán) para simplemente conectase a esa API.

Lo bueno es que Google en esta nueva versión a estandarizado muchas APIs y ya nos brinda para distintos lenguajes de programación una librería propia de conexión a sus APIs. Esto implica que a la que conseguimos conectarnos a una de sus APIs con sus librerías no solo hemos conseguido esta conexión, sino que el resto de servicios de Google nos van a quedar mucho más cerca para otras integraciones. Lo malo de todo esto es que la librería PHP es de las últimas que han salido y que la documentación actual se centra en conexiones mediante OAuth 2.0, algo que tiene mucho sentido para crear aplicaciones web pero poco para lo que solemos hacer en analítica, que es recoger por servidor los datos sin que medie usuario alguno en este proceso.

Dicho esto, ya veis de que va este post. El trabajo ya está hecho, ya puedo conectarme mediante la API V3 a analytics y por lo tanto solo me queda explicaros el proceso (aun un poco largo) a los que aun no hayáis pasado por este mal trago.

Vamos a conectarnos a analytics con PHP mediante las propias librerías de google...

Primer paso: Google APIs Console

Este nuevo sistema es necesario gestionarlo desde un entorno que Google ha puesto a nuestra disposición para gestionar nuestras conexiones a sus APIs. Se trata de un gran avance pues nos permite ver que estamos usando, nuestros códigos de acceso, bajarnos sus librerías y las cuotas de datos que estamos gastando (recordemos que tras cierto límite Google cobra por el acceso a sus datos, en analytics no será un problema pero en otros servicios si).

Configuración en la Google APIs Console

Una vez nos identificamos con nuestra cuenta de Google o la de la empresa pasamos a ver el menú de opciones de la Google APIs Console:

Clickando en el primer elemento podremos editar nuestro proyecto de APIs, un concepto que es algo asi como un contenedor de integraciones con un mismo proposito o de una misma empresa.

Una vez tenemos claro nuestro proyecto, que salvo que usemos un usuario de una agencia pocas veces será más de uno, podemos ir al panel de servicios y activar aquellos que deseemos utilizar. En este caso Google Analytics.

Este paso es importante, sin activar el servicio, no podremos conectarnos a la API V3.

Una vez lo tenemos activo, por fin es el momento de entrar en API Access y configurar nuestro acceso a las APIs (que recordemos que es común).

Aquí encontraremos 2 tipos de acceso: "Authorized" y "Simple". Nosotros vamos a usar el acceso Authorized que es el que usan las librerías de Google. El Simple es implemente una clave que añadir a las peticiones en otras versiones de la API y por lo tanto no nos interesa.

Clickaremos en crear un nuevo "Client ID" y nos dará varias opciones para conectarnos:

  • "Web Application" nos permite crear el típico acceso OAuth 2.0 estilo Facebook o Twitter con petición de permisos. Resulta ideal para crear aplicaciones web basadas en Analytics.
  • "Service Account" está creado para una conexión mediante servidor sin mediación de los usuarios
  • Por último "Installed Applications" está destinado a crear programas de escritorio donde el OAuth no puede ser exactamente igual al web

Por supuesto, la conexión que a nosotros nos interesará para importar datos de google analytics con php es la de "Service Account". Al seleccionarla se creará la nueva conexión pero también (por el funcionamiento de la misma) se nos ofrecerá un fichero llave a descargar. Este fichero es el que almacena nuestra identificación mediante este canal, por lo que es necesario bajárselo y guardarlo en un lugar seguro (donde nadie más tenga acceso y donde no podamos perderlo).

Una vez hecho esto, nuestra conexión esta lista. Ya disponemos de todos los datos para realizar el acceso con PHP mediante la API V3 de Analytics.

Dando acceso a esta nueva conexión a nuestra cuenta de Google Analytics

Sin embargo, no hemos terminado de configurar el acceso. La conexión está habilitada y podemos identificarnos en ella pero esta no va a tener acceso a las cuentas de analytics si no se lo damos.

Para ello, si miráis en la imagen superior veréis que la conexión nos ha creado un Email de identificación. Este email es el que va a realizar el acceso y por lo tanto tenemos que darle acceso a Analytics.

Para ello nada tan fácil como acceder a nuestra cuenta de Google Analytics, entrar en la administración y crear un nuevo usuario (normal, no es necesario que sea administrador) con ese Email.

Ahora sí, ya estamos listos para crear nuestro código.

Descargando la librería PHP

El código a utilizar lo encontraremos bien organizadito en el repositorio de Google Code:

Este nos brida la descarga de las librerías PHP para conectarnos a la API de Analytics (y a tantas otras) al tiempo que nos brinda una documentación bastante decente sobre como usarla.

El problema de todo esto es que tanto la descarga ofrecida como la documentación que ahí encontramos están centradas en la conexión mediante OAuth 2.0. Eso significa que no encontraremos soporte para la conexión con un "Service Account" y mediante archivo llave.

Peor aún: a día de hoy (26 de Julio de 2012) la descarga ofrecida en esta página no contiene las funciones necesarias para usar el archivo llave que nos hemos descargado. Es decir, hasta que no lo actualicen esta descarga no nos sirve pues no contiene las funciones que necesitamos.

Por lo tanto tenemos que decargarnos el proyecto mediante SVN (subversion), un protocolo que sirve para llevar un control de cambios en trabajos colaborativos y que necesita de herramientas especiales (como por ejemplo Tortoise SVN o Eclipse ) para realizar la descarga. Esto para un programador de PHP curtido no debería suponer ninguna complicación pero si puede ser problemático para programadores noveles o perfiles no tan técnicos que se asoman solo de vez en cuando a la programación.

La dirección del SVN para realizar la descarga es la siguiente:

http://google-api-php-client.googlecode.com/svn/trunk/

Realizamos el Checkout (descarga) del proyecto y ya disponemos de un código con soporte para ficheros clave y con las mismas funcionalidades que el resto del código de google (simplemente una versión un poco más actualizada).

¿Como comprobar si tu versión de google php api client es la buena?

Tenemos que abrir el archivo "auth/apiP12Signer.php"

Y encontrar en la clase la siguiente línea:

if (!openssl_sign($data, $signature, $this->privateKey, "sha256")) {
 

Conectándonos por PHP

Ya tenemos la consola configurada, nuestra conexión creada, el email de la conexión como usuario de analytics y la librería con soporte para ficheros llave. Ya solo nos queda conectarnos...

  • Nos ubicaremos en la carpeta que deseemos de nuestro servidor y copiaremos la carpeta de "google-api" dentro de esta.
  • Dentro de la carpeta "google-api" o donde deseemos (lo suyo sería un lugar no accesible desde internet) copairemos nuestro fichero llave. El que descargamos anteriormente de la consola
  • Ahora crearemos un fichero php con el código necesario para realizar la conexión...

Para ello simplemente os dejo una muestra del código a usar comentado que creo que será suficiente para la mayor parte de vosotros:


// Los includes de la librería google-api son relativos, por lo que si no programamos
// en la misma carpeta de la libería no funcionarían.
// Solución: Cambiarmos la carpeta a partir de la que se hacen los includes en php con chdir()
chdir('/var/www/mi-ruta-absoluta-hasta-la-carpeta-de-la-clase/class/google-api');

// incluimos la libería base y el módulo de Analytics
include('apiClient.php');
include('contrib/apiAnalyticsService.php');

// Declaramos nuestra configuración 
$googleApi = array(
	'id' => '803005xxxxxxxxxxxxxxxxx.apps.googleusercontent.com', // Id que nos ha dado la APIs Console
	'email' => '803005xxxxxxxxxxxxxxxxxx@developer.gserviceaccount.com', // email que nos ha dado la APIs Console
	'keyFile' => 'e6a8753xxxxxxxxxxxxxxxxxxx-privatekey.p12', // nombre del fichero llave
	'gaAccount' => 123456 // id de la cuenta de analytics a la que nos conectamos
); 

// Creamos el cliente de conexión
$client = new apiClient();
$client->setApplicationName('blog.ikhuerta.com-analytics-sample');
$client->setAssertionCredentials(
	new apiAssertionCredentials(
		$googleApi['email'],
		array('https://www.googleapis.com/auth/analytics.readonly'),
		file_get_contents($googleApi['keyFile'])
	)
);
$client->setClientId($googleApi['id']);
$client->setAccessType('offline_access');

// y con este cliente creamos el objeto para lanzar consultas a la API
$service = new apiAnalyticsService($client);

// ahora ya podemos realizar consultas de la forma acostumbrada
$results = $service->data_ga->get($googleApi['gaAccount'], '2012-01-01', '2012-02-01', 'ga:visits');

// imprimimos el resultado para verlo
var_dump($results);

Posibles problemas

Es posible que encuentres algunos errores en tu camino para conseguir esta conexión. Voy a enumerar los que cuentro más comunes:

  • Los includes internos de la librería no se realizan correctamente: esto es porque son relativos. Google espera que añadamos la carpeta de su librería a nuestros PATH en el "php.ini". Esto resolverá el problema sin duda, pero lo veo excesivo si no vamos a dedicar un servidor completo a este tipo de conexiones. Otra solución es la comentada en este propio código. Usar chdir() para cambiar la ruta desde la que se hacen los includes. Sin emabrgo esto puede dar también problemas si hacemos nuestros propios includes relativos
  • La llamada a a "openssl_sing" falla al autentificar el fichero llave: Este error lo podemos encontrar con un Warning con el texto "openssl_sign() expects parameter 4 to be long, string given". Este es un problema de la versión de PHP. Versiones por debajo de PHP5.3 no pueden trabajar la función openssl_sing() con "sha256" y por lo tanto fallan. Por desgracia Google Api no nos da solución ni hack para esto. Lo unico que podemos hacer para remediarlo es actualizar nuestro php a una versión php5.3 o superior.
  • Permiso denegado: Un error que podemos identificar al ver el siguiente mensaje en pantalla: "Error refreshing the OAuth2 token, message: '{ "error" : "invalid_grant" }'". Este error viene a decir lo que parece: que no tenemos acceso. No es un problema del código o de PHP sino de los permisos que estamos usando: revisemos que los ids indicados son correctos, que se corresponden con el archivo llave y que el email que estamos dando sea un usuario de la cuenta de analytics a la que intentamos acceder

Funcionamiento de la llamada get() en el objeto de analytics

La librería es bastante sencilla pero no existe mucha documentación sobre la misma... la verdad es que viendo el código fuente de "contrib/apiAnalyticsService.php" se ven las posibilidades de la mayor parte de funciones y el escalado de clases para la administración pero la función get no explica demasiado sobre que hay que lanzar.

Sencillo, disponemos de 4 variables obligatorias a completar con un posible array con más datos.

1) $ids: los ids de cuentas de analytics que consultamos (con "ga:" al principio).
2 y 3) $start_date y $end_date: rango de fechas de la cosnulta.
4) $metrics: metricas que queremos consultar.

El resto de parametros a pasar por array son las posibles variables que se nos informan en la propia documentación de la API de Google Analytics:

Así pues, cualquiera de estos parametros puede pasarse en el array opcional de valores. Un ejemplo: vamos a sacar las visitas y rebotes de las keywords y landings de nuestro site, pero solo contemplando el tráfico SEO:

// se supone que ya hemos creado el objeto $service de la forma anteriormente mencionada

$service->data_ga->get(
  $googleApi['gaAccount'], 
  '2012-01-01', 
  '2012-02-01', 
  'ga:visits,ga:bounces',
  array(
    'filter' => 'ga:medium==organic',
    'dimensions' => 'ga:keyword,ga:landingPagePath'
  )
);

Y como siempre, podemos sacar el listado de posibles métricas y dimensiones también de la documentación de la API de analytics:

El formato de los datos

El formato de vuelto no es el mismo que en pasadas versiones de la API. La verdad es que puede rompernos un poco los esquemas al hacer la migración pero la realidad es que el nuevo formato resulta mucho más útil y "trabajable" que el antiguo pues se centra en darte toda la información directamente como una tabla y añadirte campos con información sobre la misma. El paso de estas tablas a cualquier utilidad que quieras darle será más rápido que con el antiguo formato... por desgracia eso no se aplica tus viejos scripts que tendrán que reformularse para tratar los datos con el nuevo formato.

Conclusión

Como puedes ver, el proceso es mucho más largo y complejo que con las anteriores APIs pero creo que merece la pena el cambio (una vez lo has hecho). Tras todo este proceso tenemos ciertas ventajas que no hay que dejar de lado:

  • Estaremos mucho más cerca de trabajar con el resto de apis de Google
  • Disfrutaremos de un código mantenido y actualizado por Google
  • Estaremos muchísimo más lejos de versiones caducadas de la API
  • Disfrutaremos de un formato de los datos más manipulable
  • Podremos identificarnos en el código sin dar acceso a nuestra cuenta real de analytics (usuario y password)
  • Podremos revocar desde la consola cualquier acceso simplemente eliminando o cambiando su fichero clave
  • Podremos ver nuestras estadísticas de uso en la consola
  • Y seremos, una vez más, tiernos corderitos que hacemos las cosas solo como a Google le gusta

¿Qué? ¿os animáis?

Temas Relacionados: analitica web programacion tutoriales

Autor:

19 Comentarios para “Google Analytics API V3 con Google API PHP Client y Service Account”

  1. Muy buena la guía. Yo también he estado trasteando y usando la api de google para crear un search interno y en combinación con las seo tool para excel creé una columna con las urls de mi sitemap y en la columna contigua hice un "cache:" para cada una de esas urls. Con esto conseguí una lista de las urls de mi sitemap que están en la cache y cuales no. No siempre la cache indica que estén en el index pero es un dato bastante preciso y mejor que nada. Eso sí, sale a 5€ por 1000 request la api. El siguiente paso es automatizarlo con php y cronjob y crear un bonito frontend...

  2. Mario dice:

    Hola, muchísimas gracias por el artículo, me ayudó un montón y pude resolver mi problema, similar al tuyo.
    Te comento que a fecha de hoy, en la biblioteca en subversion han cambiado los nombres de todas las clases y métodos. (Básicamente donde se llamaba api, ahora es Google).

  3. ikhuerta dice:

    @andreas:

    Suena bien! como todo, posibilidades hay cientos, solo que al contrario de lo que muchos piensan no solo hace falta la idea sino tiempo o recursos para desarrollarla 😉 Por cierto, el tema de indexadas hace poco que sale ya en Webmaster Tools por si solo. Quizás te interese más unirte a esa API no?

    @mario:

    Pues vaya gracia Mario! Si empiezan a respetar tan poco la continuidad con sus clases no se muy bien de que nos sirve que estén evolucionando la librería...

    En fin gracias por el apunte y por tu comentario.

  4. Leandro dice:

    Muchas gracias por tan valiosa info...

    Gracias a ti he podido implementar lo que necesitaba.

    Solo quiero hacer unas aclaraciones para ayudar a otros.

    La versión que bajé del repositorio a través de Tortoise SVN ha cambiado los prefijos apiXXXX por Google_XXXX
    O sea que donde dice en tu ejemplo:

    include('apiClient.php');
    include('contrib/apiAnalyticsService.php');

    $client = new apiClient();
    new apiAssertionCredentials
    $service = new apiAnalyticsService($client);

    hay que reemplazarlo por:

    include './src/Google_Client.php';
    include './src/contrib/Google_AnalyticsService.php';

    $client = new Google_Client();
    new Google_AssertionCredentials
    $service = new Google_AnalyticsService($client);

    Otra cosa a tener en cuenta es que la versión 0.5 que había bajado antes sin el repositorio SVN tenía esta linea
    if (!openssl_sign($data, $signature, $this->privateKey, "sha256")) {

    Por lo cual pensé que serviría pero no fue así.

    La forma de darse cuenta si es una de las últimas versiones es si el archivo principal comienza con Google_

    Y un último detalle importante, es que para que funcione el openssl_sign es un requisito tener una versión de php 5.3 o superior.

    Teniendo esas cosas en cuenta y siguiendo los pasos de Iñaki se puede implementar sin problemas.

    Saludos,
    Leandro

  5. Ricardo dice:

    Hola, muy excelente informacion!!! y bueno al igual que a ti yo me he quedado barado, pues utilizaba una clase para conectarme a google analytics y bueno hace un par de dias ya no va... hice todo lo que dices , pero no me funciona (incluso ya cambie lo de api por Google_) y no va, al parecer si conecta pero al momento de hacer esto:

    $results = $service->data_ga->get($googleApi['gaAccount'], '2012-01-01', '2012-02-01', 'ga:visits');

    // imprimimos el resultado para verlo
    var_dump($results);

    ya no muestra nada, por cierto la id es la que va con este formato UA-XXXXXX-#?

    te agradecere mucho si puedes ayudarme!! de antemano muchas gracias

    atte.
    Ricardo

    • ikhuerta dice:

      justo el el id es donde creo que tienes el problema. Ahi tienes que indicar el id de perfil no el de cuenta. El de perfil es un numero sin letras, podras encontrarlo entrando a ver tus informes de analytics y entrando en admin. ahi deberias poder ver tu id de perfil.

  6. Jukian dice:

    Buen día, gracias por el post si que me saco de dudas al implementar la nueva API, todo me funcionó menos que toco improvisar ya que el hosting es php 5.2 y toco buscar una funcion de reemplazo que funcionó bien, lo que no he podido es que mi app hace 3 peticiones al instante y ahi mismo me sale error 403 error refreshing the OAuth2 token, message: User Rate Limit Exceeded.

    Como puedo evitar este error, cacheando el access token?

    • ikhuerta dice:

      Ese error sale porque han bajado el numero de peticiones por segundo que pueden hacerse. Ahora solo te deja 1 por segundo. Como pone en el post puedes pedirles que vuelvan a subirtelo a 10 como antes. Otra forma es usar la funcion sleep() de php entre peticiones haciendo que php espere lo suficiente entre peticiones para que no se produzca el error. Eso si, olvidate del tiempo real si trabajas asi pues las consultas se haran muy lentas.

  7. @analisisweb dice:

    Hola, si te digo la verdad este articulo esta siendo mi salvación, aunque estoy teniendo un atasco importante...
    a ver si puedes darme alguna pista.. en mi caso estoy intentando hacer una aplicación web, lo que implica ( creo) que el asunto del acceso cambia un poco respecto a como tú lo tienes detallado. Pero bueno, ese no es el problema, el problema viene cuando hago la consulta:
    $results = $service->data_ga->get($profileID, '2012-09-01', '2012-09-17', 'ga:visits');
    Donde $profileID es el numero de perfil ( los números, sin letras)
    resulta que no me devuelve nada... que estoy haciendo peor que mal??

    muchas gracias por anticipado..

    • ikhuerta dice:

      buenas... a ver, con esa info no puedo saber exactamente lo que te pasa. solo darte ideas de donde mirar...

      Primero me extraña tu descripción de id de perfil: no es que sea el numero de cuenta sin el UA delante sino que ese numero y el perfil son cosas distintas. Para entendernos. Cuando entras en analytics primero te ofrece una lista de cuentas (esas son las que tienen id con letras) pero dentro de estas tienes que escoger un perfil (por defecto cada cuenta tiene solo un perfil pero puede haber mas de 1 por cuenta). Lo que la API de analytics quiere es el id de perfil, no el de cuenta. Para mirarlo debes ir a ese perfil y desde ahi al administrador. En la pestaña de configuracion del perfil veras el id (pero solo si eres admin de esa cuenta)

      Otras opciones son que no tengas permiso para conectarte. Revisa tis credenciales y que el email que se conecta tenga acceso a analytics.

      Sea como sea, la clase de google deberia mostrarte un error en forma de excepcion de php. Ese error te indicara exactamente que punto es el que no cuadra....

      No se, si no es nada de eso dame mas datos pues con la info que pasas es dificil decir más.

  8. @analisisweb dice:

    gracias, tienes razón, la información que te doy es mas bien escasa, pero no quería dejarte una comentario muy largo...
    te cuento el proceso,
    1.- autorizo la entrada
    2.- saco una lista de perfiles para seleccionar
    3.- una vez seleccionado paso el id de perfil( managementprifiles-> getID)
    4 hago la consulta tal como has visto en el comentario... y devuelve nada.
    he probado a cambiar fechas y demás, pero nada...
    si quieres verlo lo tengo en http://dashboardanalytics.es
    ya me diras... creo que hare un post contando el proceso de ayuda...
    😉
    Gracias!

  9. @analisisweb dice:

    Hola de nuevo Iñaki,
    te comunico que acabo de solucionar el asunto... el problema era QUE SOY UN PUTO MELÓN...
    verás, todo estaba bien, excepto el $IDperfil, yo pasaba el numerito ( que estaba correcto) y lo que hay que pasar es un string de esta forma 'ga:'.$IDperfil. ha sido poner el 'ga' y funcionar...
    gracias de todas formas, todo el artículo ha sido una salvación para mi...
    gracias!

  10. Jordi dice:

    Hola, teneis el código actualizado para la version 0.6 del client?

  11. ikhuerta dice:

    Buenas Jordi,

    No, aun no lo he necesitado. En los comentarios sin aparecen algunos cambios que ha hecho la gente en su implementación para adaptarse. Fundalmentalmente cambiar "api" por "google" en las llamadas.

    No te va con esos cambios?

  12. Daniel Alberto Bernal Martinez dice:

    Viejo se gano el cielo, que su dios lo recompense con placeres mundanos. no sabe cuanto me ayudo.

  13. tengo un problemilla con Analytics, resulta que me da datos de todas las visitas y su procedencia, extrangero, capitales de provincia incluso poblaciones pequeñas como Cullera, Mollet o Cataroja en cambio hay una excepcion en la provincia de Tarragona, solo da datos como Tarragona capital, no desglosa por poblaciones, cuando yo se positivamente que recibo visitas y no pocas desde Salou, Cambrils, Reus o Tortosa.
    Quizas en otras provincias pase lo mismo pero la que me afecta es la de Tarragona pues quiero vender espacios publicitarios en mi web y creo necesario poder demostrar a mis clientes cual seria su posible clientela.
    Podrian indicarme, como solucionar el tema??, de quien depende esta informacion??

    Gracias por adelantado

    • ikhuerta dice:

      La localización la saca la propia herramienta de herramientas GEOIP. A partir de la IP se estima una procedencia. En algunas regiones como USA esta estamación es realmente sorprendente sin embargo en zonas como por ejemplo españa deja mucho que desear.

      Yo personalmente en el caso de españa no me fio de la localización por un nivel inferior a país, te la juegas demasiado.

  14. Stal dice:

    hola estoy implementando la consulta
    $results = $service->data_ga->get($googleApi['gaAccount'], '2013-12-01', '2014-01-01', 'ga:visits');

    pero no funciona yo pienso que es debido a que poseo varias WebPropertyId (propiedades) dentro de la misma cuenta. Alguien a realizado consultas de este tipo?

Anímate y deja tu comentario