Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial

Utilizzare Google Analytics API con .NET in C#

Gestire i dati di traffico dei nostri siti con applicazioni client o sul Web, grazie alle API di Google
Gestire i dati di traffico dei nostri siti con applicazioni client o sul Web, grazie alle API di Google
Link copiato negli appunti

Google Analytics è un servizio di analisi di dati che consente di ottenere informazioni dettagliate sul traffico del proprio sito web e sull'efficacia delle campagne di marketing Google AdSense e Google AdWords.

In questo articolo vedremo come usare le API di Google Analytics per realizzare applicazioni client (o Web) che interrogano i dati raccolti ed elaborati da Google Analytics.

Per iniziare vediamo come attivare un account e monitorare un sito Web. Chi possiede già un account e un profilo su Google Analytics, può leggere direttamente la parte successiva sulla Google Analytics Data Export API

Account su Google Analytics

Per poter usare Google Analytics bisogna creare (gratuitamente) un Account Analytics. Dopo la creazione dell'account vedremo come creare dei profili e associarli ai siti web che vogliamo monitorare. Vedremo che, per consentire ad Analytics di registrare le informazioni, è sufficiente inserire un codice JavaScript nelle pagine web da monitorare.

Creare l'account Google è molto semplice, come si vede nella Guida Google Analytics, dopo averlo creato, possiamo accedere all'interfaccia amministrativa fornendo le nostre credenziali.

Infine potremo controllare il traffico dei siti e analizzare i dati tramite i report proposti dall'interfaccia stessa o graziie a report personalizzati.

Figura 1. Report - la dashboard
(clic per ingrandire)


Report - la dashboard

Creare un profilo

La prima cosa da fare per monitorare un sito (o una pagina) è associarlo un profilo di Analytics. Un utente può avere uno o più profili.

Figura 2. Amministrazione dei profili
(clic per ingrandire)


Amministrazione dei profili

In figura vediamo che l'utente simonmor@tiscali.it, possessore dell'account simonemoretti75, ha un solo profilo relativo al sito www.mariomoretti.it. Se clicchiamo sul link "Visualizza rapporto" ci viene proposto il report (Figura 1) che evidenzia l'andamento delle visite del sito nell'ultimo mese. Nel menu di sinistra troviamo altri report che riportano dati relativi ai visitatori, ai referer del sito e molto altro ancora.

Includere il codice JavaScript nelle pagine Web

Il codice Javascript da inserire nelle pagine web ci viene fornito dall'amministrazione nel momento in cui creiamo un nuovo profilo. Se clicchiamo su Aggiungi nuovo profilo, appare una nuova pagina in cui inserire l'indirizzo del nuovo sito da monitorare. Fatto questo, accediamo ad una pagina che riepiloga le caratteristiche del nuovo profilo e fornisce il codice JavaScript da inserire nelle pagine web del nostro sito subito prima del tag di chiusura </head> (figura 5).

Figura 3. Codice JavaScript del profilo
(clic per ingrandire)


Codice JavaScript del profilo

Ulteriori approfondimenti su Google Analytics si possono trovare sulla guida.

Le Google Data API

Le Google Data API (abbreviate in GData API) costituiscono un framework molto versatile che ci consente di accedere e gestire i dati messi a disposizione dai vari servizi Google.

Queste librerie hanno in comune un protocollo di comunicazione chiamato Google Data Protocol, basato su standard come HTTP, REST, AtomPub, JSON, che possiamo sfruttare per interfacciare un client o una applicazione Web ai servizi remoti.

Figura 4. Google Data API
(clic per ingrandire)


Google Data API

A questo scopo sono dispobili anche alcune librerie client per diverse piattaforme (Java, JavaScript, .NET, PHP, Python). Queste librerie introducono un livello di astrazione che ci consente di non dover lavorare a basso livello sul protocollo HTTP ma di interagire con oggetti che rappresentano i dati trasmessi (feed, entry, account utente, profili, etc.).

In questo articolo utilizzeremo solo le Google Analytics Data Export API che servono ad interfacciarsi con i dati web monitorati da Google Analytics, i più curiosi e intraprendenti possono consultare l'elenco completo delle API.

Google Analytics Data Export API

Con le Google Analytics Data Export API (in breve GA Export API) si possono implementare applicazioni client (o Web) per richiedere dati da un profilo di un utente possessore di un account Analytics. Attualmente questa API ci permette di accedere ai dati in sola lettura.

I dati Analytics si possono raggruppare in due categorie principali:

  • dati dell'utente: account e profilo
  • dati del sito web: reportistica sul traffico del sito

Per poter prelevare e maneggiare i nostri dati di Google Analytics è necessario eseguire una sequenza di quattro passi:

1. Autenticazione

Fase in cui noi, o gli utenti della nostra applicazione, ci facciamo riconoscere da Google con le credenziali di accesso. Esistono tre meccanismi di autenticazione: ClientLogin, AuthSub e OAuth. Li esamineremo in dettaglio in seguito.

2. Autorizzazione

Ogni account può avere più profili Analytics, generalmente un profilo per ogni sito monitorato. Dopo aver autenticato l'utente dobbiamo, quindi, determinare quali sono i profili sui quali operare. I profili hanno un identificativo numerico che li individua univocamente. Se già conosciamo l'id questo passo risulta superfluo, altrimenti dobbiamo consentire all'utente di scegliere uno dei propri profili.

3. Eseguire la query sul profilo

Una volta autenticato l'utente ed individuato l'identificativo del profilo di nostro interesse possiamo interrogare il sistema.

4. Decodificare il risultato della query

Google ci restituirà il risultato della query in una risposta HTTP sotto forma di data feed. Per default il formato usato da Google è Atom ma possiamo impostare anche altri formati standard come RSS o JSON.

Possiamo decodificare il risultato sia a basso livello, maneggiando direttamente la risposta HTTP, sia ad alto livello usando le librerie client fornite da Google (per .NET usiamo GData .NET Client Library). Negli esempi che faremo percorreremo entrambe le strade.

GData .NET Client Library

La GData .NET Client Library è una libreria .NET rilasciata dal Google Data team, grazia alla quale interagire ad alto livello con i servizi remoti GData. Possiamo scaricare l'ultima versione della libreria dalla home page del sito.

