最近Webのバックエンドを任されて開発をしているのですが、自身のサービスを世に出す時にアクセス統計情報を解析したいという話になった。そこで、Googleが提供しているAnalytics APIを使ってアクセス統計情報を扱おうということになったので、Ruby on railsにて実装しようとしたが、ハマってしまったお話。
認証がOAuth2.0に変更
いつからかはわからないが(おそらくは2016年あたり)、googleのAPIサービス全般の認証システムに変更があったらしい。OAuth2.0というらしいが、以前の認証が使えなくなっていたので、過去の参考記事がほとんど意味をなさない状態だった。
gemも更新されていて・・・
Ruby on railsでgoogle Analytics APIを実装するにあたって、gemをインストールするのが一般的だ。例によって
gem 'google-api-client' gem 'signet'
をインストールしてAPIを叩こうとしたところ、cannot load such file — google/api_clientというエラーになってしまった。
どうやらapi_clientというのは使えなくなって、今はapis/analyticsreporting_v4など、requireするファイルを明示的に示さなければいけなくなったとのこと。
google developer consoleもアップデート
一番困ったのはここかもしれない。google developer consoleからAPIを使うためクライアントIDを取得し有効にしたりするのだが、これが過去のUIから変更があったらしく、結構手こずった。プロジェクトを作成し、使いたいAPIを有効にした後、サービスアカウントを作成するという順序で正解だった。ViewIDやアナリティクスでアカウントメールアドレスを登録する手順は以前と同じだったので問題ないだろう。
対策としては
今回私はgemを古いもののバージョンにして対応した。こうすることで、requireのエラーも出なくなり、正常にAPIが動作した。一応コードを以下に示すので参考になるといいと思う。
・Gem file
gem 'google-api-client','0.8.2', require: 'google/api_client' gem 'signet'
・api.rb
require 'google/api_client' class GoogleApi API_VERSION = 'v3' CACHED_API_FILE = "# #適宜変更/analytics-#{API_VERSION}.cache" SERVICE_ACCOUNT_EMAIL = ' #適宜変更.iam.gserviceaccount.com' KEY_FILE = "# #適宜変更.p12" KEY_SECRET = 'notasecret' VIEW_ID = '#適宜変更' def initialize @client = Google::APIClient.new( application_name: 'hackman', application_name: '1.0' ) end # Cache api file to avoide round-trip def api analytics = nil if File.exists? CACHED_API_FILE File.open(CACHED_API_FILE) do |file| analytics = Marshal.load(file) end else analytics = @client.discovered_api('analytics', API_VERSION) File.open(CACHED_API_FILE, 'w') do |file| Marshal.dump(analytics, file) end end analytics end def signing_key return if @signing_key @signing_key = Google::APIClient::KeyUtils.load_from_pkcs12(KEY_FILE, KEY_SECRET) end def authorize! @client.authorization = Signet::OAuth2::Client.new( token_credential_uri: 'https://accounts.google.com/o/oauth2/token', audience: 'https://accounts.google.com/o/oauth2/token', scope: 'https://www.googleapis.com/auth/analytics.readonly', issuer: SERVICE_ACCOUNT_EMAIL, signing_key: signing_key ) @client.authorization.fetch_access_token! end def get_data(options = {}) @client.execute( api_method: api.data.ga.get, parameters: { "ids" => "ga:#{VIEW_ID}", "start-date" => "today", "end-date" => "today", "metrics" => "ga:pageviews", "dimensions" => "ga:year,ga:month,ga:day", "sort" => "ga:year,ga:month,ga:day" } ) end end