Google Analytics Core Reporting API (Data Export) with Google Chart Visualizations

Updated 12/20/11 and 01/04/12 to reflect Google’s API changes

You can punch into the Google Analytics Core Reporting (Data Export) API, pull out some stats, and stuff them into some nice graphical charts using Google Chart Visualizations. This demo is done in PHP.
Google Chart Visualizations

Authenticate the User

The user can authenticate via the ClientLogin or using the AuthSub login which is actually more secure. For the ClientLogin, a typical username/password form is used. For the AuthSub login a link is used to send the user to Google to log in. Both are shown below. Normally you would use one or the other.

* Use ClientLogin ONLY for installed apps and not web apps

<form name="loginForm" action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post">
		    <label for="email">Gmail:</label>
		    <input id="email" type="text" name="email" />
		    <label for="password">Password:</label>
		    <input type="password" name="password" id="password"/>
		    <br /><br />
		    <button type="submit" id="submitLogin">Submit</button>
		</form>
        <p><a class="button" href="https://www.google.com/accounts/AuthSubRequest?next=http://your-return-url&scope=https://www.googleapis.com/auth/analytics.readonly&secure=0&session=1">Or,authenticate using AuthSub through Google.</a></p>

And, of course, the two authentication methods use different http calls to return a token that can be used to access the API.

//ClientLogin: try to log in and get session token for multiple API calls
if(isset($_POST['email']) && isset($_POST['password'])){
	$_SESSION['sessionToken'] = googleLogin($_POST['email'],$_POST['password']);
}
//AuthSub: exchange token for session token so multiple calls can be made to api
if(isset($_REQUEST['token'])){
	$_SESSION['authSub'] = true;
	$_SESSION['sessionToken'] = get_session_token($_REQUEST['token']);
}

//returns sessionToken for multiple calls to API
function googleLogin($email,$passwd){
	
    $clientlogin_url = "https://www.google.com/accounts/ClientLogin";
     $clientlogin_post = array(
    "accountType" => "GOOGLE",
    "Email" => $email,
    "Passwd" => $passwd,
    "service" => "analytics",
    "source" => "my-analytics"
	);
 
	$curl = curl_init($clientlogin_url);

	curl_setopt($curl, CURLOPT_POST, true);
	curl_setopt($curl, CURLOPT_POSTFIELDS, $clientlogin_post);
	curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
	curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
	curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);

	$response = curl_exec($curl);
 
	preg_match("/Auth=([a-z0-9_\-]+)/i", $response, $matches);
	$sessionToken = $matches[1];

	if (strlen($sessionToken) == 0){
		$sessionToken = "Authentication Failed.";
	}
	 
 	return $sessionToken;
}

//AuthSub returns session token for multiple calls to API
	function get_session_token($onetimetoken) {
		$output = call_api($onetimetoken, "https://www.google.com/accounts/AuthSubSessionToken");
				
		if (preg_match("/Token=(.*)/", $output, $matches))
		{
			$sessionToken = $matches[1];
		} else {
			echo "Error authenticating with Google.";
			exit;
		}
		
		return $sessionToken;
	}

Data Requests

Once authenticated to a Google Analytics account and a multi-use session token is acquired, the data requests can be made. The first one will request the profiles (websites) associated with the account. If there is more than one, a dropdown select is populated allowing for the selection of the profile from which to pull data.

The key is added to the request per this post by Google.

$accountxml = call_api($_SESSION['sessionToken'],"https://www.googleapis.com/analytics/v2.4/management/accounts/~all/webproperties/~all/profiles?key=Axxxxxxxxxxxxxxxxxx4");
// Get an array with the available accounts
$profiles = parse_account_list($accountxml);

The call_api function is going to return the XML data from Google based on the request URL sent in. In this case, it is getting the profile data and the parse_account_list function is rolling through that XML and putting the profile data in an array.

//gets the data
function call_api($sessionToken,$url){
	$curl = curl_init($url);
 
	curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);	
	if (isset($_SESSION['authSub'])){
		$curlheader[0] = sprintf("Authorization: AuthSub token=\"%s\"/n", $sessionToken);
	} else {
		$curlheader[0] = "Authorization: GoogleLogin auth=" . $sessionToken;
	}
	curl_setopt($curl, CURLOPT_HTTPHEADER, $curlheader);

	$response = curl_exec($curl);
	curl_close($curl);

	return $response;	    
}

//returns accounts list as array	
function parse_account_list($xml){
	$doc = new DOMDocument();
	if(stripos($xml,"<") !== FALSE)
	{
		$doc->loadXML($xml);
	
		$entries = $doc->getElementsByTagName('entry');
		$i = 0;
		$profiles= array();
		foreach($entries as $entry)
		{
			$profiles[$i] = array();

			$properties = $entry->getElementsByTagName('property');
			foreach($properties as $property)
			{
				if (strcmp($property->getAttribute('name'), 'ga:accountId') == 0)
					$profiles[$i]["accountId"] = $property->getAttribute('value');

				if (strcmp($property->getAttribute('name'), 'ga:profileName') == 0)
					$profiles[$i]["title"] = $property->getAttribute('value');

				if (strcmp($property->getAttribute('name'), 'dxp:tableId') == 0)
					$profiles[$i]["tableId"] = $property->getAttribute('value');
			}
				
			$i++;
		}
		
		return $profiles;
	} else {
		$sessionToken = "Authentication Failed.";
	}
}

The dropdown of the profile array:

echo "<form name='siteSelect' id='siteSelect' method='post' action='" . $_SERVER['PHP_SELF'] . "'><p><label for='tableId'>Select Site:</label><select name='tableId' id='tableId'>";
		foreach($profiles as $profile)
		{
			if($profile["tableId"] == $table_Id)
				$selected = "selected='selected'";
				echo "<option value='" . $profile["tableId"] . "|" . $profile["title"] . "'" . $selected  . ">" . $profile["title"] . "</option>";
				$selected = " ";
		}
		echo "</select></p>";