Procediamo con l'installazione della libreria lanciando il file Google Data API Setup(1.6.x.x).msiche abbiamo scaricato. L'installazione copia in una cartella le DLL associate alle GData API supportate.

Una volta installate le DLL possiamo cominciare a sfruttarle nelle nostre applicazioni (anche Client). Tutto ciò che dobbiamo fare è referenziare nelle applicazioni web le dll che ci servono. Nei nostri esempi avremo bisogno di tre dll:

Libreria Descrizione
Google.GData.Client dll con gli oggetti e le funzionalità di base della GData API
Google.GData.Extensions dll con gli oggetti e le funzionalità specifiche della GA Export API
Google.GData.Analytics dll con estensioni alle funzionalità base della GData API

dovremo poi includere nei sorgenti i relativi namespace:

using Google.GData.Client;
using Google.GData.Extensions;
using Google.GData.Analytics;

Autenticazione ClientLogin

Quando un utente richiede dei dati ad Analytics, deve essere riconosciuto da Google attraverso le credenziali di accesso: la coppia email-password dell'account Google. Le Google Analytics Data Export API supportano tre meccanismi di autenticazione, ClientLogin, AuthSub e OAuth, che andiamo a vedere nel dettaglio.

Il metodo ClientLogin è il più semplice dei tre ma anche il meno sicuro. Consiste nel chiedere le credenziali di accesso da una maschera della applicazione client. Visto che con questo metodo è l'applicazione a maneggiare le credenziali di accesso è consigliabile usarlo solo se l'applicazione è di tipo desktop (non web) ed è usata dal proprietario del PC sulla quale risiede.

È assolutamente da evitare se l'applicazione è web e maneggia le credenziali di accesso di terze parti perché non sarebbe garantita la sicurezza dei dati degli utenti.

Se il servizio di autenticazione di Google non riconosce le credenziali di accesso risponde con un codice di errore HTTP 401 che indica l'insuccesso dell'autenticazione, se invece le credenziali sono valide ci viene restituito il codice HTTP 200 ed un token con il quale effettuare tutte le richieste HTTP successive. Sarà questo token a garantire che l'utente è già autenticato.

Vediamo, con un esempio, come effettuare il passaggio delle credenziali di accesso attraverso una richiesta HTTP e come decodificare il token restituito nella risposta HTTP del servizio di autenticazione:

// le credenziali di accesso inserite dall'utente
string postData = "Email=" + TxtEmail.Text + "&Passwd=" + TxtPassword.Text;
//altri parametri necessari, in source mettiamo il nome della applicazione
postData = postData + "&accountType=GOOGLE" + "&service=analytics" + "&source=SimoneMoretti-gdataSamples-1";
ASCIIEncoding encoding = new ASCIIEncoding();
byte[] data = encoding.GetBytes(postData);
// creiamo una richiesta http di tipo POST
HttpWebRequest myRequest = (HttpWebRequest)WebRequest.Create("https://www.google.com/accounts/ClientLogin");
myRequest.Method = "POST";
myRequest.ContentType = "application/x-www-form-urlencoded";
myRequest.ContentLength = data.Length;
Stream newStream = myRequest.GetRequestStream();
// spediamo la richiesta HTTP
newStream.Write(data, 0, data.Length);
newStream.Close();
// Intercettiamo la risposta
HttpWebResponse myResponse = (HttpWebResponse)myRequest.GetResponse();
Stream responseBody = myResponse.GetResponseStream();
Encoding encode = System.Text.Encoding.GetEncoding("utf-8");
StreamReader readStream = new StreamReader(responseBody, encode);
// Risposta in formato stringa
string response = readStream.ReadToEnd();
//preleviamo il token di autorizzazione
string[] auth = response.Split(new string[] { "Auth=" }, StringSplitOptions.None);
//mettiamo il token in sessione in modo da usarlo nelle richieste successive
Session["token"] = auth[1];

Per creare una richiesta HTTP utilizziamo la classe HttpWebRequest contenuta nel namespace System.Net. Le credenziali di accesso vanno spedite al servizio di autenticazione di Google che risponde alla URL:

https://www.google.com/accounts/ClientLogin

Oltre ad email e password vanno forniti altri parametri che riepiloghiamo nella seguente tabella:

Parametro Descrizione
accountType Il tipo di account per il quale richiedere l'autorizzazione. Al momento l'unico valore supportato da Google analytics è GOOGLE
Email L'indirizzo email dell'account Google dell'utente funge da username
Passwd La password dell'account Google
service Il nome del servizio Google da richiedere, nel nostro caso è analytics
source Una stringa che identifica la nostra applicazione client nella forma companyName-applicationName-versionID

La richiesta HTTP deve essere di tipo POST perché stiamo chiedendo al servizio la creazione di un token di autenticazione.

Per intercettare la risposta HTTP usiamo la classe HttpWebResponse contenuta nel NameSpace System.Net. Della risposta ci interessa il token di autenticazione il cui valore si trova dopo il parametro Auth.

Autenticazione attraverso la .NET Client Library

Vediamo ora come l'autenticazione risulta più semplice usando la GData .NET Client Library. Esaminiamo questo brano di codice:

// Configuriamo il servizio Google di autenticazione con il nome della app
asv = new AnalyticsService("SimoneMoretti-gdataSamples-1");
// Passiamo le credenziali di accesso al servizio.
asv.setUserCredentials(TxtEmail.Text, TxtPassword.Text);

Anzitutto configuriamo il servizio di autenticazione creando un'istanza della classe AnalyticsService del NameSpace Google.GData.Analytics. A differenza del metodo precedente dobbiamo indicare il solo nome della applicazione client che effettua la richiesta di autenticazione.

Lanciamo poi il metodo setUserCredentials, al quale passiamo i soli parametri di accesso. Siamo riusciti a fare in due sole righe di codice quello che con il metodo precedente abbiamo ottenuto con 18 righe e, cosa ancor più interessante, è la libreria ad occuparsi della gestione del token di autenticazione, in modo a noi del tutto invisibile. Più avanti approfondiremo meglio l'uso della GData .NET Client Library.

Autenticazione AuthSub

