bekkou68 の日記

Gogengo! や IT 技術など。

Rails サーバから Google Analytics API で情報を取得する手順 ーー google-api-ruby-client, OAuth

はじめに

Rails サーバから Google Analytics API をたたいて情報を取得する手順をまとめます。
google/google-api-ruby-client · GitHub を使います。ログインだと Web で認可をもとめられる(後述)ので OAuth を使います。
日にちごとのスクリーンビューを取得するスパイクをつくるのがゴールです。

OAuth に必要な鍵を修得

  • Google Analytics で使用するアカウントで Google Developers Console にアクセス
  • プロジェクトを作成
  • 作成したプロジェクトをクリック
  • APIs & Auth > Credentials を選択
  • Client ID を新規作成。Service account を選択
  • p12 をダウンロード

鍵は $RAILS_ROOT/certificates/google_analytics.p12 に配置するとします。

ライブラリをインストール

Gemfile に追加します。

gem 'google-api-client' # Google Analytics API から情報を取得するためのクライアント
gem 'signet' # OAuth 認証

インストールします。

$ bundle install

クライアントのモデルを用意

app/models/ga_client.rb を新規作成します。"EDIT" コメントの部分をてきぎ書き換えてください。

require 'google/api_client'

# Google Analytics Client
class GaClient
  def initialize(
    application_name: 'My App Google Analytics', # EDIT
    application_version: '1.0.0' # EDIT
  )
    @client = Google::APIClient.new(
      application_name: application_name,
      application_version: application_version
    )
  end

  def api
    @api ||= @client.discovered_api('analytics', 'v3')
  end

  def signing_key
    return if @signing_key

    keyfile = Rails.root.join('certificates', 'google_analytics.p12')

    # see: http://stackoverflow.com/questions/14525565/not-sufficient-permissions-google-analytics-api-service-account
    # see: http://stackoverflow.com/questions/11534438/what-is-the-google-api-password-for-the-oauth-pkcs-p12-private-key
    passphrase = 'notasecret'

    @signing_key = Google::APIClient::KeyUtils.load_from_pkcs12(keyfile, passphrase)
  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: 'xxxx@developer.gserviceaccount.com', # EDIT
      signing_key: signing_key
    )
    @client.authorization.fetch_access_token!
  end

  def daily_screen_view(date:, screen_name:)
    # 管理画面の Admin > VIEW > View Settings に記載されている View ID を指定
    ga_id = 'ga:XXX' # EDIT

    result = @client.execute(
      api_method: api.data.ga.get,
      parameters: {
        ids: ga_id,
        'start-date' => date.to_s,
        'end-date' => date.to_s,
        metrics: 'ga:screenviews',
        filters: "ga:screenName==#{screen_name}",
        dimensions: 'ga:date',
      }
    )
    body = JSON.parse(result.response.body)
    date, screen_view = body['rows'].first
    screen_view
  end
end

クライアントを使って情報を取得

呼び出し側を実装します。「マイページ」というスクリーン名のスクリーンビューを取得します。

client = GaClient.new
client.authorize!
puts client.daily_screen_view(date: Date.today, screen_name: 'マイページ') #=> 1024

今日のスクリーンビューは 1024 だとわかりました!

紆余曲折

情報を取得するまでにいろいろと試行錯誤しました。そのログを残します。

  • Sija/garb · GitHub を見つける
  • ログイン(メールアドレスとパスワードで認証)でやってみよう
  • ローカルで動いた。サーバにデプロイして確認してみよう。おや……動かないぞ……
  • "Error=BadAuthentication Info=WebLoginRequired" とエラーを吐いていた。Webログインが必要……!?
  • 普段つかわない端末からアクセスしたら Google が不審なアクティビティとしてはじくようだ
  • 端末から https://accounts.google.com/displayunlockcaptcha にアクセスして認可すればいいらしい
  • とはいえサーバから Webブラウザは立ちあげられない
  • いろいろ試す
  • ひとまずログインでなく OAuth でやってみよう。長時間かかっても解決しなさそうだったらサーバに proxy を立てて Web認証かな……(やりたくない)
  • garb だと OAuth つかうのしんどそうだった。Web を一度介さないとアクセストークンを取得するのができなさそう
  • 他にやりかたないかな。omniauth はしんどそうだなあ
  • PHP にはクライアントあるのかRuby にもないかな
  • あった!

記事のはじめに戻ります。