// set $tableId
if(isset($_POST['tableId'])){
    $tableId = substr($_POST['tableId'],0,strpos($_POST['tableId'],"|"));
}

The parse_data function below is going to roll through the data returned from Google Analytics and spit out an array that can be used to create the Google Visualization graphs.

//returns data as array	
function parse_data($xml){
		$doc = new DOMDocument();
		$doc->loadXML($xml);

		$entries = $doc->getElementsByTagName('entry');
		$i = 0;
		$results = array();
		foreach($entries as $entry)
		{		
			$dimensions = $entry->getElementsByTagName('dimension');
			foreach($dimensions as $dimension)
			{
				$results[$i][ltrim($dimension->getAttribute("name"),"ga:")] =  $dimension->getAttribute('value');
			}
			
			$metrics = $entry->getElementsByTagName('metric');
			foreach($metrics as $metric)
			{
				$results[$i][ltrim($metric->getAttribute('name'),"ga:")] =  $metric->getAttribute('value');
			}
			
			$i++;
		}
		return $results;
}

Graph Generation

Request the data

// For each website, get referrals
$requrl = sprintf("https://www.googleapis.com/analytics/v2.4/data?ids=%s&dimensions=ga:source&metrics=ga:visits&filters=ga:medium==referral&start-date=%s&end-date=%s&sort=-ga:visits&max-results=10",$tableId,$start_date,$end_date);
				
$referralsxml = call_api($_SESSION['sessionToken'],$requrl);				
$referrers = parse_data($referralsxml);

$requrlvisitsgraph = sprintf("https://www.googleapis.com/analytics/v2.4/data?ids=%s&dimensions=ga:date&metrics=ga:visits&start-date=%s&end-date=%s",$tableId,$start_date,$end_date);
$visitsgraphxml = call_api($_SESSION['sessionToken'],$requrlvisitsgraph);				
$visitsgraph = parse_data($visitsgraphxml);		

Google Visualizations requires the inclusion of a javascript file in the head tag and empty div’s that will be the target for the graphs:

<script type="text/javascript" src="//www.google.com/jsapi"></script>

The target div’s should be placed on the page where you want them to appear.

<div id='barchart_div'></div>
<div id='piechart_div'></div>

Finally, the data can be added to the chart generation javascript:

<script>      
function drawPieChart() {
	var data = new google.visualization.DataTable();
    data.addColumn('string', 'Referrer');
    data.addColumn('number', 'Visits');
    data.addRows(<?php echo sizeof($referrers) ?>);
    <?php
    $row = 0;
    foreach($referrers as $referrer)
		{
	?>
	data.setValue(<?php echo $row ?>,0,'<?php echo $referrer["source"] ?>');
	data.setValue(<?php echo $row ?>,1,<?php echo $referrer["visits"] ?>);
	<?php	
	$row++;
	}
	?>

	var chart = new google.visualization.PieChart(document.getElementById('piechart_div'));
    chart.draw(data, {width: 600, height: 440, is3D: true, title: 'Referrer/Visits'});
}

function drawBarChart() {
	var data = new google.visualization.DataTable();
    data.addColumn('string', 'Day');
    data.addColumn('number', 'Visits');
    data.addRows(<?php echo sizeof($visitsgraph) ?>);
	<?php
    $row = 0;
    foreach($visitsgraph as $visits)
		{
	?>
		data.setValue(<?php echo $row ?>,0,'<?php if ($visits_graph_type === "month"){echo date("M", mktime(0, 0, 0, $visits["month"]))." ".$visits["year"];}else{echo substr($visits['date'],6,2)."-".date('M', mktime(0, 0, 0, substr($visits['date'],4,2)))."-".substr($visits['date'],0,4);} ?>');
		data.setValue(<?php echo $row ?>,1,<?php echo $visits["visits"] ?>);
		<?php 
		$row++; 
		}
		?>
    var chart = new google.visualization.ColumnChart(document.getElementById('barchart_div'));
    chart.draw(data, {'width': 700, 'height': 400, 'is3D': true, 'title': 'Visits'});
}

google.load("visualization", "1.0", {packages:["corechart"]});
google.setOnLoadCallback(drawPieChart);
google.setOnLoadCallback(drawBarChart);

</script>

Recommended

Demo

Download code

Posted in Google Analytics, php, Web development. Tags: , , , . Permalink. Both comments and trackbacks are closed.

22 Comments

  1. October 23, 2011 at 11:11 am | Permalink

    @Francois

    I do not know. Take a look at the response in the console using Firebug or Chrome’s developer tools. The error should be in there.

  2. Francois
    October 23, 2011 at 10:42 am | Permalink

    Hi Jen,
    Thanks for this wonderful job! After I grant access to Google, i’ve got this error:
    Error authenticating with Google.

    if (preg_match(“/Token=(.*)/”, $output, $matches))
    {
    $sessionToken = $matches[1];
    } else {
    echo “Error authenticating with Google.”;
    exit;
    }

    But my adress is : http://www.limestats.com/admin/demo/?token=1%252F2jljBrcyHlAKPv1y2nSDVmdcs_moGxR4JE6UluxAhwk

    What doesn’t work ?

    Thanks so much again!

2 Trackbacks

  1. [...] This post was mentioned on Twitter by A.Elduayen, jkang. jkang said: New Post: Google Analytics Data Export API with Google Chart Visualizations on jensbits.com: http://bit.ly/aZo4nz [...]

  2. By Gadget Newz on June 25, 2010 at 2:28 pm

    [...] Google Analytics Data Export API w/ Google Charts [...]