HOWTO access the Google Analytics API with Ruby

This guide will show you how to access the Google Analytics API with Ruby, using the OAuth 2.0 flow for web applications.


Step 1: Setup your project

First you’ll need to sign in to the Google Developers Console and register your app:

You can find these pages under the “APIs & auth” menu item, and you can come back and tweak all these settings before you deploy to staging or production environments.

Step 2: Install the google-api-client gem

Add the google-api-client gem to your Gemfile:

gem 'google-api-client', '~> 0.9', require: 'google/apis/analytics_v3'

Then run bundle. The gem has a lot of dependencies, but will save you from having to write any low level HTTP client code to call the API.

Step 3: Obtain an authorization code

The first step in the OAuth 2.0 flow is to redirect the user to Google so they can sign in and consent to the access you are requesting.

If you’re using Rails your controller action might look something like this:

def redirect
  client = Signet::OAuth2::Client.new({
    client_id: ENV.fetch('GOOGLE_API_CLIENT_ID'),
    client_secret: ENV.fetch('GOOGLE_API_CLIENT_SECRET'),
    authorization_uri: 'https://accounts.google.com/o/oauth2/auth',
    scope: Google::Apis::AnalyticsV3::AUTH_ANALYTICS_READONLY,
    redirect_uri: url_for(:action => :callback)
  })

  redirect_to client.authorization_uri.to_s
end

There’s a lot going on here, so let’s go through some of the details:

Step 4: Obtain an access token

The next step in the OAuth 2.0 flow is to handle the callback and exchange the temporary authorization code for an access token. If you’re using Rails your controller action might look something like this:

def callback
  client = Signet::OAuth2::Client.new({
    client_id: ENV.fetch('GOOGLE_API_CLIENT_ID'),
    client_secret: ENV.fetch('GOOGLE_API_CLIENT_SECRET'),
    token_credential_uri: 'https://accounts.google.com/o/oauth2/token',
    redirect_uri: url_for(:action => :callback),
    code: params[:code]
  })

  response = client.fetch_access_token!

  session[:access_token] = response['access_token']

  redirect_to url_for(:action => :analytics)
end

Initialization of the client object is similar to before, and includes the temporary authorization code from the request params.

The call to #fetch_access_token! exchanges the authorization code for an access token, which is then put into the session to persist it between requests.

Step 5: Call the Google Analytics API

Now that you have an access token you can call the Google Analytics API itself–finally!

The callback action in the previous step finishes by redirecting to an analytics action, which you can implement like this:

def analytics
  client = Signet::OAuth2::Client.new(access_token: session[:access_token])

  service = Google::Apis::AnalyticsV3::AnalyticsService.new

  service.authorization = client

  @account_summaries = service.list_account_summaries
end

This time the client object is initialized with the access token from the session. The service object provides methods for making calls to the Analytics API. This example calls the Management API to get a list of the analytics properties the user has access to. The API response is assigned to an instance variable so it can be accessed from the view.

You can then add in a basic view to list the web properties and their profiles like this:

<ul>
  <% @account_summaries.items.each do |item| %>
    <li><%= item.name %> (<%= item.id %>)
      <ul>
        <% item.web_properties.each do |property| %>
          <li><%= property.name %> (<%= property.id %>)
            <ul>
              <% property.profiles.each do |profile| %>
                <li><%= profile.name %> (<%= profile.id %>)</li>
              <% end %>
            </ul>
          </li>
        <% end %>
      </ul>
    </li>
  <% end %>
</ul>

You should now be able to test the complete flow end-to-end by starting at the redirect action. If everything is configured correctly the callback action should fetch the access token and redirect to the analytics action to display a list of your properties and profiles.

Calling the Core Reporting API

Using the Management API to get the account summaries will allow you to get the ids of the profiles you’re interested in reporting on, but you’re probably more interested in getting analytics data. For this you’ll need the Core Reporting API. For example, here’s how you would query for the number of sessions by date in a given month:

profile_id = 'ga:123456'

start_date = '2015-10-01'

end_date = '2015-10-31'

metrics = 'ga:sessions'

service.get_ga_data(profile_id, start_date, end_date, metrics, {
  dimensions: 'ga:date'
})

Note that the profile id needs to be prefixed and parameters need to be strings. There are some common queries listed in the developer docs which might be useful.

Things to consider

The examples above implement the “happy path”, and don’t handle errors or exceptions which you should code for in a production ready application. Some common failure scenarios you might want to implement:

The code examples above contain some duplication in setting up the signet client. To reduce this you can either use some of the classes included in the google-api-client gem (e.g. Google::APIClient::ClientSecrets and Google::APIClient::InstalledAppFlow), or you can refactor and reorganize it as you would any other code.

You might want to consider storing the tokens in some kind of datastore instead of the session, depending on the needs of your application.