Questo metodo è particolarmente adatto ad applicazioni Web e alle applicazioni desktop che gestiscono account Google di terzi. In questo caso non è l'applicazione a gestire le credenziali di accesso, queste infatti vengono inserite su una pagina Web ospitata su un server Google, ciò a garanzia di maggior sicurezza.

Il procedimento di autenticazione è leggermente diverso dal metodo ClientLogin: quando l'utente effettua la richiesta di autenticazione gli viene restituito un token monouso che deve consumare in una seconda richiesta di autenticazione che restituisce un token multi-sessione. Quest'ultimo può essere utilizzato dall'utente per tutte le richieste successive.

Quindi rispetto al metodo ClientLogin le credenziali di accesso vengono fornite in un web form remoto e il token multisessione viene fornito solo alla seconda richiesta. Mettiamo in pratica il metodo passo dopo passo:

1. La prima richiesta

Esaminiamo la composizione dell'URL che utilizziamo per la prima richiesta, per farlo la scriviamo "spezzettata":

https://www.google.com/accounts/AuthSubRequest?
&next=http://localhost:1627/tradizionale.aspx
&scope=https://www.google.com/analytics/feeds/
&secure=0
&session=1

Questa URL sarà accessibile per mezzo di un link o di un pulsante, contiene i seguenti parametri:

Parametro Descrizione
next URL dove l'utente verrà redirezionato dopo aver fornito le credenziali di accesso. È la pagina della applicazione client che si occupa di richiedere il token multisessione
scope Indica che l'applicazione sta richiedendo il token multisessione per accedere a dati Analytics. Questo campo deve essere: https://www.google.com/analytics/feeds/
secure Valore booleano che indica se la transazione di autorizzazione deve rilasciare o meno un token sicuro. I token sicuri sono disponibili solo per le applicazioni registrate
session Valore booleano che impostato a uno indica che il token rilasciato deve essere usato per una seguente richiesta di token multisessione

Quando forniamo le credenziali di accesso il sistema ci redireziona verso la URL specificata nel parametro next ed appende un token monouso come parametro. Nella pagina di approdo dobbiamo intercettare il token monouso e fornirlo come parametro a questa URL:

https://www.google.com/accounts/AuthSubSessionToken

che ritorna il token multisessione. Vediamo un esempio:

string token = Request.QueryString["token"]; //token mono-uso
//effettuiamo una richiesta HTTP per il token multi-sessione
HttpWebRequest myRequest = (HttpWebRequest) WebRequest.Create("https://www.google.com/accounts/AuthSubSessionToken");
myRequest.Headers.Add("Authorization: AuthSub token=" + token);
HttpWebResponse myResponse = (HttpWebResponse)myRequest.GetResponse();
Stream responseBody = myResponse.GetResponseStream();
Encoding encode = System.Text.Encoding.GetEncoding("utf-8");
StreamReader readStream = new StreamReader(responseBody, encode);
//trasformiamo la risposta HTTP in stringa
string response = readStream.ReadToEnd();
//mettiamo in sessione il token multiuso
Session["token"] = response.Split('=')[1];

Utilizziamo una richiesta HTTP di tipo GET inserendo nella sezione Header il token monouso ottenuto al passo precedente. A questo punto riceviamo il token "multiuso" dalla risposta e lo immagaziniamo nel nostro oggetto Session.

È possibile usare il metodo AuthSub anche con le librerie client.

Autenticazione OAuth

OAuth è un metodo adatto sia per applicazioni desktop che web. Come AuthSub fornisce un token di autenticazione e esonera le applicazioni dal maneggiare le credenziali di accesso dell'utente. A differenza di AuthSub però è necessario registrare le applicazioni con un certificato di sicurezza. Non approfondiamo oltre questo metodo che però troviamo documentato in questo articolo.

Eseguire le query

Una volta passata l'autenticazione possiamo procedere alla richiesta dei dati. Dobbiamo solo ricordare di inserire il nostro token di autenticazione nella sezine header di tutte le richieste HTTP.

Come abbiamo detto in precedenza possiamo scegliere se richiedere i dati utente o i report sul traffico, per iniziare vediamo come ottenere le informazioni su account e profili.

Richiedere dati dell'utente

Per richiedere i dati relativi ad un account utente è necessario fare una richiesta HTTP di tipo GET alla URL:

https://www.google.com/analytics/feeds/accounts/default

Per mezzo del token multisessione il servizio remoto di Google che risponde a quest'indirizzo identifica l'utente che ha effettuato la richiesta e risponde restituendo un Account Feed in formato XML. Esaminiamolo:

Account Feed
Tag Descrizione
id è una URI univoca dalla forma: https://www.google.com/analytics/feeds/ accounts/simonmor@tiscali.it
title È la stringa "Account list for" seguita dal nome dell'utente autenticato
totalResults il numero totale di risultati per la query
startIndex l'indice di partenza per le entry, di default è uno
itemsPerPage il numero di elementi nella richiesta corrente, il valore massimo è mille
entry Ci possono essere uno o più oggetti entry formati dalle seguenti proprietà

Proprietà Descrizione
webPropertyId web property ID associata al profilo
accountName nome dell'account
accountId account ID associato al profilo (esempio: UA-30481-22)
profileId id numerico del profilo (esempio: UA-30481-22)
title nome del profilo che si vede anche nella interfaccia amministrativa
id una stringa che identifica univocamente l'oggetto entry. Esempio: https://www.google.com/analytics/ feeds/accounts/ga:1234
tableId identificativo che identifica univocamente il profilo

Ecco un Account Feed di esempio:

