Home » Php » php – request Google Analytics data from a local server

php – request Google Analytics data from a local server

Posted by: admin July 12, 2020 Leave a comment

Questions:

I want to write a PHP script that imports web stats data from GA. The script is accessible through a web front end (for triggering the import) and resides on a local server (127.0.0.1).

enter image description here

As I understood from the documentation is that there are two options for authenticating and using the core API:

  1. API key – grants only access to statistics
  2. OAuth2 – full authorization

If I understand the mechanics of OAuth2 correctly then this is not an option in my scenario because I cannot specify a callback URL. Hacky solutions come to my mind – like establishing a web profile authentication directly connecting to GA from the browser and then fetching the data by JavaScript and feeding it to the import script – but I would prefer to refrain from such solutions. Also because the browser interaction triggering the import process might be substituted with a cron job in the future.

The API key seems to be exactly what I want but the GET request from the browser fails.

GET request:

https://www.googleapis.com/analytics/v3/data/ga
  ?ids=ga:[profile ID]
  &start-date=2013-01-01&end-date=2013-01-05
  &metrics=ga:visits
  &key=[the API key]

Response:

{
  error: {
  errors: [
    {
      domain: "global",
      reason: "required",
      message: "Login Required",
      locationType: "header",
      location: "Authorization"
    }
  ],
  code: 401,
  message: "Login Required"
  }
}

The URL though should be fine. Except for the key parameter it is the same as the one generated with http://ga-dev-tools.appspot.com/explorer/ which is also working (AOuth2 is used in that case). The API key is fresh.

Then again generating a new API key confronts me with the next inconveniency which is that apparently the key is only valid for a day.


So at the end of the day my question is this:

Is it possible to fetch data in the above described scenario without having to authenticate manually or generate API keys on a daily basis?

How to&Answers:

As already suggested, use this library: https://code.google.com/p/google-api-php-client/
but, instead of using oauth, create a service account from the api console (just select server application). This will provide you with a client id, an email that identify the service account, and *.p12 file holding the private key.

You then have to add the service account (the email) to your analytics as an admin user in order to get the data you need.

To use the service:

$client = new Google_Client();
$client->setApplicationName('test');

$client->setAssertionCredentials(
    new Google_AssertionCredentials(
        EMAIL,
        array('https://www.googleapis.com/auth/analytics.readonly'),
        file_get_contents(PRIVATE_KEY_FILEPATH)
    )
);
$client->setClientId(CLIENT_ID);
$client->setAccessType('offline_access');

$analytics = new Google_AnalyticsService($client);

To get some data:

$analytics->data_ga->get(PROFILE_ID, $date_from, $date_to, $metrics, $optParams)

For the details check api docs. Also, be careful, there is a query cap (unless you pay)

Answer:

I think to get this working, you need to use OAuth but with a slight modification to run it from server. Google calls this auth method “Using OAuth 2.0 for Web Server Applications

As described on that page, you can use a PHP client library to get the authentication done. The client library is located here.

An example example on how to use this client library are on the same project’s help pages. Note that you’ll have to make some modifications to the code as the comments say to store the token in db and to refresh it regularly.

<?php
require_once 'google-api-php-client/src/Google_Client.php';
require_once 'google-api-php-client/src/contrib/Google_PlusService.php';

// Set your cached access token. Remember to replace $_SESSION with a
// real database or memcached.
session_start();

$client = new Google_Client();
$client->setApplicationName('Google+ PHP Starter Application');
// Visit https://code.google.com/apis/console?api=plus to generate your
// client id, client secret, and to register your redirect uri.
$client->setClientId('insert_your_oauth2_client_id');
$client->setClientSecret('insert_your_oauth2_client_secret');
$client->setRedirectUri('insert_your_oauth2_redirect_uri');
$client->setDeveloperKey('insert_your_simple_api_key');
$plus = new Google_PlusService($client);

if (isset($_GET['code'])) {
  $client->authenticate();
  $_SESSION['token'] = $client->getAccessToken();
  $redirect = 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'];
  header('Location: ' . filter_var($redirect, FILTER_SANITIZE_URL));
}

if (isset($_SESSION['token'])) {
  $client->setAccessToken($_SESSION['token']);
}

if ($client->getAccessToken()) {
  $activities = $plus->activities->listActivities('me', 'public');
  print 'Your Activities: <pre>' . print_r($activities, true) . '</pre>';

  // We're not done yet. Remember to update the cached access token.
  // Remember to replace $_SESSION with a real database or memcached.
  $_SESSION['token'] = $client->getAccessToken();
} else {
  $authUrl = $client->createAuthUrl();
  print "<a href='$authUrl'>Connect Me!</a>";
}

Answer:

I have a similar setup. The thing that you don’t realize is that you can specify a http://localhost or http://127.0.0.1 or anything else as an origin and callback URL. You need to setup some web interface on your local server that initiates an OAuth setup for the user with the GA access. Note that this is one time. The callback handler must be something like this:

Note: The libraries used here are the same as the previous answer, the detailed code is in the wrapper.

$redirect = 'http://' . $_SERVER['HTTP_HOST'] . '/content/business-intelligence';
if (isset($_GET['code'])) {
    require_once 'GAPI.php';
    $client = GAPI::init(); //create client instance of Google_Client
    $client->authenticate(); //convert auth code to access token
    $token = $client->getAccessToken();
    $retVal = CF_GAPI::persistToken($token); //save token
    if($retVal)
        $redirect .= "?new_token";
    else
        $redirect .= "?bad_token";
}
header('Location: ' . $redirect); //redirect to bi index

Once you have saved the token saved, you must set it in the client before making requests to GA to get your analytics data. Like:

try {
    $token = GAPI::readToken(); //read from persistent storage
} catch (Exception $e) {
    $token = FALSE;
}

if($token == FALSE) {
    $logger->crit("Token not set before running cron!");
    echo "Error: Token not set before running cron!";
    exit;
}

$client = GAPI::init(); //instance of Google_Client
$client->setAccessToken($token); 

The GAPI::init() is implemented as follows:

$client = new Google_Client();
$client->setApplicationName(self::APP_NAME);

$client->setClientId(self::CLIENT_ID);
$client->setClientSecret(self::CLIENT_SECRET);
$client->setRedirectUri(self::REDIRECT_URI);
$client->setDeveloperKey(self::DEVELOPER_KEY);

//to specify that the token is stored offline
$client->setAccessType('offline');

//all results will be objects
$client->setUseObjects(true);

//tell that this app will RO from Analytics
$client->setScopes('https://www.googleapis.com/auth/analytics.readonly');

return $client;

My mysql table has columns like id, title, send_to_emails, frequency, dimensions, metrics, filters, profile_id which completely define each report to the generated from GA. You can play around with them using the documentation, list of metrics & dimensions and the sandbox tester that you already know about.