29
34

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

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

Posted at

ブログ更新
http://www.workabroad.jp/posts/2114/edit

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

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

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

  • 新規に訪れた人
  • 登録した人
  • 自分史(ブログ)を作った人
  • ストーリー(記事)を書いた人

  

###Google Analytics クライアント

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

#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 というファイルをつくりました。


#lib/ga_api.rb 

require 'google/api_client'

class GaApi

	KEY_FILE = "#{Rails.root}/certificate/xxxxxxxxxxx.p12"
	ACCOUNT_EMAIL = "xxxxxxxxxxx@developer.gserviceaccount.com"
	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があると想定します。

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を使いたいので、それように整形しました。

こんな感じ ↓

@new_visitor = 

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

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

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!

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

@new_signup = 

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

  

###表示

Chartkick 使います。

gem "chartkick"

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

<%= 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

29
34
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
29
34

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?