2012年7月2日月曜日

Google DriveにCURLでアップロードするには?

LinuxからGoogleドライブにファイルをアップロードしたい!

Google Driveにlinuxからファイルを自動アップロードするにはどうしたら良いかを考えていた。

残念ながらlinux版のクライアントは予定はされているものの、まだリリースされていない。さてどうしよう?

例えば、一応SDKでライブラリが提供されているのでJavaでクライアントを書くとか?重いなぁ。そこまでやらなきゃいけないか?

そこで、Google DriveはRESTFulなんだからCurlだけでもある程度いけるはず・・・と思ってやってみたらできた。

Get Startedを参考にはじめる。
Google Drive SDK — Google Developers

ちなみに、テスト環境はlinuxではなくMacのLIONです。

追記12.07.04:CentOS 5 64bitでも正常動作を確認した


APIコンソールでアプリケーション登録

まずAPIコンソールでアプリケーション登録をする必要がある。
Google APIs Console

Create>「GoogleDriveUploader」とでも名前を付けて>Create Project

Services>Drive SDKをON

API Access>Create an OAuth2.0 client ID

Product Nameに「GoogleDriveUploader」とでも名前を付けて>Next
Installed Application、Otherを選択して>Create client ID

ここまででこんな情報を貰える。これが必要な情報。



ブラウザでOAuth認証してcodeを取得する

今度はブラウザ上で、先ほど得た情報を使ってOAuthの認証を通す。

https://accounts.google.com/o/oauth2/auth?client_id=CLIENT_ID&response_type=code&redirect_uri=urn:ietf:wg:oauth:2.0:oob&scope=https://www.googleapis.com/auth/drive

こんな画面が出るので「アクセスを許可」。




すると、このようにcodeを取得できる。



アクセストークンの取得

今度はCurlを使って、このようにアクセストークンを取得する。

curl -X POST https://accounts.google.com/o/oauth2/token \
-d "code=CODE" \
-d "client_id=CLIENT_ID" \
-d "client_secret=CLIENT_SECRET" \
-d "redirect_uri=urn:ietf:wg:oauth:2.0:oob" \
-d "grant_type=authorization_code"

すると、このようなJSONが返ってくる。

{
"access_token" : "ACCESS_TOKEN",
"token_type" : "Bearer",
"expires_in" : 3600,
"refresh_token" : "REFRESH_TOKEN"
}


アクセストークンの更新

アクセストークンは一定時間を過ぎると無効になる。つまり使い捨て。

そこで、このようにREFRESH_TOKENを使って適当なタイミングでアクセストークンを更新する必要がある。

curl -X POST https://accounts.google.com/o/oauth2/token \
-d "refresh_token=REFRESH_TOKEN" \
-d "client_id=CLIENT_ID" \
-d "client_secret=CLIENT_SECRET" \
-d "grant_type=refresh_token"

すると、このようなJSONが返ってくる。

{
"access_token" : "ACCESS_TOKEN",
"token_type" : "Bearer",
"expires_in" : 3600
}

アクセストークンの取得の時と違い、返ってきたJSONにはrefresh_tokenが含まれていないことに注意。


ファイルリストを取得する

いよいよGoogle Driveからファイルリストを取得してみる。

curl https://www.googleapis.com/drive/v2/files?access_token=ACCESS_TOKEN

おお!JSONがずらずらと!

これができればOAuth認証が正しく通っているということ。


ファイルをアップロードする

本芸に移ります∠( ̄∧ ̄)

ここでは少々データを用意しておかなければならない。

カレントディレクトリにアップロードするデータ(今回はupload.jpg)とファイルのメタデータとなるJSON(今回はmetadata.txt)を次のような感じで用意しておく。UTF8でね。

{
"title": "upload.jpg",
"mimeType": "image/jpeg",
"description": "Uploaded From Curl"
}

アップロード!

curl -X POST https://www.googleapis.com/upload/drive/v2/files?uploadType=multipart \
-H "Authorization: Bearer ACCESS_TOKEN" \
-H "Content-Type: multipart/related" \
-F "metadata=@metadata.txt;type=application/json;charset=UTF-8" \
-F "file=@upload.jpg;type=image/jpeg"

アップロードが完了するとアップロードしたファイルのIDやらのメタデータがJSONで返ってくる。

WEB上のGoogle Driveでアップロードできていることを確認する。やた!


ファイルを削除する

アップロード時に返ってきたJSONの中にあるidを使ってファイルを削除してみる。

curl -X DELETE https://www.googleapis.com/drive/v2/files/FILE_ID \
-H "Authorization: Bearer ACCESS_TOKEN"

ここでもWEB上のGoogle Driveで削除できていることを確認する。無くなってる。OK!


ファイルの更新(再アップロード)

一度アップロードしたファイルのデータ部分(つまり今回は画像)だけ再アップロードして更新してみる。

その前に、upload2.jpgというファイルを用意する。

curl -X PUT https://www.googleapis.com/upload/drive/v2/files/FILE_ID \
-H "Authorization: Bearer ACCESS_TOKEN" \
-F "file=@upload2.jpg;type=image/jpeg"

ここでもWEB上のGoogle Driveで画像が差し替わっていることを確認する。OK!


最後に

他にもメソッドは色々とあるけど、とりあえずこれくらいできればlinux上でファイル自動アップロードスクリプトを組むくらいならできるだろう。

いやぁ、RESTFulって、本当にいいものですね。

最後に、こちらのページが大変参考になりました。感謝を申し上げます。
curl で Google Drive にアップロード - Ajidoの日記


追記12.07.02:最後の問題。Google DriveやOAuthで返ってきたJSONを処理する方法。
琴線探査: JSONをシェルスクリプトで処理するには?