Google Drive API v3を使用したGoogle Docsのリビジョンファイルのダウンロード

# 概要
Google Drive API v3を使用してリビジョンIDからGoogle Docsのファイルをダウンロードします。Google Docsとは、スプレッドシートやドキュメント、スライドなどを指します。ここでは画像やテキストなどのファイルはGoogle Docs以外と表現しています。

Google Drive API v2ではファイルの種類を問わずに"downloadUrl"を取得することでダウンロード可能でしたがv3ではURL出力が廃止されています。さらに、Google Docsとそれら以外のファイルでダウンロード方法が異なります。v3での説明が非常に[シンプル](https://developers.google.com/drive/v3/reference/revisions/get)だったこともあり、v3を使用したリビジョン毎のファイルダウンロード方法を聞かれたり、質問されているところを見かけましたので他の方のお役に立てばと、こちらに記載させていただきました。

# 問題点
Google Drive API v3の[Revisions getのリファレンス](https://developers.google.com/drive/v3/reference/revisions/get)では、``https://www.googleapis.com/drive/v3/files/### FileID ###/revisions/### RevisionID ###``を使用するとあります。[ダウンロード](https://developers.google.com/drive/v3/web/manage-downloads)する場合は、"files.get"を使って``?alt=media``のクエリパラメータを追加します。この場合、画像ファイルやテキストファイルなど、Google Docs以外のファイルをダウンロードすることはできますが、Google Docsをダウンロードしようとすると下記のようなエラーが返されます。

~~~json
{
 "error": {
  "errors": [
   {
    "domain": "global",
    "reason": "fileNotDownloadable",
    "message": "Only files with binary content can be downloaded. Use Export with Google Docs files.",
    "locationType": "parameter",
    "location": "alt"
   }
  ],
  "code": 403,
  "message": "Only files with binary content can be downloaded. Use Export with Google Docs files."
 }
}
~~~

"Use Export with Google Docs files."とありますので、["files.get"](https://developers.google.com/drive/v3/reference/files/get)のように["files.export"](https://developers.google.com/drive/v3/reference/files/export)へクエリパラメータを追加することでダウンロードできるはず単純に考えましたがここでハマってしまいました。

# 解決策
結果としてExportでもURLのクエリパラメータを追加する必要がありました。ただ、残念ながら追加したパラメータはGoogleの[リファレンス](https://developers.google.com/drive/v3/reference/files/export)には掲載されていませんでした。

下記のように"files.export"に対して、``revisions=### RevisionID ###``をパラメータとして付け加えることでダウンロードすることができました。``revision=### RevisionID ###``でもOKです。revisionsで複数ファイルをダウンロードすることができるのかも？と思いましたが、残念ながらその方法は不明でした。

~~~
https://www.googleapis.com/drive/v3/files/### FileID ###/export?revisions=### RevisionID ###
~~~

最初に検索サイトで調べてみましたが、ダウンロードできない、v2の使用を推奨、などの内容ばかりで解決策には到達しませんでした。そこで、試行錯誤しました。探索方法はいたって簡単で、"files.get"と同様に"files.export"にもクエリパラメータがあるだろうと想定して、可能性のあるキー、値を並べてランダムで一気に走らせました。運よく引っかかりました。

## サンプル（Google Docs）
ここではリビジョンファイルをダウンロードするためのサンプルとしてcurlを使用します。実行する前にアクセストークンの取得、APIコンソールでDrive APIの有効化を行ってください。SCOPEは``https://www.googleapis.com/auth/drive.readonly``で問題ありません。

初めにリビジョンIDを取得します。下記を実行するとリビジョンidとmodifiedTimeが配列で出力されます。

~~~bash
curl -sSLG \
    -H 'Authorization: Bearer ### Access token ###' \
    'https://www.googleapis.com/drive/v3/files/### FileID ###/revisions?fields=revisions(id%2CmodifiedTime)'
~~~

取得したリビジョンIDを使用してファイルをダウンロードします。サンプルとしてスプレッドシートをエクセルに変換してダウンロードします。

~~~bash
curl -sSLG \
    -d "mimeType=application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" \
    -H 'Authorization: Bearer ### Access token ###' \
    "https://www.googleapis.com/drive/v3/files/### FileID ###/export?revisions=### RevisionID ###" \
    -o outputfilename.xlsx
~~~

これでGoogle Docsのリビジョンファイルのダウンロードは完了です。

## サンプル（Google Docs以外）
Google Docs以外のリビジョンファイルは下記のようにしてダウンロードします。リビジョンIDの取得方法は共通です。

~~~bash
curl -sSLG \
    -H 'Authorization: Bearer ### Access token ###' \
    "https://www.googleapis.com/drive/v3/files/### FileID ###/revisions/### RevisionID ###?alt=media" \
    -o outputfilename
~~~

ところで、画像ファイルやテキストファイルなど、Google Docs以外のファイルのリビジョンIDを見ると、通常のファイルIDと似ていることに気づきました。このことから、通常のファイルダウンロードでもダウンロードすることが可能なのではないかと考え、下記のように実行してみるとダウンロードすることができました。

~~~bash
curl -sSLG \
    -H 'Authorization: Bearer ### Access token ###' \
    "https://www.googleapis.com/drive/v3/files/### RevisionID ###?alt=media" \
    -o outputfilename
~~~

## GASのリビジョン
GASのリビジョンを確認しようとIDを入力すると、下記のようなエラーが返されます。スクリプトエディタの変更履歴からは手動で取得できますので、これをAPIで出力することができればと思ったのですが見つかりませんでした。

~~~json
{
 "error": {
  "errors": [
   {
    "domain": "global",
    "reason": "revisionsNotSupported",
    "message": "The file does not support revisions."
   }
  ],
  "code": 403,
  "message": "The file does not support revisions."
 }
}
~~~