以下で対応されたようです
このドキュメント何?
google_driveと、google-api-clientを同時に使おうと思ったら、google_driveがgoogle-api-clientのバージョン0.8を使っており、最新の0.9が使えなかったので、Google Driveを扱うのに、google-api-clientで全部やるかと決意した人のためのドキュメント。
コードはpryで実行したので、一部結果を載せています。
serviceはGoogle::Apis::DriveV3::DriveService.new
のことです。
バージョン
- google-api-client: 0.9.6
導入編
- Ruby Quickstartを見る
- APIs Explorerで全部のGoogle APIの仕様がみれる。ここで、Drive APIを眺めて何ができるか確認する。別途Drive REST APIドキュメントもある
- google-api-clientのgemのReferenceを見る。ここにもAPIドキュメントがる。DriveServiceを見ると各Drive APIに対応したrubyのメソッドの呼び出し形式がわかる
- Supported MIME Typesを見ると、フォルダを作成するときのMEME Typeや、tsvをspreadsheetに変換するときのMIME Typeがわかる
Drive API呼び出し
tsvファイルをSpreadsheet形式でアップロードする
- ここを参考にして実装する
file_metadata = {
name: 'test',
mime_type: 'application/vnd.google-apps.spreadsheet',
}
service.create_file(file_metadata, upload_source: 'data.tsv')
=> #<Google::Apis::DriveV3::File:0x007ffb66894e50
@id="1zhbfOjzwSs5d4k0vTMYjJenB20JvkHjIkJgrsB6_y3U",
@kind="drive#file",
@mime_type="application/vnd.google-apps.spreadsheet",
@name="test">
ばっちりできました。mime_typeをつけないと普通のtsvとしてアップロードされます。csvでアップロードしたいときも同じような感じでいけます。
フォルダを作成する
file_metadata = {
name: 'test-folder',
mime_type: 'application/vnd.google-apps.folder',
}
service.create_file(file_metadata, fields: 'id')
=> #<Google::Apis::DriveV3::File:0x007ffb6316a6f0 @id="0Byz3oGJQilf-a3hGbWVXV2ZSbXc">
Spreadsheetを特定のフォルダ以下にアップロードする
さっき作ったフォルダに入れてみます。
file_metadata = {
name: 'test',
mime_type: 'application/vnd.google-apps.spreadsheet',
parents: ['0Byz3oGJQilf-a3hGbWVXV2ZSbXc']
}
service.create_file(file_metadata, upload_source: 'data.tsv')
=> #<Google::Apis::DriveV3::File:0x007ffb62f13050
@id="10Wvb1xVGNsdB5ZQIGSDqzDCFToJxH4vh4CMEB2J34jc",
@kind="drive#file",
@mime_type="application/vnd.google-apps.spreadsheet",
@name="test">
特定のフォルダにある既存のSpreadsheetを特定のフォルダ以下に移動する
before-folder/test から after-folder/test にファイルを移動させます。
file_id = '1zhbfOjzwSs5d4k0vTMYjJenB20JvkHjIkJgrsB6_y3U' # before-folder/test
after_folder_id = '0Byz3oGJQilf-aHBGUk9sMTN4N0U'
file = service.get_file(file_id, fields: 'parents')
previous_parents = file.parents.join(',')
file = service.update_file(file_id,
add_parents: after_folder_id,
remove_parents: previous_parents,
fields: 'id, parents')
=> #<Google::Apis::DriveV3::File:0x007ffb62b92278
@id="1zhbfOjzwSs5d4k0vTMYjJenB20JvkHjIkJgrsB6_y3U",
@parents=["0Byz3oGJQilf-aHBGUk9sMTN4N0U"]>
特定のフォルダ以下にあるファイルをリストアップする
ページング無し
response = service.list_files(q: "'0Byz3oGJQilf-aHBGUk9sMTN4N0U' in parents",
spaces: 'drive',
fields:'nextPageToken, files(id, name)')
for file in response.files
puts "Found file: #{file.name} #{file.id}"
end
ページングあり
page_token = nil
begin
response = service.list_files(q: "'0Byz3oGJQilf-aHBGUk9sMTN4N0U' in parents",
spaces: 'drive',
fields:'nextPageToken, files(id, name)',
page_token: page_token)
for file in response.files
# Process change
puts "Found file: #{file.name} #{file.id}"
end
page_token = response.next_page_token
end while !page_token.nil?
なお、qのクエリ方法についてはSearch for Filesにあります。
Spreadsheetを削除する
削除されたファイルはゴミ箱にいかずに削除されます。
フォルダを指定した場合は、フォルダ以下のファイルがすべて消去されます。
service.delete_file('1zhbfOjzwSs5d4k0vTMYjJenB20JvkHjIkJgrsB6_y3U')
Spreadsheetをコピーする
from_idがコピー元のID. parentsには、所属させたいフォルダを指定します。
file_metadata = {
name: name,
parents: [to_folder_id],
}
service.copy_file(from_id, file_metadata, {})
スプレッドシートの内容を読み取る
ここまでで、Drive APIを通して、Spreadsheetをアップロードできましたので、その中身の操作をしたいと思います。
ここで、問題があるのですが、Spreadsheetの中身はDrive APIを通しては操作できません。操作するには、Sheet APIを通して行うか、Apps Scriptを実行することによって行います。
google_driveのgemはSheet APIを通してSpreadsheetを操作していますが、表現力がやや限られている事もあり、より良い感じで操作したければ、Apps Scriptを使う必要があります。
Apps ScriptをRubyから呼び出す基本的な方法は、ここを参照するといと思います。さらにqiitaの別の投稿でApps Scriptを使ったSpreadsheetの逆引き操作方法も載せています。
よくあるエラー
スクリプト実行後に以下のようなエラーが出ることがあります。
Unauthorized (Google::Apis::AuthorizationError)
そのようなときは、SCOPEが足りていない時があるので、直接Google Apps Scriptをみて、ファイル -> プロジェクトのプロパティ -> スコープを見てください。
rubyのスクリプトで実際に上記のSCOPEを含めているか確認してください。
あとがき
ここまでやってきて、Apps Scriptを使う流れは、JavaScriptを書く必要があり、rubyで完結できないので、google_driveをgoogle-api-clientの0.9対応するのもひとつの手だなとは思いました。
google_dirveで対応できないものは適宜、Apps Scriptでやれば、Rubyでほぼかけるので便利そうではあります。