lalahop

Utiliser l’API de Piwik pour générer des rapports

Table des matières

L'API de Piwik permet, entre autres, de générer des rapports automatiques et/ou personnalisables.

Rappels de base sur l'API

L'API peut être interrogée via HTTP ou être utilisée directement dans vos scripts PHP. Voir ici pour des exemples : Piwik Analytics API – Calling Techniques. Ci-dessous, nous intégrerons l'API à un script PHP mais il est tout à fait envisageable de scripter l'appel à l'API via HTTP grâce à un script shell et à curl/wget. Quand on a compris une méthode, l'autre coule de source, seul le formalisme change.

Si je n'ai qu'un seul reproche à formuler à l'API, c'est son manque de documentation. Les prototypes des fonctions disponibles sont bien annoncés mais on ne nous explique pas toujours ce que la fonction attend en paramètre. Il faut alors aller lire le code source pour comprendre. De plus, l’hétérogénéité (ou le manque d'harmonisation) du code n'aide pas (ex. : pour certaines fonctions, on doit passer un tableau, pour d'autres une liste dont les termes sont séparés par une virgule ...).

Comment créer un rapport depuis l'API ?

Pourquoi créer un rapport via l'API alors que l'interface web le permet ? Parfois, la création d'un rapport via l'interface web échoue. Je n'ai pas encore cherché la cause du problème.

Voici le code :

<?php

	define('PIWIK_INCLUDE_PATH', realpath('./piwik')); //Répertoire racine de Piwik
	define('PIWIK_USER_PATH', realpath('./piwik')); //Idem
	define('PIWIK_ENABLE_DISPATCH', false);
	define('PIWIK_ENABLE_ERROR_HANDLER', false);
	define('PIWIK_ENABLE_SESSION_START', false);
	require_once PIWIK_INCLUDE_PATH . "/index.php";
	require_once PIWIK_INCLUDE_PATH . "/core/API/Request.php";
 
        //On créer le contrôleur
	Piwik_FrontController::getInstance()->init();
 
        //On prépare la requête que l'on souhaite effectuer
	$request = new Piwik_API_Request('
			method=PDFReports.addReport
			&idSite=1
			&description=test API
			&period=never
			&reportFormat=html
                        &reports=VisitsSummary_get,VisitTime_getVisitInformationPerLocalTime,Actions_getPageTitles,Actions_getOutlinks,Referers_getRefererType,Referers_getKeywords,Referers_getWebsites,Referers_getSearchEngines,UserCountry_getCountry,VisitorInterest_getNumberOfVisitsPerVisitDuration,VisitorInterest_getNumberOfVisitsPerPage,VisitFrequency_get,Provider_getProvider,UserSettings_getConfiguration
			&emailMe=0
			&token_auth=votretoken
	');

 
        //On exécute la requête
        $result = $request->process();
 
        //On affiche le résultat de la requête
	echo $result,'<br />';
?>

La méthode Piwik_API_Request permet de préparer une requête pour l'API. Les paramètres de cette méthode sont variables selon ce que l'on veut obtenir. Ici (seuls les paramètres peu ou pas documentés sont expliquées) :

  • method permet de spécifier ce que l'on veut obtenir. Ici, nous utilisons la méthode addReports du module PDFReports. Pour avoir une idée des opérations disponibles, il suffit d'aller dans la doc de Piwik (j'ai déjà donné un lien plus haut)
  • description permet de spécifier la description du rapport (voir interface web)
  • reportFormat permet de choisir un format de rapport (pdf ou html)
  • reports permet de choisir les informations (configuration matérielle du visiteur, heure de visite, ...) que l'on veut intégrer au rapport. La liste est disponible en appelant la méthode getReportMetadata du module API. Voir un exemple en ligne. Il suffit de récupérer l'uniqueId associé au rapport que vous voulez et de l'indiquer dans ce paramètre. Ici, on récupère, dans l'ordre : le récapitulatif des visites, les visites en fonction de l'heure locale, le titre des pages vues, les liens sortants, les types de referer (entrée directe, site web, ...), les mots clés dans les moteurs de recherche, les sites web, les moteurs de recherches d'où provient l'entrée, le pays du visiteur, la durée d'une visite, le nombre de pages par visite, la fréquence des visites, le FAI, la configuration complète du visiteur.
  • emailMe permet de demander la réception du rapport par courrier. Ici, on refuse (0).

Si la création du rapport fonctionne, l'API vous retourne l'id du rapport, sinon, l'API vous retourne un message d'erreur explicite.

Comment générer un rapport automatiquement depuis un script ?

Si vous avez compris l'exemple précédent, rien de bien compliqué ici : il suffit de lire la doc et les fichiers sources.

<?php
	define('PIWIK_INCLUDE_PATH', realpath('./piwik')); //Répertoire racine de Piwik
	define('PIWIK_USER_PATH', realpath('./piwik')); //Idem
	define('PIWIK_ENABLE_DISPATCH', false);
	define('PIWIK_ENABLE_ERROR_HANDLER', false);
	define('PIWIK_ENABLE_SESSION_START', false);
	require_once PIWIK_INCLUDE_PATH . "/index.php";
	require_once PIWIK_INCLUDE_PATH . "/core/API/Request.php";

        //On créer le contrôleur
	Piwik_FrontController::getInstance()->init();
        //On prépare la requête que l'on souhaite effectuer
	$request = new Piwik_API_Request('
			method=PDFReports.generateReport
			&idSite=1
			&idReport=2
			&date=2011-07-05
			&language=fr
			&period=month
			&reportFormat=html
			&outputType=2
			&token_auth=votretoken
        ');

 
        //On exécute la requête
        $result = $request->process();
?>

Explications :

  • idReport doit correspondre à l'id d'un rapport existant. Cet id est retourné par la méthode addReport ou est disponible dans la base de données et plus précisément dans la table prefixe_pdf. En remplaçant "prefixe" par le préfixe de vos tables Piwik.
  • outputType correspond à la manière dont le rapport sera sauvegardé. Si la valeur 1 est passée, alors le fichier sera disponible en téléchargement. Si la valeur 2 est passée, alors le fichier sera stocké sur le serveur, dans le repertoire piwik/tmp/assets/ . La valeur 1 est la valeur par défaut. Ces deux valeurs sont définies dans les constantes OUTPUT_DOWNLOAD et OUTPUT_SAVE_ON_DISK de la classe Piwik_PDFReports_API (fichier Piwik/plugins/PDFReports/API.php.

Là où cela devient intéressant, c'est dans le cadre d'un processus de sauvegarde secondaire. En effet, si vous n'avez jamais exporté vos données sur une longue période, il est fastidieux de le faire à la main.

L'API possède une option YYYY-MM-DD,YYYY-MM-DD pour le paramètre date et une option "month" pour le paramètre period. Cela permet donc de récupérer, comme le dit la doc, des informations pour chaque mois de la période donnée. Ex. : index.php?module=API&method=VisitsSummary.get&idSite=1&period=month&date=2010-07-01,2011-03-01&format=html permet de récupérer le récapitulatif des visiteurs pour chacun des mois compris entre juillet 2010 et mars 2011, au format html. Mais, cela ne fonctionne pas avec toutes les méthodes de l'API. C'est notamment le cas avec le module live ou le module PDFReports.

Il va donc falloir scripter afin de récupérer un rapport par mois, tous les mois d'une période donnée. Une simple boucle et l'utilisation de la classe DateTime suffiront. Cela donne :

<?php
	define('PIWIK_INCLUDE_PATH', realpath('./piwik')); //Répertoire racine de Piwik
	define('PIWIK_USER_PATH', realpath('./piwik')); //Idem
	define('PIWIK_ENABLE_DISPATCH', false);
	define('PIWIK_ENABLE_ERROR_HANDLER', false);
	define('PIWIK_ENABLE_SESSION_START', false);
	require_once PIWIK_INCLUDE_PATH . "/index.php";
	require_once PIWIK_INCLUDE_PATH . "/core/API/Request.php";
 
        //On créer le contrôleur
	Piwik_FrontController::getInstance()->init();
 
        //On prépare la période sur laquelle on va travailler
	$dateDebut = '2010-08-01';
	$dateFin = '2011-08-01';	
	$dateInc = new DateTime($dateDebut);

 
        //Tant que la date qui va être incrémenté n'est pas égale à la date de fin ...
	while ($dateInc->format('Y-m-d') != $dateFin)
	{	
                // ... on prépare la requête ...

	        $request = new Piwik_API_Request('
				method=PDFReports.generateReport
				&idSite=1
				&idReport=1
				&date='.$dateInc->format('Y-m-d').'
				&language=fr
				&period=month
				&reportFormat=html
				&outputType=2
				&token_auth=votretoken
		');

 
		// ... et on l’exécute ...
		$result = $request->process();
 
                // ... et enfin on incrémente la date sur laquelle on travaille		
		$dateInc->modify('+1 month');
	}
?>

ÉDIT 31/07/2011 à 1h12 :
Le script ci-dessus peut-être optimisé. Nous profitons de l'opérateur d'égalité (pas d'identité !) qui permet de faire la différence entre deux objets d'une même classe en fonction de la valeur de leur attributs. Ainsi, nous ne faisons plus appel à la méthode "format()" de la classe DateTime. Ce qui donne :

        // code identique
        $dateDebut = new DateTime('2010-08-01');
        $dateFin = new DateTime('2011-08-01');	
 
        //Tant que la date qui va être incrémenté n'est pas égale à la date de fin ...
	while ($dateDebut != $dateFin)
	{
		// code identique
	}

Côté performance, cela est insignifiant : environ 0.0012 secondes d'écart entre les deux scripts, en faveur du deuxième script. Mesure effectuée avec la fonction xdebug_time_index() de XDebug, en ne faisant rien d'autre qu'afficher un message avec echo dans la boucle while et en prenant une période de 490 mois .
Fin de l'édit

Comment débloquer la limite du nombre de lignes de chaque tableau ?

Comme je l'ai déjà dit, dans un rapport, le nombre de lignes par tableau est limité (ex. : seulement les 30 mots-clés les plus utilisés sont affichés).

L'API précise qu'il existe un paramètre optionnel, filter_truncate, qui permet de changer cette limite. Néanmoins, ce paramètre est contourné par le module PDFReports. C'est dans le fichier /piwik/plugins/PDFReports/API.php que cela se passe :

Lignes 313-314 :

$filterTruncateGET = Piwik_Common::getRequestVar('filter_truncate', false);
$_GET['filter_truncate'] = 30;

Lignes 333-337 :

// Restore values
if($filterTruncateGET !== false)
{
        $_GET['filter_truncate'] = $filterTruncateGET;
}

Bien que cette option a sans doute été désactivée pour des raisons de performances, il y a un moyen de la réactiver :

Il suffit de remplacer les lignes 313/314 par :

$_GET['filter_truncate'] = $filterTruncateGET = Piwik_Common::getRequestVar('filter_truncate', false);

Et de commenter les lignes 333-337.

Ensuite, vous pouvez utiliser filter_truncate. Avec ce code, les tableaux du rapport généré feront jusqu'à 100 lignes. Ainsi, dans le rapport sur les mots-clés utilisés, vous aurez le top 100 au lieu du top 30 :

$request = new Piwik_API_Request('
		method=PDFReports.generateReport
		&idSite=1
		&idReport=1
		&date='.$dateInc->format('Y-m-d').'
		&language=fr
		&period=month
		&reportFormat=html
		&outputType=2
                &filter_truncate=100
		&token_auth=votretoken
');

Comment utiliser l'API pour générer des rapports plus personnels

De nombreuses méthodes existent dans l'API Piwik. Cela vous permet de vous fabriquer un rapport sur mesure (avec uniquement les informations que vous voulez) ou de surveiller une seule information (le nombre de visiteurs uniques du mois, par exemple). De plus, l'API donne accès à des informations que les rapports n’intègrent pas (ex. : le module live n'apparait pas dans les rapports), ce qui permet un export des données.

C'est ici que je vous laisse car vous trouverez des exemples dans la documentation de Piwik.

PS : Les codes donnés ci-dessus n'ont pas vocation à être utilisés en production sans amélioration. Par exemple : il n'y a pas de contrôle des erreurs.

PS2 : Ce billet n'évoque pas la Piwik Tracker API. Il peut tout de même être intéressant de jeter un oeil à la documentation, pour, par exemple, prendre un minimum en compte les utilisateurs ayant désactivé javascript.

Les commentaires sont fermés