A Complete Example of Using Google Analytics Reporting API V4 in PHP to Get Custom Report

In the Google Analytics web console, user can create custom reports by specifying dimensions and metrics. There are many reasons you may want to use the Google Analytics Reporting API to programmatically create custom reports. For example,

  1. There are too many entries in the generated custom reports. The web console allows you to select only 5000 rows at a time and export.
  2. You want to combine more dimensions in a report. The web console allows you to add at most 5 dimensions, while the API allows 7.
  3. You want to automate the data exporting process. Say you would like to have a report automatically generated every day and stores in your database.

This example supposes that you have the following prepared:

  1. Knowledge about Google Analytics custom report, dimensions, metrics, etc.
  2. Have the Google API client library installed. If not, please refer to this document.
  3. Set up OAuth 2.0 for authorization. If not, please refer to my previous post.

After you complete step 2 and 3, you should be able to create a service object with the following code.

require_once 'vendor/autoload.php';
$key = PATH_TO_YOUR_JSON_FILE;

/* create the client object */
$client = new Google_Client();

/* use the service account for authorization */
putenv('GOOGLE_APPLICATION_CREDENTIALS=' . $key);
$client->useApplicationDefaultCredentials();
$client->addScope(Google_Service_Analytics::ANALYTICS_READONLY);

/* create the service object */
$analytics = new Google_Service_AnalyticsReporting($client);

Before proceeding, you need to consider the following parameters for the report:

  1. Google Analytics View ID, which you can find in the web console: Admin -> View Settings -> View ID.
  2. Start date & end date of your report.
  3. Dimensions & metrics, which you can find the name through the explorer.
  4. Filters: you might want to filter out some values of certain dimensions.
  5. How would you like the report to be ordered.
  6. Page size: report can be paginated, i.e. how many entries you want to get in each request.

