Rails / Google Analyticsのデータを使って分析や管理画面のためのグラフをつくる

Shunsuke Sawada

ウェブサービスを運営すると「もっとたくさんの人に使ってもらいたい!」ともちろん思う訳ですが、サービスのどこを改善すればいいのか勘で決めてしまうわけにはいかない… ってことで、分析する時に便利なグラフ化のメモ。
  

海外に行く人専用のブログサービスCANPATHが題材です。
こんなグラフつくります。
Screen Shot 2014-10-05 at 2.41.25 PM

欲しいのは次のデータとします。

Google Analytics クライアント

これ使います。
google-api-ruby-client
OAuth認証のためにsignetというGemも使います。

1
2
3
#Gemfile
gem 'google-api-client'
gem 'signet'

下準備

もちろんGoogle Analyticsのアカウントは必須。

Developers ConsoleでOAuth用の鍵を取得。
Developers Consoleで新規プロジェクトを作ったら、APIsにいって「Analytics API」をONにする。
Screen Shot 2014-10-05 at 3.06.00 PM
  
Credentials / Create new Client ID / Service account とクリックするとP12keyがダウンロードできます。P12keyはアプリ直下に新しいディレクトリをつくって保存しました。
こんな感じ ↓
Railsルート/certificate/xxxxxxxxxxx.p12
  
Service Accountの詳細にEMAIL ADDRESSがあるので、それをGoogle Analyticsの管理者として登録してください。これしないとエラーになるのでちょっとハマった。
Screen Shot 2014-10-05 at 3.42.11 PM

データ取得用のクラス

どこでもいいと思いますが、とくにデータベースとも結びつかないので lib/ga_api.rb というファイルをつくりました。

ruby
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#lib/ga_api.rb 

require 'google/api_client'

class GaApi

    KEY_FILE = "#{Rails.root}/certificate/xxxxxxxxxxx.p12"
    ACCOUNT_EMAIL = "[email protected]"
    KEY_SECRET = "xxxxxxxxxxx"
    VIEW_ID = "xxxxxxxxxxx"
    VERSION = "v3"
    CACHED_API_FILE = "#{Rails.root}/certificate/analytics-#{VERSION}.cache"

    def initialize
        @client = Google::APIClient.new(
            application_name: 'xxxxxxxxxxx',
            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', 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: 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" => options[:start_date].to_s,
        "end-date" => options[:end_date].to_s,
        "metrics" => options[:metrics],
        "dimensions" => "ga:year,ga:month,ga:day",
        "sort" => "ga:year,ga:month,ga:day"
      }
    )
    end

end

KEY_FILE
Developer Consoleで取得したファイルの保存場所
ACCOUNT_EMAIL
Developer Consoleで取得したEメールアドレス
KEY_SECRET
Developer Consoleでkeyを作成すると一回だけ表示されます
VIEW_ID
下の画像参考
VERSION
APIのバージョン。Googleはv3使えといってます。`
CACHED_API_FILE
キャッシュファイルの保存場所(certificateの中に入れているのが気持ち悪いですが、どこでもいいと思うので適宜変えてください。)
  
VIEW_IDはanalyticsの管理画面から知る事ができます。下の画像のようなやつです。
Screen Shot 2014-10-05 at 3.41.48 PM

データ整形

管理用としてadmins_controller.rbがあると想定します。

ruby
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
require 'ga_client'

class AdminsController < ApplicationController
  def show
    api = GaApi.new
    api.authorize!
    analytics = api.get_data(
      start_data: 1.month.ago(Date.today),
      end_data: Date.today,
      metrics: "ga:newUsers"
    )
    analytics  = JSON.parse(analytics.response.body)
  end
end

なんてすると、analytics["row"]のなかにデータが入ってます。
metricsのリストはココにあるので、いろいろ試すといろいろデータが取得できます。ひとつしか指定してませんが、カンマくぎりで複数まとめて取得することも可能。

上の例で、analyticsには、

["2014", "10", "05", "123"]
["2014", "10", "06", "456"]
["2014", "10", "07", "352"]

なんてデータが入ってるので、あとは好きなように整形する。
今回はChartkickというGemを使いたいので、それように整形しました。

こんな感じ ↓

ruby
1
2
3
4
5
6
@new_visitor = 

{ "2014-10-05" => 1234 }
{ "2014-10-06" => 1234 }
{ "2014-10-07" => 1234 }

  
会員登録数とかはDBから直接とって整形。
登録が無い日があると、その日のデータ自体が入らず困るので0を挿入してます。

ruby
1
2
3
4
5
6
7
8
9
start_date = 1.month.ago(Date.today)
end_date = Date.today
@new_signup = User.where(created_at: [start_date..end_date]).group("DATE(created_at)").count

start_date.upto(end_date).each do |date|
    @new_signup[date] = 0 unless @new_signup.has_key?(date)
end
@new_signup = @new_signup.map { |key, val| [key.strftime('%Y-%m-%d'), val] }
@new_signup.sort!

  
こちらもこんな感じのデータになればいいと思います。 ↓

ruby
1
2
3
4
5
6
@new_signup = 

{ "2014-10-05" => 123 }
{ "2014-10-06" => 123 }
{ "2014-10-07" => 123 }

表示

Chartkick 使います。

1
gem "chartkick"

これはめちゃくちゃ簡単。
ちゃんとデータが整形されていれば渡してあげるだけ。べんりー。

erb
1
2
3
4
5
6
7
8
9
<%= javascript_include_tag "//www.google.com/jsapi", "chartkick" %>

<%= line_chart [
    { name: "新規に訪れた", data: @new_visit },
    { name: "登録した", data: @new_signup },
    { name: "自分史を作った", data: @has_timeline },
    { name: "ストーリーを書いた", data: @has_story }
    ]
%>

以上です。
パーセントとかは単純に計算すればいいだけなので省略。
データ分析だけでなく、ユーザーの管理画面とかにも良さそうですね。

今回は使わなかったけど、Railscastにもチャートの作り方がいくつかあるようです。
#223 Charts & Graphs (revised) - RailsCasts
#378 FnordMetric - RailsCasts
#223 Charts - RailsCasts

参考

google-api-ruby-client
google-api-ruby-client-samples/service_account at master · google/google-api-ruby-client-samples
google/signet
Chartkick
Dimensions & Metrics Reference - Google Analytics — Google Developers
Railsプロジェクトでグラフ描画ライブラリChartkickを使用する手順
Rails サーバから Google Analytics API で情報を取得する手順 ーー google-api-ruby-client, OAuth - bekkou68の日記
ruby on rails - Getting count of elements by created_at by day in a given month - Stack Overflow
ruby on rails 3 - Grouping created_at by date only? - Stack Overflow

435
Shunsuke Sawada

おすすめの記事

カウチサーフィンの評判と実際と日本との差
14
GithubにRailsのWordpressっぽいブログアプリを公開しました。
43
Rails / Google Analytics が動きを止めた & なぜかURLが正常に取得できない
11