54
Help us understand the problem. What are the problem?

More than 5 years have passed since last update.

posted at

updated at

Google Spreadsheet へ Ruby を使ってアクセスする(OAuth)

Google SpreadsheetのセルをRubyで参照したり、セルに書き込む方法をメモします。

認証は OAuth を使います。Googleの id, password を使って認証する方法がググると見つかりますが、この方法は現在は非推奨となっていて、代わりに OAuth を使うことが推奨されています。

今回は以下の2個のgemを組み合わせて使いました。

準備

  1. Developers Console にログインし、プロジェクトを作成する
  2. API -> Drive API を有効にする
  3. クライアントIDを作成する
    1. アプリケーションの種類は Installed application を選択する
    2. タイプは その他 を選択
  4. 作成したクライアントIDのページにある JSONをダウンロード を押して、JSONファイルをダウンロードし、以下のコードと同じディレクトリに client_secrets.json という名前で置く

サンプルコード

Gemfile
source 'http://rubygems.org'

gem 'google-api-client', '>= 0.6'
gem 'google_drive'
.gitignore
client_secrets.json
credential-oauth2.json
sample.rb
#!/usr/bin/env ruby
#
# ref: https://github.com/google/google-api-ruby-client-samples/blob/master/drive/drive.rb
#
require 'rubygems'
require 'google/api_client'
require 'google/api_client/client_secrets'
require 'google/api_client/auth/file_storage'
require 'google/api_client/auth/installed_app'
require 'google_drive'
require 'pp'

# 認証情報のキャッシュファイル。gitリポジトリに入れない
CREDENTIAL_STORE_FILE = "credential-oauth2.json"

def setup()
  client = Google::APIClient.new(:application_name => 'Ruby spreadsheet sample',
      :application_version => '1.0.0')

  # 認証情報をファイルにキャッシュする
  # これによりaccess tokenがexpireしてもpromptが出ない
  # 注意: 複数ユーザ、複数プロセスでの利用には向かない
  file_storage = Google::APIClient::FileStorage.new(CREDENTIAL_STORE_FILE)
  if file_storage.authorization.nil?
    # client_secrets.jsonを読み込む
    # Google::APIClient::ClientSecrets.load(
    #   'config/client_secrets.json'
    # ) 
    # みたいに任意パスに置くことも可能
    client_secrets = Google::APIClient::ClientSecrets.load

    # Installed App 用のヘルパを使って認証する
    # 初回実行時のみブラウザにリダイレクトされる
    flow = Google::APIClient::InstalledAppFlow.new(
      :client_id => client_secrets.client_id,
      :client_secret => client_secrets.client_secret,
      :scope => %w(
        https://www.googleapis.com/auth/drive
        https://docs.google.com/feeds/
        https://docs.googleusercontent.com/
        https://spreadsheets.google.com/feeds/
      ),
    )
    client.authorization = flow.authorize(file_storage)
  else
    client.authorization = file_storage.authorization
  end

  return client
end

client = setup()
session = GoogleDrive.login_with_oauth(client.authorization.access_token)
ws = session.spreadsheet_by_key("YOUR_SPREADSHEET_ID_HERE").worksheets[0]

# dump a cell
pp ws[1,1] 

# update a cell
ws[5,5] = "new"
ws.save

# dump all cells
pp ws.rows

Next step

google-drive-ruby を参考にspreadsheetを操作していくことになります

ちなみに...

この背景にある個人的な目的は、cronでspreadsheetをバッチ更新したかったのです。cron(=CLIツール)でどうやって OAuth クリアするんだっけ.... ということでこうなりました。

他方、1回目の実行ではブラウザが必要です。でも実行したいのはCLIオンリーなサーバ。さてどうしたものか。自分は一度 Mac で実行し token を取得して credential-oauth2.json を対象サーバにコピーしました。

ちなみに、CLIオンリーなサーバ上で1回目実行するとCLIブラウザが立ち上がりますが、自分はうまく出来ませんでした。

いずれにせよ、コピーする方法はいいやり方でない気がします。もし他にいいやり方があれば教えていただきたいです!

参考

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Sign upLogin
54
Help us understand the problem. What are the problem?