<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xmlns:dxp="http://schemas.google.com/analytics/2009"  xmlns:openSearch="http://a9.com/-/spec/opensearchrss/1.0/">
  <id>http://www.google.com/analytics/feeds/accounts/abc@prova.it</id>
  <updated>2010-06-29T02:05:01.413-07:00</updated>
  <title type="text">Profile list for abc@prova.it </title>
  <link rel="self" type="application/atom+xml"
          href="https://www.google.com/analytics/feeds/accounts/default" />
  <author>
    <name>Google Analytics</name>
  </author>
  <generator version="1.0">Google Analytics</generator>
  <openSearch:totalResults>2</openSearch:totalResults>
  <openSearch:startIndex>1</openSearch:startIndex>
  <openSearch:itemsPerPage>2</openSearch:itemsPerPage>
  <entry>
    <id>http://www.google.com/analytics/feeds/accounts/ga:174288</id>
    <updated>2010-06-29T02:05:01.413-07:00</updated>
    <title type="text">www.mariomoretti.it</title>
    <link rel="alternate" type="text/html"
                  href="http://www.google.com/analytics" />
    <dxp:property name="ga:accountId" value="86539" />
    <dxp:property name="ga:accountName" value="mariomoretti" />
    <dxp:property name="ga:profileId" value="174288" />
    <dxp:property name="ga:webPropertyId" value="UA-86539-1" />
    <dxp:property name="ga:currency" value="USD" />
    <dxp:property name="ga:timezone" value="Europe/Rome" />
    <dxp:tableId>ga:174288</dxp:tableId>
  </entry>
  <entry>
    <id>http://www.google.com/analytics/feeds/accounts/ga:331664</id>
    <updated>2010-05-28T17:28:02.857-07:00</updated>
    <title type="text">www.simonemoretti75.wordpress.com</title>
    <link rel="alternate" type="text/html"
                     href="http://www.google.com/analytics" />
    <dxp:property name="ga:accountId" value="86539" />
    <dxp:property name="ga:accountName" value="mariomoretti" />
    <dxp:property name="ga:profileId" value="331664" />
    <dxp:property name="ga:webPropertyId" value="UA-86539-3" />
    <dxp:property name="ga:currency" value="USD" />
    <dxp:property name="ga:timezone" value="America/Los_Angeles" />
    <dxp:tableId>ga:331664</dxp:tableId>
  </entry>
</feed>

In questo Account Feed possiamo trovare tutti gli elementi principali citati nella tabella precedente. La prima indicazione che troviamo è che si tratta di un file XML e la che il feed restituito è in formato Atom. Troviamo poi il valore della proprietà id e via via tutti gli altri elementi proposti in tabella.

Possiamo facilmente verificare che nell'account feed restituito, abbiamo un account utente avente identificativo 86539 e nome mariomoretti con due profili aventi identificativi 174288 e 331664. Il primo profilo fa riferimento al sito www.mariomoretti.it, il secondo profilo invece fa riferimento al sito www.simonemoretti75.wordpress.com. Notiamo come il primo sito sia impostato sulla zona temporale di Roma e come il secondo sulla zona temporale di Los Angeles.

Esaminiamo un esempio di codice che richiede i dati di un account:

//creiamo una richiesta http di tipo GET
HttpWebRequest myRequest = (HttpWebRequest)WebRequest.Create("https://www.google.com/analytics/feeds/accounts/default");
//mettiamo il token multisessione nell'header della richiesta
myRequest.Headers.Add("Authorization: GoogleLogin auth=" + token);
//inviamo la richiesta e intercettiamo la risposta
HttpWebResponse myResponse = (HttpWebResponse)myRequest.GetResponse();

Ricordiamoci che prima di effettuare la richiesta dell'account dobbiamo autenticarci come abbiamo già visto. Nella variabile token è contenuto il token multisessione che dobbiamo aggiungere nell'header della richiesta HTTP al fine di essere autenticati. La richiesta HTTP è identificata dall'oggetto myRequest di tipo HttpWebRequest. Per ricevere la risposta dal servizio remoto dobbiamo invocare il metodo GetResponse() dell'oggetto myRequest. Vedremo più avanti come decodificare il risultato della query.

Vediamo ora come si ottiene la stessa cosa con la GData .NET Client Library:

// Configuriamo il servizio Google di autenticazione con il nome della app
asv = new AnalyticsService("SimoneMoretti-gdataSamples-1");
// Passiamo le credenziali di accesso al servizio.
asv.setUserCredentials(TxtEmail.Text, TxtPassword.Text);
// Creiamo una query di tipo Account.
AccountQuery query = new AccountQuery();
// eseguiamo la query e mettiamo il risultato in un oggetto di tipo AccountFeed
AccountFeed accountFeed = asv.Query(query);

Confrontando i due approccim notiamo che usando la libreria lavoriamo con astrazioni di alto livello: si maneggiano richieste HTTP ma si lavora con oggetti tipici del mondo Google Analytics. Occorre solo creare un oggetto di tipo AccountQuery e passarlo al servizio di tipo AnalyticsService, al quale abbiamo precedentemente passato le credenziali di accesso. Questo rende del tutto invisibile l'esistenza di un token multisessione che viene maneggiato dietro le quinte dalla libreria.

Richiedere i dati di traffico del sito web

Per richiedere i dati relativi al traffico di un sito web è necessario fare una richiesta HTTP di tipo GET alla url:

https://www.google.com/analytics/feeds/data

A questa URL vanno aggiunti dei parametri che servono a costruire la query. Riportiamo nella seguente tabella i principali parametri di ingresso:

