Google Drive(docs)からrubyでファイル一覧を取得する方法メモ。
Google Drive(docs)からrubyでファイル一覧を取得する方法
全体的にけっこうややこしいです。大雑把に以下の手順が必要です。
- Google APIのページでGoogle Drive APIを許可する
- client_secrets.jsonをダウンロードする
- rubyコードを実行する
順に説明していきます。
Google APIのページでGoogle Drive APIを許可する
Google APIのページはこちらです。
一応やるべきことは全部このREADMEに書いてあります。
github/google/google-api-ruby-client-samples
上記の資料は英語ですし情報がやや古いですが、この後ばんばん英語の情報がでてくるので上記の資料は頑張って読み解きましょう。
Google APIのページでやることは主に下記の通りです。
- APIs & auth > APIsからGoogle Drive APIをONにする(Google Drive SDKは不要)
- 自分のアプリケーションに名前を付ける(後述)
- client_secrets.jsonをダウンロードする(後述)
Google APIのページからclient_secrets.jsonをダウンロードする
この手順も上記の英語の資料に書いてあります。「APIs & auth > Credentials > CREATE NEW CLIENT ID」からClient IDを作成すると、client_secrets.jsonをダウンロードするリンクが表示されます。
途中、Application TypeはInstalled Application、Installed Application TypeはOtherを選んでください。
さらにこの後、「APIs & auth > Consent screen」からProduct Nameを何か適当な値にしておくのを忘れないようにしましょう。これをしてないと後でエラーになります。
rubyコードを実行する
gemはgoogle-api-ruby-clientを使うのが現状ベストっぽいです。
google-api-ruby-clientの作者(google)が、Google Driveにファイルを新規にアップロードするサンプルを公開してくれています。
github google-api-ruby-client-samples drive.rb
ただし上記のサンプルコードだけではバグが残っています。そのバグを手直しして、ファイル新規アップロードではなく、特定のフォルダのファイル一覧を取得するコードは下記の通りです。
# -*- coding: utf-8 -*- 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 'logger' API_VERSION = 'v2' CACHED_API_FILE = "drive-#{API_VERSION}.cache" CREDENTIAL_STORE_FILE = "#{$0}-oauth2.json" # gemにバグがあるらしく、暫定的なコードとしてこの変換がおすすめされている。 # この処理がないと、refresh_tokenを使ったtoken再取得に失敗する。 # https://github.com/google/google-api-ruby-client/issues/90 def file_format_bug_fix(credential_store_file) return if !File.exists?(credential_store_file) temp = nil File.open(credential_store_file, "r") do |f| temp = JSON.load(f) if temp["authorization_uri"].class != String temp["authorization_uri"] = "https://accounts.google.com/o/oauth2/auth" end if temp["token_credential_uri"].class != String temp["token_credential_uri"] = "https://accounts.google.com/o/oauth2/token" end end File.open(credential_store_file, "w") do |f| f.write(temp.to_json) end end def setup() log_file = File.open('log/drive.log', 'a+') log_file.sync = true logger = Logger.new(log_file) logger.level = Logger::DEBUG client = Google::APIClient.new(:application_name => 'Ruby Drive sample', :application_version => '1.0.0') file_storage = Google::APIClient::FileStorage.new(CREDENTIAL_STORE_FILE) if file_storage.authorization.nil? client_secrets = Google::APIClient::ClientSecrets.load flow = Google::APIClient::InstalledAppFlow.new( :client_id => client_secrets.client_id, :client_secret => client_secrets.client_secret, :scope => ['https://www.googleapis.com/auth/drive'] ) client.authorization = flow.authorize(file_storage) else client.authorization = file_storage.authorization end drive = nil if File.exists? CACHED_API_FILE File.open(CACHED_API_FILE) do |file| drive = Marshal.load(file) end else drive = client.discovered_api('drive', API_VERSION) File.open(CACHED_API_FILE, 'w') do |file| Marshal.dump(drive, file) end end return client, drive end # フォルダを指定し、ファイル名を指定し、条件を満たしたファイル一覧を返す def get_list(client, drive) result = client.execute( :api_method => drive.children.list, :parameters => { 'folderId' => '検索したいフォルダのID', 'q' => "title = 'タイトルから検索したい文字列'", 'alt' => 'json'}) #jj result.data.to_hash result.data.items end if __FILE__ == $0 file_format_bug_fix(CREDENTIAL_STORE_FILE) client, drive = setup() files = get_list(client, drive) end
上記のrubyコードでは、フォルダを指定し、ファイル名を指定し、ファイルの一覧を取得しています。APIの仕様は公式リファレンスをご参照ください。
その他注意事項
上記のrubyコードを実行する際は、client_secrets.jsonをrubyコードと同じディレクトリに置いておくと、client_id、client_secretが自動で読み込まれます。
「Unable to find a browser command. ~ Launchy::CommandNotFoundError」の対策
上記のrubyコードをlinux上で実行する際は、まずlocalhost(macとか)で実行して、drive.rb-oauth2.jsonを生成しておき、drive.rb-oauth2.jsonをlinux上のrubyコードと同じディレクトリに置いておきましょう。初回のみブラウザでの認証が必須なため、localhostで先にdrive.rb-oauth2.jsonを生成しておく必要があります。
ご意見、ご質問
分からない点等は@ts_3156までお気軽にご質問ください(^^)
参考リンク
Google Developers API Reference
Google Drive(docs)からrubyでファイルを取得する方法
Google Drive(docs)からrubyでファイルをコピーする方法