To be clear and flexible, we set all the parameters in an array and wrap the process of getting the report in a function that takes the parameter array. Suppose you want to get insight of the session duration per city per operating system, the following script will guide you through the steps.

  1. Set up parameters and pass it to the function we are going to call together with the $analytics object that we created previously.
  2. $param = array('view_id'    => YOUR_VIEW_ID,
                   'startDate'  => YOUR_START_DATE,
                   'endDate'    => YOUR_END_DATE,
                   'dimensions' => array('ga:cityId' => 'city_id',
                                         'ga:operatingSystem' => 'os),
                   'metrics'    => array('ga:sessionDuration' => 'session_duration'),
                   'orderField' => 'ga:cityId',
                   'orderType'  => 'DESCENDING',
                   'pageSize'   => 500);
    
    $report = getReport($analytics, $param);
    
  3. The main function that calls the API.
  4. function getReport($analytics, $param) {
        /* set view_id - required */
        if (isset($param['view_id'] ))
             $view_id = $param['view_id'];
        else {
            echo 'Error: Google Analytics View ID must be set';
            return;
        }
    
        /* set date -required */
        $dateRange = new Google_Service_AnalyticsReporting_DateRange();
        if (isset($param['startDate']) && isset($param['endDate'])) {
            $dateRange->setStartDate($param['startDate']);
            $dateRange->setEndDate($param['endDate']);
        }
        else {
            echo 'Error: Google Analytics date range must be set';
            return;
        }
    
        /* Set dimensions - required */
        if (!isset($param['dimensions']) || empty ($param['dimensions'])) {
            echo 'Error: No dimensions have been set';
            return;
        }
        else {
            $dimensions = array();
            $dimension_names = array();
            foreach ($param['dimensions'] as $k => $v) {
                $dimension = new Google_Service_AnalyticsReporting_Dimension();
                $dimension->setName($k);
                $dimensions[] = $dimension;
                $dimension_names[] = $v;
            }
        }
    
        /* set metrics - required */
        if (!isset($param['metrics']) || empty ($param['metrics'])) {
            echo 'Error: No metrics have been set';
            return;
        }
        else {
            $metrics = array();
            $metric_names = array();
            foreach ($param['metrics'] as $k => $v) {
                $metric = new Google_Service_AnalyticsReporting_Metric();
                $metric->setExpression($k);
                $metric->setAlias($v);
                $metrics[] = $metric;
                $metric_names[] = $v;
            }
        }
    
        /* set dimension filter - optional */
        if (isset($param['dimFilter']) && isset($param['dimFilter']['dimensionName']) && isset($param['dimFilter']['operator']) && isset($param['dimFilter']['expression'])) {
            $filter = new Google_Service_AnalyticsReporting_DimensionFilter();
            $filter->setDimensionName($param['dimFilter']['dimensionName']);
            $filter->setOperator($param['dimFilter']['operator']);
            $filter->setExpressions($param['dimFilter']['expression']);
            if (isset($param['dimFilter']['exclude'] ))
                $filter->setNot($param['dimFilter']['exclude']);
            $filter_clause = new Google_Service_AnalyticsReporting_DimensionFilterClause();
            $filter_clause->setFilters($filter);
        }
    
        /* set order by - optional */
        if (isset($param['orderField'])) {
            $orderby = new Google_Service_AnalyticsReporting_OrderBy();
            $orderby->setFieldName($param['orderField']);
            if (isset( $param['orderType']))
                $orderby->setSortOrder($param['orderType']);
         }
    
    
    
    
        /* Create the ReportRequest object */
        $request = new Google_Service_AnalyticsReporting_ReportRequest();
        $request->setViewId($view_id);
        $request->setDateRanges($dateRange);
        $request->setDimensions($dimensions);
        $request->setMetrics($metrics);
        if (isset($orderby))
            $request->setOrderBys($orderby);
        if (isset($filter_clause))
             $request->setDimensionFilterClauses($filter_clause);
        if (isset($param['pageSize']))
            $request->setPageSize($param['pageSize']);
    
    
    
        /* set the request body */
        $body = new Google_Service_AnalyticsReporting_GetReportsRequest();
    
    
    
    
        /* iterate to call the API and store the response data, 500 a time */
        $pageToken;
        $report = array();
         do {
             /* fire the request */
             $body->setReportRequests(array($request));
             $response = $analytics->reports->batchGet($body);
    
             /* get rows from the response */
             $rows = getRows($response, $report, $dimension_names);
    
             /* merge rows into the report */
             $report = array_merge($report, $rows);
    
             /* set next page token to get the next 500 rows */
             $pageToken = $response[0]->getNextPageToken();
             $request->setPageToken($pageToken);
    
         } while ( $pageToken != null );
    
    
         return $report;
    }
    
  5. The function that renders the response that we get from Google. Returns the result in an array consisting of rows of the report.
  6. function getRows($response, $dimension_names) {
        /* get dimension headers and metric headers from the API response */
        for ($i = 0; $i < count($response); $i++) {
            $header = $response[$i]->getColumnHeader();
            $dimensionHeaders = $header->getDimensions();
            $metricHeaders = $header->getMetricHeader()->getMetricHeaderEntries();
            $rows = $response[$i]->getData()->getRows();
    
            /* iterate row by row */
            $report_rows = array();
            for ( $rowIndex = 0; $rowIndex < count($rows); $rowIndex++) {
                $row = $rows[$rowIndex];
                $dimensions = $row->getDimensions();
                $metrics = $row->getMetrics();
                $result_row = array();
    
                /* get dimension data */
                for ($i = 0; $i < count($dimensionHeaders) && $i < count($dimensions); $i++) {
                   $result_row[$dimension_names[$i]] = $dimensions[$i];
                }
    
                /* get metric data */
                for ($i = 0; $i < count($metricHeaders); $i++) {
                    $result_row[$metricHeaders[$i]->getName()] = $metrics[0]->getValues()[$i];
                }
    
                /* add the row to the report */
                $report_rows[] = $result_row;
            }
        }
        return $report_rows;
    }
    

The code above covers almost the essential usage of Google Analytics Reporting API with PHP Client Library in order to get a custom report. After running the script, you should be able to get the report stored in the array $report. Then, you are able to analyze the report or store it into the database of your choice.

However, in the case that you are dealing with big data here, say your report has millions of entries, storing it in an array will definitely exhaust the memory. The good way to deal with it is to stream the report into your database. By ‘stream’ I mean that we transfer the data into database in each iteration of API call (500 rows each iteration in the example). I’ll address the streaming process using BigQuery in the following post.

Thanks for reading : )

Reference:

  1. https://github.com/google/google-api-php-client
  2. https://developers.google.com/analytics/devguides/reporting/core/v4/quickstart/service-php
  3. https://developers.google.com/analytics/devguides/reporting/core/dimsmets

 

 

2 thoughts on “A Complete Example of Using Google Analytics Reporting API V4 in PHP to Get Custom Report

  1. Joe Vallender September 27, 2016 / 8:46 pm

    Hey, just wanted to say thanks for this. It’s not obvious from the documentation how to iterate the paginated the results, so your post saved me some time! 🙂

    Like

    • Xiaoxin Lufei September 28, 2016 / 9:16 am

      It took me some time to figure it out, too. I’m really glad that you find it helps!

      Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s