google-api-clientを使ってRailsのDBのデータをスプレッドシートに出力してみた

こんにちは!kossyです!



さて、今回は、スプレッドシートを操作できるGem「google-api-client」を使って、
RailsのDBのデータをスプレッドシートに出力する方法について
ブログに残してみたいと思います。





google-api-clientの設定
スプレッドシートを操作するためのgemである
google-api-clientをインストールし、諸々の設定を説明します。


まずはGemファイルに追記しbundle installします。

/.gemfile

gem 'google-api-client'


$ bundle install


次にgoogleAPI ruby quickstartページにアクセスし、大まかな流れをマニュアル通りに進めます。
developers.google.com



まずは下のボタンを押して、Google Sheets APIを有効にします。
f:id:kossy-web-engineer:20190831175304p:plain



すると、
f:id:kossy-web-engineer:20190831175418p:plain
プロジェクト名とサービスおよび関連するAPIの使用を利用規約に準拠することに同意を求められるので、プロジェクト名を決め、yesにします。
有効化に成功すると、


f:id:kossy-web-engineer:20190831175643p:plain
認証情報をダウンロードできるようになるので、ダウンロードし、
Railsプロジェクトのconfig直下にでも置いておきます。



この時、gitignoreすることを忘れないで下さい。

.gitignore

config/credentials.json

次に、Step3のコードを参考にしてlib/google_api_client.rbファイルを作成します。

lib/google_api_client.rb


# 必須モジュールの宣言
require 'google/apis/sheets_v4'
require 'googleauth'
require 'googleauth/stores/file_token_store'

# 何かと便利なのでクラスにしています。
class GoogleApiClient
  OOB_URI = 'urn:ietf:wg:oauth:2.0:oob'.freeze
  APPLICATION_NAME = 'Your App Name'.freeze
  CREDENTIALS_PATH = Rails.root + 'config/google_drive_credentials.json'.freeze
  # 最初にタスクを実行する時に自動で作成されます。
  TOKEN_PATH = Pathname.new Rails.root + 'config/google_drive_token.yaml'.freeze
  SCOPE = Google::Apis::SheetsV4::AUTH_SPREADSHEETS

  # インスタンスが作成された時に実行
  def initialize
    @service = Google::Apis::SheetsV4::SheetsService.new
    @service.client_options.application_name = APPLICATION_NAME
    @service.authorization = authorize
  end

  def authorize
    client_id = Google::Auth::ClientId.from_file CREDENTIALS_PATH
    token_store = Google::Auth::Stores::FileTokenStore.new file: TOKEN_PATH
    authorizer = Google::Auth::UserAuthorizer.new client_id, SCOPE, token_store
    user_id = 'default'
    credentials = authorizer.get_credentials user_id
    if credentials.nil?
      url = authorizer.get_authorization_url(base_url: OOB_URI)
      puts 'Open the following URL in the browser and enter the ' \
           "resulting code after authorization:\n" + url
      code = gets
      credentials = authorizer.get_and_store_credentials_from_code(
        user_id: user_id, code: code, base_url: OOB_URI
      )
    end
    credentials
  end

  # スプレッドシートのアップデート用メソッド
  def update_sheets(data, spreadsheet_id:, sheet_name: nil)
    value_range = Google::Apis::SheetsV4::ValueRange.new
    value_range.range = "#{sheet_name}!A1:ZZ"
    value_range.values = data
    @service.clear_values spreadsheet_id, value_range.range
    @service.update_spreadsheet_value spreadsheet_id, value_range.range, value_range, value_input_option: 'USER_ENTERED'
  end
end

Railsではlib下のファイルはapplication.rbに変更を加えないと、自動で読み込んでくれないので、config/application.rbに以下の設定を追加します。

config/application.rb

もろもろ省略
module App
  class Application < Rails::Application

    config.paths.add 'lib', eager_load: true <= 追加
  end
end

次に、新しいスプレッドシートを作成して、スプレッドシートのIDを控えておきます。
IDはURLの/d/の後に続く数字とアルファベットが混在した部分までです。

このスプレッドシートのIDを、

$ EDITOR="vim" rails credentials:edit

環境変数として登録します。

spread_sheet_id: <your spreadsheetid>

次に、lib/spread_sheet_task.rbというファイルを作成します。このファイルに、実際にcronジョブに実行してもらうことを書き込んでいきます。

lib/spread_sheet_task.rb

Module SpreadSheetTask

def self.sample_task
  # Memberモデルがあることを想定しています。以下は例です。

    data = [['背番号', 'ユーザー名', '氏名', 'メールアドレス', '誕生日', '性別', '出身地']]
    Member.all.each do |member|
      data << [
        member.number,
        member.name,
        member.full_name,
        member.email,
        member.birthday,
        member.show_sex,
        member.prefecture.name
      ]
    end
  # スプレッドシートのアップデート用メソッドを呼び出す。IDは環境変数で設定した値を使う。sheet_nameでシートの名前を設定できる。
    GoogleApiClient.new.update_sheets data, spreadsheet_id: "#{Rails.application.credentials.dig(:spread_sheet_id)}", sheet_name: 'メンバー一覧'
end

これで、まずはrails c をしてコンソールから実行してみます。

$ rails c

$ SpreadSheetTask.sample_task

すると、

Open the following URL in the browser and enter the resulting code after authorization:
https://accounts.google.com~~~

と表示されるので、表示されたURLにアクセスします。

アクセスすると、ログインを要求されるので、アカウント選択しログインします。
f:id:kossy-web-engineer:20190831191101p:plain

ログインすると、
f:id:kossy-web-engineer:20190831191138p:plain
この画面が表示されるので、左下の「詳細」をクリックし、「Quickstart(安全ではないページ)に移動」をクリックします。

その後、
f:id:kossy-web-engineer:20190831191304p:plain
この画面に遷移するので、「許可」をクリックします。

クリック後、
f:id:kossy-web-engineer:20190831191351p:plain
選択内容を確認してくださいという画面が表示されるので、これも「許可」をクリックします。

トークンが発行されるので、そのトークンをコピーして、コマンドラインにペーストして、enterキーを押します。
その後、スプレッドシートに値が吐き出され、config/google_drive_token.yamlというファイルが作成されます。

このファイルはgitignoreするのを忘れないようにしましょう。

./.gitignore

/config/google_drive_token.yaml

今回はローカル環境のDBのデータを吐き出しましたが、本番環境での吐き出し方も
後々ブログに残してみたいと思います。



参考にさせていただいたサイト
Ruby quickstart  |  Sheets API  |  Google Developers