Google Search Console APIをRubyで扱う


##はじめに
SearchConsoleだと1000件までしかデータがとれないけど、API経由なら5000件まで取れるそうなので、RubyからAPI経由で取得しようとしました。公式のRubyでのサンプルがなかったので、メモしておきます。

##参考
こちらをベースに作りました。とても助かりました。
[Rails サーバから Google Analytics API で情報を取得する手順 ーー google-api-ruby-client, OAuth](http://bekkou68.hatenablog.com/entry/2014/08/20/222032)

##アカウント準備
- Google Developers Console にアクセス
- プロジェクトを作成
- APIと認証 > 認証情報 > 認証情報を追加 > サービスアカウント
P12を指定。パスフレーズが表示されて証明書ファイルがダウンロードされます。
- [APIを有効にする](https://console.developers.google.com/project/matome-tool-project/apiui/apiview/webmasters/overview)

## インストール
OAuthでAPI接続するためのライブラリをインストール

```gemfile
gem 'google-api-client'
gem 'signet'
```

## 実装

```ruby
require 'google/api_client'

  # サーチコンソールからデータを取得するクラス
  class SearchConsoleTool

    def initialize(application_name: "SearchConsoleTool", application_version: '1.0.0')
      @client = Google::APIClient.new(
      application_name: application_name,
      application_version: application_version
    )
    end

    # 秘密鍵の認証
    # @param keyfile Google認証情報のP12ファイルのパス
    # @param passphrase Googleサービスアカウントのパスワード
    def signing_key(keyfile, passphrase)
      return if @signing_key
      @signing_key = Google::APIClient::KeyUtils.load_from_pkcs12(keyfile, passphrase)
    end

    # OAuth認証
    # @param mail_address Googleサービスアカウントのメールアドレス
    # @param keyfile Google認証情報のP12ファイルのパス
    # @param passphrase Googleサービスアカウントのパスワード
    def authorize!(mail_address, keyfile, passphrase)
      @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/webmasters.readonly',
        issuer: mail_address,
        signing_key: signing_key(keyfile,passphrase)
      )
      @client.authorization.fetch_access_token!
    end

    # SearchConsole APIの取得
    def api
      @api ||= @client.discovered_api('webmasters', 'v3')
    end

    # クエリ実行
    # @param site_url 対象サイトのURL
    # @param start_date 集計開始日
    # @param end_date 集計終了日
    # @return [Array] URLごとのデータ {"keys": URL, "clicks": クリック数, "impressions": 表示数, "position": 平均掲載順位}
    def query(site_url, start_date= Date.today, end_date= Date.today)
      result = @client.execute(
        api_method: api.searchanalytics.query,
        parameters: {
          "siteUrl": site_url,
        },
        body_object:{
          "startDate": start_date.strftime("%Y-%m-%d"),
          "endDate": end_date.strftime("%Y-%m-%d"),
          "dimensions":[
            "page"
          ],
          "rowLimit": 5000
        }
      )
      return JSON.parse(result.response.body)["rows"]
    end

  end

```

5000件とれるのはいいけど、page制御がサポートされていないようで、その先はとれないorz。
全URLに対して調べたい場合は、URLのリストを作って1件ずつ調べるしかないかな。。ちなみに1日のAPI使用制限は1,000,000回

## 実行
```ruby
  site_url = "https://your-site"
  mail_address = 'your-address@developer.gserviceaccount.com'
  keyfile = "your-file.p12"
  passphrase = 'notasecret'

  tool = SearchConsoleTool.new
  tool.authorize!(mail_address,keyfile,passphrase)
  result = tool.query(site_url, Date.today-5, Date.today-5)
```
JSONで結果が出力されます

## クエリパラメータについて
queryメソッド内でしようしているbody_objectに設定できるパラメータについて。
SearchConsoleで行うようなフィルターが設定できます。
[公式ドキュメント](https://developers.google.com/webmaster-tools/v3/searchanalytics/query?hl=ja)

| パラメータ名 | データ型 | 説明 |
|:-----------|:------------:|:------------|
| startDate  |String |開始日時。"YYYY-mm-ddの形式"|
| endDate  |String |終了日時。"YYYY-mm-ddの形式"|
| dimensions|Array |検索範囲。"country"(国),"device"(デバイス),"page"(ページ),"query"(クエリ)を指定する|
| searchType|String |検索種類。"web","image","video"から指定。デフォルトは"web"|
| dimensionFilterGroups|Array|filtersとgroupTypeを掛け合わせる。filtersには検索条件を入れ、groupTypeは"and"を入れて結合条件にする
| dimensionFilterGroups[].groupType|String|"and"を指定するのみ|
| dimensionFilterGroups[].filters[]|Array|dimension, operator, expressionを掛け合わせて検索条件を表現する。(例)"query" "equals" "おすすめ"|
| dimensionFilterGroups[].filters[].dimension|String| "country"(国),"device"(デバイス),"page"(ページ),"query"(クエリ)のいずれかを指定する|
| dimensionFilterGroups[].filters[].operator|String|"contains"(含む),"equals"(一致),"notContains"(含まない),"notEquals"(不一致)をのいずれかを指定する|
| dimensionFilterGroups[].filters[].expression|String|値を指定する|

## はまった点
あまり関係ないけど、RVMを使用してたらSSLの設定ができてなくてエラーがでた

```
OpenSSL::SSL::SSLError: SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed
```
オプションをつけてrubyをインストールしなおしたらうまくいった

```
rvm install 2.2.0 --disable-binary
```

http://toadle.me/2015/04/16/fixing-failing-ssl-verification-with-rvm.html