Campo Descrizione
ids Identifica il profilo utente
dimensions Uno o più parametri per la segmentazione della metrica (es: visite segmentate per browser dell'utente)
metrics Le statistiche aggregate sulle attività dell'utente (clic, visite, pagine viste, ecc. )
sort Per l'ordinamento dei risultati
start-date Data di inizio della query
end-date Data di fine della query
max-results Numero massimo di risultati restituiti
prettyprint Se impostato a true indica al servizio remoto di restituire la risposta XML in un formato leggibile per l'uomo

Mostriamo come richiedere le prime tre pagine più viste del sito associato al profilo 174288 nel mese di Marzo 2010:

https://www.google.com/analytics/feeds/data?
ids=ga:174288 
&dimensions=ga:pageTitle&
metrics=ga:pageviews
&sort=-ga:pageviews
&start-date=2010-03-01
&end-date=2010-03-31
&prettyprint=true
&max-results=3 

Per mezzo del token multisessione che agganciamo all'header della richiesta HTTP, il servizio remoto di Google che risponde a quest'indirizzo identifica l'utente che ha effettuato la richiesta e risponde restituendo un Data Feed in formato XML. Vediamo gli elementi principali da cui è composto un Data Feed:

Data Feed
Tag Descrizione
title la stringa "Google Analytics Data for Profile" seguita dall' ID del profilo
id la URL del data feed
totalResults il numero totale di risultati per la query
startIndex l'indice iniziale degli elementi entry, per default è 1
itemsPerPage il numero di elementi nella richiesta corrente, il massimo è 10000
startDate data iniziale della query
endDate data finale della query
dataSource informazioni sulla sorgente del dato
entry ci possono essere uno o più oggetti entry formati dalle seguenti proprietà:

Proprietà Descrizione
title la lista di dimensioni della query con i relativi valori
metric le statistiche aggregate sulle attività dell'utente (clic, visite, pagine viste, ecc. )
dimension parametro per la segmentazione della metrica (es: visite segmentate per browser dell'utente)

Per una migliore comprensione esaminiamo un estratto di un Data Feed relativo alla richiesta precedente:

<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"
xmlns:dxp="http://schemas.google.com/analytics/2009"
xmlns:openSearch="http://a9.com/-/spec/opensearchrss/1.0/">
  <id>http://www.google.com/analytics/feeds/data?ids=ga:174288&
      dimensions=ga:pageTitle&metrics=ga:pageviews&
      start-date=2010-03-01&end-date=2010-03-31
  </id>
  <updated>2010-03-31T16:59:59.999-07:00</updated>
  <title type="text">Google Analytics Data for Profile 174288</title>
  <author>
    <name>Google Analytics</name>
  </author>
  <generator version="1.0">Google Analytics</generator>
  <openSearch:totalResults>10</openSearch:totalResults>
  <openSearch:startIndex>1</openSearch:startIndex>
  <openSearch:itemsPerPage>5</openSearch:itemsPerPage>
  <dxp:dataSource>
    <dxp:property name="ga:profileId" value="174288" />
    <dxp:property name="ga:webPropertyId" value="UA-86539-1" />
    <dxp:property name="ga:accountName" value="www.mariomoretti.it" />
    <dxp:tableId>ga:174288</dxp:tableId>
    <dxp:tableName>www.mariomoretti.it</dxp:tableName>
  </dxp:dataSource>
  <dxp:endDate>2010-03-31</dxp:endDate>
  <dxp:startDate>2010-03-01</dxp:startDate>
  <entry>
    <id>http://www.google.com/analytics/feeds/data?ids=ga:174288&
        ga:pageTitle=Il%20podismo%20a%20cura%20di%20Mario%20Moretti&
        start-date=2010-03-01&end-date=2010-03-31
    </id>
    <updated>2010-03-30T17:00:00.001-07:00</updated>
    <title type="text">ga:pageTitle=Il podismo a cura di Mario Moretti</title>
    <link rel="alternate" type="text/html"
                        href="http://www.google.com/analytics" />
    <dxp:dimension name="ga:pageTitle"
                     value="Il podismo a cura di Mario Moretti" />
    <dxp:metric confidenceInterval="0.0" name="ga:pageviews"
                                             type="integer" value="30512" />
  </entry>
  <entry>
    <id>http://www.google.com/analytics/feeds/data?ids=ga:174288&
        ga:pageTitle=Calendario%20gare%20podistiche&
        start-date=2010-03-01&end-date=2010-03-31
    </id>
    <updated>2010-03-30T17:00:00.001-07:00</updated>
    <title type="text">ga:pageTitle=Calendario gare podistiche</title>
    <link rel="alternate" type="text/html"
                             href="http://www.google.com/analytics" />
    <dxp:dimension name="ga:pageTitle" value="Calendario gare podistiche" />
    <dxp:metric confidenceInterval="0.0" name="ga:pageviews"
                                               type="integer" value="7080" />
  </entry>
</feed>

Il data feed proposto riporta la lista delle pagine più visitate del sito www.mariomoretti.it nel mese di Marzo 2010. Ogni oggetto entry fornisce il titolo della pagina nel campo dimension ed il numero di visite alla pagina nel campo metric.

Esaminiamo ora un esempio di codice che richiede le 3 pagine più viste di un sito web nel mese di Marzo:

//creiamo una richiesta http di tipo GET
HttpWebRequest myRequest = (HttpWebRequest)WebRequest.Create(
              "https://www.google.com/analytics/feeds/data?ids=ga:" +
              profileID + "&dimensions=ga:pageTitle&metrics=ga:pageviews&sort=-
              ga:pageviews&start-date=2010-03-01&end-date=2010-03-31
              &prettyprint=true&max-results=3");
			  //mettiamo il token multisessione nell'header della richiesta
myRequest.Headers.Add("Authorization: GoogleLogin auth=" + token);
//inviamo la richiesta e intercettiamo la risposta
HttpWebResponse myResponse = (HttpWebResponse)myRequest.GetResponse();

La prassi è la stessa seguita per la richiesta dell'account, cambia solo l'url cui effettuiamo la richiesta. Per prendere confidenza con le moltiplici query che possiamo effettuare è consigliabile utilizzare il tool gratuito Data Feed Query Explorer.

Vediamo come si ottiene la stessa cosa con la GData .NET Client Library:

// Configuriamo il servizio Google di autenticazione con il nome della app
asv = new AnalyticsService("SimoneMoretti-gdataSamples-1");
// Passiamo le credenziali di accesso al servizio.
asv.setUserCredentials(TxtEmail.Text, TxtPassword.Text);
//Data Feed query uri.
String baseUrl = "https://www.google.com/analytics/feeds/data";
DataQuery query = new DataQuery(baseUrl);
query.Ids = TABLE_ID;
query.Metrics = "ga:pageviews";
query.Dimensions = "ga:pageTitle";
query.Sort = "-ga:pageviews";
query.GAStartDate = "2010-03-01";
query.GAEndDate = "2010-03-31";
query.NumberToRetrieve = 3;
query.PrettyPrint = true;
try
{
  DataFeed feed = asv.Query(query); //eseguiamo la query
}
catch (AuthenticationException e)
{
  // autenticazione fallita
}
  catch (Google.GData.Client.GDataRequestException e)
{
  // richiesta fallita
}

Usando la libreria basta creare un oggetto di tipo DataQuery al quale passiamo la URL per la richiesta dei data feed e i parametri per raffinare la query. Chiamando il metodo Query dell'oggetto AnalyticsService mandiamo in esecuzione la query ed il risultato viene posto in un oggetto di tipo DataFeed.

Gestire i risultati: account feed e data feed

Una volta capito come autenticare l'utente e come effettuare la richiesta di dati non ci resta che vedere come ricevere i risultati ed usarli per i nostri scopi. Osserviamo quindi come intercettare le risposta HTTP e interpretare i risultati dell'interrogazione.

Gestire un Account Feed

Cominciamo con l'intercettare la risposta HTTP che Analytics ci invia in seguito alla richiesta di un account utente. Vediamo, nel prossimo esempio, come interpretare l'account feed ricevuto:

//myRequest è la richiesta http per l'account utente
HttpWebResponse myResponse = (HttpWebResponse)myRequest.GetResponse();
Stream responseBody = myResponse.GetResponseStream();
Encoding encode = System.Text.Encoding.GetEncoding("utf-8");
StreamReader readStream = new StreamReader(responseBody, encode);
//trasformiamo la risposta in stringa
string response = readStream.ReadToEnd();
//la risposta ha un formato XML quindi creiamo un documento XML appropriato
XmlDocument accountinfoXML = new XmlDocument(); accountinfoXML.LoadXml(response);
//per ogni profilo abbiamo un elemento entry nell'account feed
XmlNodeList entries = accountinfoXML.GetElementsByTagName("entry");
NameValueCollection profiles = new NameValueCollection();
//cicliamo su tutti gli elementi entry
for (int i = 0; i < entries.Count; i++)
{
  // prendiamo l'id e il nome dei profili e mettiamoli in una collezione                         profiles.Add(entries.Item(i).ChildNodes[2].InnerText,
                   entries.Item(i).ChildNodes[6].Attributes["value"].Value);
}

La risposta HTTP viene gestita dalla classe HttpWebResponse. L' account feed che riceviamo è in formato Atom ovvero in un formato XML quindi, per comodità, trasformiamo la risposta HTTP in stringa e creiamo un documento XML a partire dalla stringa sfruttando la classe XmlDocument (System.Xml).

Sappiamo che ad ogni profilo corrisponde un elemento entry dell'account feed quindi cicliamo tra i vari nodi XML di tipo entry e prendiamo i valori relativi all'id e al nome del profilo. Collochiamo, infine, queste informazioni in una collezione.

Al solito, vediamo come ottenere lo stesso risultato impiegando la GData .NET Client Library:

// Creiamo una query di tipo Account.
AccountQuery query = new AccountQuery();
// eseguiamo la query e mettiamo il risultato in un oggetto di tipo AccountFeed
AccountFeed accountFeed = asv.Query(query);
NameValueCollection profiles = new NameValueCollection();
//cicliamo su tutti gli elementi entry
for (int i = 0; i < accountFeed.Entries.Count; i++)
{
  string nome =((AccountEntry)accountFeed.Entries[i]).Title;
  string profileid =((AccountEntry)accountFeed.Entries[i]).ProfileId;
  // prendiamo l'id e il nome dei profili e mettiamoli in una collezione
  profiles.Add(profileid, nome);
}

Tutto ciò che dobbiamo fare è creare un oggetto di tipo AccountQuery che rappresenta la richiesta di informazioni sull'account utente. Dopo di ciò dobbiamo invocare il metodo Query dell'oggetto asv di tipo AnalyticsService e mettere il risultato della query in un oggetto di tipo AccountFeed. Cicliamo, infine, tra le entry (ne abbiamo una per ogni profilo) e preleviamo il nome e l'identificativo dei profili per mezzo delle proprietà Title e ProfileId.

Gestire un Data Feed

Nella pagina precedente abbiamo visto come richiedere i dati relativi alle pagine più viste di un sito in un determinato mese. Vediamo, attraverso il seguente esempio, come intercettare la risposta http e come interpretare il data feed ricevuto:

//myRequest è la richiesta http di dati Analytics
HttpWebResponse myResponse = (HttpWebResponse)myRequest.GetResponse();
Stream responseBody = myResponse.GetResponseStream();
Encoding encode = System.Text.Encoding.GetEncoding("utf-8");
StreamReader readStream = new StreamReader(responseBody, encode);
//trasformiamo il risultato in formato stringa
results = readStream.ReadToEnd();
//creiamo un documento XML a partire dalla stringa precedente
XmlDocument resultsXML = new XmlDocument();
resultsXML.LoadXml(results);
//creiamo una lista degli oggetti entry
XmlNodeList entries = resultsXML.GetElementsByTagName("entry");
//dagli oggetti entry preleviamo il valore di dimension e metric
for (int i = 0; i < entries.Count; i++)
{
   string dimension = entries[i].ChildNodes[4].Attributes["value"].Value;
   string metric = entries[i].ChildNodes[5].Attributes["value"].Value;
   // dimension e metric sono il titolo della pagina e il numero di visualizzazioni
   Response.Write(demension + " - " + metric + "<BR>");
}

La risposta HTTP viene gestita dalla classe HttpWebResponse. Il data feed che riceviamo è in formato Atom ovvero in un formato XML quindi per comodità del programmatore trasformiamo la risposta HTTP in stringa e creiamo un documento XML a partire dalla stringa sfruttando la classe XmlDocument. Sappiamo che ad ogni dato corrisponde un elemento entry del data feed quindi cicliamo tra i vari nodi XML di tipo entry e prendiamo i valori relativi alla dimensione e alla metrica.

Ecco come ottenere lo stesso risultato impiegando la GData .NET Client Library:

// GA Data Feed query uri
String baseUrl = "https://www.google.com/analytics/feeds/data";
DataQuery query = new DataQuery(baseUrl);
          query.Ids = TABLE_ID;
          query.Metrics = "ga:pageviews";
          query.Dimensions = "ga:pageTitle";
          query.Sort = "-ga:pageviews";
          query.GAStartDate = "2010-03-01";
          query.GAEndDate = "2010-03-31";
          query.NumberToRetrieve = 3;
          query.PrettyPrint = true;
try
{
  feed = asv.Query(query); //eseguiamo la query
}
catch (AuthenticationException e){ // autenticazione fallita }
catch (Google.GData.Client.GDataRequestException e){ //autenticazione fallita } 
if (feed.Entries.Count != 0) //se abbiamo oggetti entry
{
  for (int i = 0; i < feed.Entries.Count; i++) //cicliamo tra gli entry
  {
    //prendiamo dimension e metric
    string dimension = ((DataEntry)feed.Entries[i]).Dimensions[0].Value;
    string metric = ((DataEntry)feed.Entries[i]).Metrics[0].Value;
    //dimension e metric sono il titolo della pagina e il numero di visualizzazioni
    Response.Write(dimension + " - " + metric + "<BR>");
  }
}

Creiamo un oggetto DataQuery al quale passiamo i parametri Ids, Dimensions, Metrics, Sort, GAStartDate, GAEndDate, NumberToRetrieve e PrettyPrint. Eseguiamo la query e poniamo il risultato in un oggetto DataFeed. Cicliamo tra gli oggetti Entry del DataFeed e prendiamo i valori delle proprietà Dimension e Metric.

Usare la GData .NET Client Library

La libreria mette a disposizione un insieme di classi che corrispondono agli elementi ed ai tipi di dati usati dalla GData API. Ad esempio c'è una classe Feed che corrisponde all'elemento <atom:feed>, c'è anche una classe Entry corrispondente all'elemento <atom:entry>. Allo stesso modo troviamo classi Dimension, Metric, Segment, DataSource corrispondenti ad altrettanti elementi Atom.

La libreria può navigare automaticamente all'interno di una struttura Atom e creare degli oggetti corrispondenti agli elementi della struttura.

Nel capitolo 3 abbiamo presentato degli esempi che fanno vedere quanto sia semplice interagire con le GA Export API attraverso la GData .NET Client Library. Abbiamo osservato anche che le GA Export API permettono solo di leggere dati Analytics ma di non manipolarli.

Osserviamo che attraverso la GData .NET Client Library è possibile interagire non solo con le GA Export API ma con tutte le GData API riportate di seguito:

GData API supportate
Base Blogger
Calendar Spreadsheets
Google Apps Provisioning Code Search
Notebook Picasa Web Albums
Document Feed Contacts
You Tube Google Health
Google Webmaster Tools

Molte di queste API consentono di manipolare i dati, oltre che di leggerli. GData .NET Client Library agevola questa manipolazione attraverso degli appositi metodi (insert, update, delete) applicabili ad oggetti di alto livello (feed, entry, segment, ecc.). Maggiori dettagli li troviamo sulla .NET Client Library Developer's Guide.

Ora ne sappiamo abbastanza su Google Analytics e sulle relative API. Nella seconda parte dell'articolo realizzeremo tre esempi che per toccare con mano le potenzialità che questi strumenti mettono a disposizione.

Email con report settimanale degli accessi al sito

Nella prima parte dell'articolo abbiamo osservato le tecniche di base per l'accesso ai dati di traffico dei nostri siti. Ora realizziamo invece alcuni esempi per toccare con mano le potenzialità di queste API.

Un servizio molto interessante che possiamo implementare è l'invio di una email con resoconto settimanale delle statistiche del sito web rivolta ad una lista di utenti:

protected void btnEmail_Click(object sender, EventArgs e)
{
  string from = "webmaster@undominio.it";
  string soggetto = "Resoconto Settimanale Statistiche Sito Web";
  string emails = "cliente1@undominio.it, cliente2@undominio.it";
  System.Net.Mail.MailMessage mail = new System.Net.Mail.MailMessage();
  System.Net.Mail.SmtpClient smtp = new System.Net.Mail.SmtpClient();
  mail.From = new System.Net.Mail.MailAddress(from);
  mail.To.Add(emails);
  mail.IsBodyHtml = true;
  mail.Subject = soggetto;
  mail.Body = dati();//risultato della query a Google Analytics
  smtp.Host = "Smtp.undominio.it";
  smtp.Send(mail);
}

Per generare l'email usiamo la classe Mail (System.Net), valorizziamo i campi mittente, destinatario e soggetto e nel corpo del messaggio inseriamo il risultato della nostra query a Google Analytics.

Esaminiamo il metodo dati che richiede il totale di accessi al sito nella settimana corrente:

protected string dati()
{
  // GA Data Feed query uri
  String baseUrl = "https://www.google.com/analytics/feeds/data";
  DataQuery query = new DataQuery(baseUrl);
            query.Ids = TABLE_ID;
            query.Metrics = "ga:visits";
            query.Dimensions = "ga:date";
            query.Sort = "ga:date";
            query.GAStartDate = "2010-06-21";
            query.GAEndDate = "2010-06-27";
            query.PrettyPrint = true;
   try
   {
      feed = asv.Query(query);
   }
   catch (AuthenticationException e)
   {
     //autenticazione fallita
   }
   catch (Google.GData.Client.GDataRequestException e)
   {
     //autenticazione fallita
   }
   return getEntriesAsTable(feed); //trasformo il DataFeed in formato stringa
}

Il risultato della query valorizza l'oggetto feed di tipo DataFeed. Di questo oggetto prendiamo solo i dati che ci interessano e li trasformiamo in stringhe, grazie al metodo getEntriesAsTable, in cui iniziamo ad elaborare il messattio. Per organizzare meglio il report, introduciamo anche un po' di formattazione nel testo:

public String getEntriesAsTable()
{
  if (feed.Entries.Count == 0)
  {
      return "Nessun entry trovato";
  }
  StringBuilder feedDataLines = new StringBuilder("n----- Elenco delle entry ----n");
  //cicliamo tra gli oggetti entry del DataFeed
  foreach (DataEntry singleEntry in feed.Entries)
  {
    // creiamo un array delle dimensioni
    foreach (Dimension dimension in singleEntry.Dimensions)
    {
     String[] args = { dimension.Name, dimension.Value };
     feedDataLines.AppendLine(String.Format("n{0} t= {1}", args));
    }
    // creiamo un array delle metriche
    foreach (Metric metric in singleEntry.Metrics)
    {
     String[] args = { metric.Name, metric.Value };
     feedDataLines.AppendLine(String.Format("n{0} t= {1}", args));
    }
    feedDataLines.Append("n");
  }
  // ritorniamo la stringa generata
  return feedDataLines.ToString();
}

Cicliamo tra gli oggetti entry del datafeed, per ogni entry cicliamo tra i suoi oggetti Dimension e Metric ed inseriamo i valori in un oggetto StringBuilder di appoggio che alla fine trasformiamo in stringa.

Grafici con statistiche mensili degli accessi al sito

Il secondo esempio che realizziamo consiste nella creazione di grafici che mostrino le statistiche del traffico del sito.Questi report possono essere creati dinamicamente al momento della richiesta degli utenti da pagine web preposte.

Grafico lineare degli accessi

Vediamo come realizzare un grafico lineare che riporta il numero di accessi al sito nel corso di un mese:

protected string dati()
{
  // GA Data Feed query uri.
  String baseUrl = "https://www.google.com/analytics/feeds/data";
  DataQuery query = new DataQuery(baseUrl);
  query.Ids = TABLE_ID;
  query.Metrics = "ga:visits";
  query.Dimensions = "ga:date";
  query.Sort = "ga:date";
  query.GAStartDate = "2010-03-01";
  query.GAEndDate = "2010-03-31";
  query.PrettyPrint = true;
  try { feed = asv.Query(query); }
  catch (AuthenticationException e) { } // autenticazione fallita
  catch (Google.GData.Client.GDataRequestException e){ } //autenticazione fallita
  if (feed.Entries.Count != 0)
  {
    for (int i = 0; i < feed.Entries.Count; i++)
	{
      string giorno = ((DataEntry)feed.Entries[i]).Dimensions[0].Value;
      string visite = ((DataEntry)feed.Entries[i]).Metrics[0].Value;
      Chart1.Series["Serie"].Points.AddXY(giorno, visite );
      //recupero il datapoint appena inserito e vi aggiungo la proprietà tooltip
      System.Web.UI.DataVisualization.Charting.DataPoint dp = new System.Web.UI.DataVisualization.Charting.DataPoint();
      dp = Chart1.Series["Serie"].Points[Chart1.Series["Serie"].Points.Count - 1];
      dp.ToolTip = "visite: " + visite + " giorno:" + giorno;
    }
  }
  Chart1.Visible= true;
}

Il nostro grafico ha nell'asse delle ascisse i giorni del mese e nell'asse delle ordinate il numero totale di accessi per giorno. Costruiamo il grafico usando il Chart Control. Alimentiamo il grafico con i dati provenienti dalla query rivolta al servizio remoto Google Analytics. In figura 6 possiamo vedere il grafico generato.

Figura 5. Grafico degli accessi mensili
(clic per ingrandire)


Google Data API

Per saperne di più sull'utilizzo del Chart Control è possible leggere questo articolo.

Grafico a torta dei browser dei visitatori

Un altro report tipico è quello che riproduce in un grafico a torta le visite raggruppate sui browser usati dai visitatori del sito web:

protected string dati()
{
  // GA Data Feed query uri.
  String baseUrl = "https://www.google.com/analytics/feeds/data";
  DataQuery query = new DataQuery(baseUrl);
  query.Ids = TABLE_ID;
  query.Metrics = "ga:visits";
  query.Dimensions = "ga:browser";
  query.Sort = "ga:visits";
  query.GAStartDate = "2010-03-01";
  query.GAEndDate = "2010-03-31";
  query.PrettyPrint = true;
  try { feed = asv.Query(query);  }
  catch (AuthenticationException e) { } // autenticazione fallita
  catch (Google.GData.Client.GDataRequestException e) { } //autenticazione fallita
  if (feed.Entries.Count != 0)
  {
    for (int i = 0; i < feed.Entries.Count; i++)
	{
	  string browser = ((DataEntry)feed.Entries[i]).Dimensions[0].Value;
	  string visite = ((DataEntry)feed.Entries[i]).Metrics[0].Value;
	  Chart2.Series["Serie"].Points.AddXY(browser, visite);
	  // recupero il datapoint appena inserito e vi aggiungo la proprietà tooltip
	  System.Web.UI.DataVisualization.Charting.DataPoint dp = new System.Web.UI.DataVisualization.Charting.DataPoint();
	  dp = Chart2.Series["Serie"].Points[Chart2.Series["Serie"].Points.Count - 1];
	  dp.ToolTip = "Browser = #VALXnTotale visite = #VALYnPercentuale =  #PERCENT{P2}";
    }
  }
  Chart2.Visible = true;
}

La prassi è la stessa dell'esempio precedente, eseguiamo la query al servizio Analytics e riempiamo l'oggetto Chart con i dati contenuti negli oggetti Dimension e Metric.

Figura 6. Grafico browser usati dai visitatori del sito
Grafico browser usati dai visitatori del sito

Tutti gli esempi che abbiamo esaminato sono disponibili nel file allegato all'articolo.

Conclusioni

Interrogare Google Analytics è molto semplice, grazie alle Google Analytics Data Export API. Abbiamo visto come effettuare query e ottenere i dati sotto forma di richieste e risposte HTTP (logica REST) e come sfruttare i dati ottenuti sotto forma di feed.

  • Google Data Protocol: home page sul protocollo di comunicazione usato dalle Google Data API
  • .NET Client Library Developer's Guide: guida all'utilizzo della libreria client nella versione per la piattaforma .NET
  • HTTP - Method Definitions : dalla RFC del protocollo HTTP
  • Building Web Services the REST Way : interessante articolo di Roger Costello sul protocollo REST
  • The Atom Publishing Protocol: specifiche del protocollo AtomPub
  • Using JSON in the Google Data Protocol: guida all'uso di JSON come alternativa ad ATOM nel Google Data Protocol
  • Introducing Google Analytics API with asp.net/C# : usare le Google Analytics API con il metodo tradizionale proposto da Dave Callan.
  • Simone Moretti è un architetto ASP.NET Senior laureato in Informatica. Si dedica da quasi un decennio alla realizzazione di applicazioni Web con tecnologia ASP.NET/C#. Attualmente lavora presso la pubblica amministrazione per conto di Wizards Consulting SpA [www.wizardsgroup.it].

    Ti consigliamo anche