Upgrading google-api-ruby-client from 0.8.x to 0.9 will probably break a lot of your code. Officially, there is a migration guide, but it does not give you much clue of how to pull Google Analytics stats via the API, neither does the documentation in Google developer platform.
The post is to focus on the integration with Google Analytics' Core Reporting API and authorisation with Ruby (on Rails) from server side. So the use case is, any user comes to authorise your application to access the data in his/her Google Analytics account, and then your server can pull the latest data at any time without a second time authorisation from the user.
Before typing any code, please make sure you have got
client_secret. If you don't have them like
X1NUhvO-rQr9sm8uUSMY8i7v respectively, please follow the Step 1 in Google Developers Guide, where the rest of steps are not for Ruby.
Google API's authorisation suggests Signet to do OAuth2. That means there are two rounds of API communication, to get an authorisation code by
client_secret, and then use the code to exchange for an access token.
Because we need to initialize
Signet::OAuth2::Client for many times, I prefer to create another ruby class as a wrapper of it, such as a
google_api.rb file (in your
/lib folder if using rails).
#google_api.rb require 'google/apis/analytics_v3' class GoogleAPI GOOGLE_API_CLIENT_ID = '44410190108-74nkm6jc5e3vvjqis803frkvmu88cu3a.apps.googleusercontent.com' GOOGLE_API_CLIENT_SECRET = 'X1NUhvO-rQr9sm8uUSMY8i7v' GOOGLE_OAUTH2_URL = 'https://accounts.google.com/o/oauth2/auth' GOOGLE_ACCESS_TOKEN_URL = 'https://www.googleapis.com/oauth2/v3/token' GOOGLE_CALLBACK_URL = 'http://yourhost/google/callback' #the url that Google will send authorisation codes to attr_accessor :client def initialize @client = Signet::OAuth2::Client.new( client_id: GOOGLE_API_CLIENT_ID, client_secret: GOOGLE_API_CLIENT_SECRET, authorization_uri: GOOGLE_OAUTH2_URL, scope: Google::Apis::AnalyticsV3::AUTH_ANALYTICS_READONLY, token_credential_uri: GOOGLE_ACCESS_TOKEN_URL, redirect_uri: GOOGLE_CALLBACK_URL ) end end
Then to handle the request from users, just redirect to Google's authorisation uri in your controller.
#google_api.rb class GoogleAPI ... def authorization_uri @client.authorization_uri.to_s end ... end #google_controller.rb class GoogleController < ApplicationController def authorise redirect_to GoogleAPI.new.authorization_uri end end
After users click through the authorisation steps, Google will send you authorisation codes, with which you can request access tokens. The access token is ready for fetching API data, but it expires in
3600 seconds. If just going to render some remote data to the user immediately and only once, you can skip the following parts about
Otherwise, for any offline access you have to use
refresh token that only returns at the first time requesting for access tokens. If you miss it, revoking the authorisation from the Google account will reset.
#google_api.rb class GoogleAPI ... def init_refresh_token(authorization_code) @client.update!(code: authorization_code) # @client.fetch_access_token!['access_token'] gives you the access token @client.fetch_access_token!['refresh_token'] end ... end #google_controller.rb class GoogleController < ApplicationController ... def google_callback if params[:code] refresh_token = GoogleAPI.new.init_refresh_token(params[:code]) #store the refresh token in database for later access from server end end ... end
Before real playing, do not forget reauthorisation to exchange a fresh access token with the stored refresh token (don't store access token!) from your server job (not triggered by users).
#google_api.rb class GoogleAPI ... def reauthorize!(refresh_token) @client.update!(refresh_token: refresh_token, grant_type: :refresh_token) access_token = @client.fetch_access_token!['access_token'] @client.update!(access_token: access_token) end def init_service(refresh_token) self.reauthorize!(refresh_token) service = Google::Apis::AnalyticsV3::AnalyticsService.new service.authorization = @client service end ... end #in your server job service = GoogleAPI.new.init_service(refresh_token) #refresh_token from your database account_summaries = service.list_account_summaries
Yes, it's as simply as this and none of the steps are complicated above. But nowhere I could find to gather all the them together. Probably because Google does not take Ruby as one of the major programming languages that will consume its API, as the usage for Java is way clearer.
Thanks to the blog that helped me more than any of Google's documentation or guide (if you still believe they really does), but just misses the offline access part.
I have not been to any difficulties in requesting the analytic data part, so leaving the Play! short and simple. Trust me, going through the source code of
google-api-client is way way more effective than searching from Google's documentation to call the right endpoint.
Version: ruby 2.3.0 rails 4.2.5 google-api-client 0.9