29
28

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

GASを使ってGoogle Drive内にあるファイルのダウンロードURLからコンテンツを取得したい

Posted at

概要

Google Apps Script(GAS)を使ってGoogle Drive内にあるファイルのダウンロードURLからコンテンツを取得するための方法について記載します。

問題点

Googleの拡張サービスDrive.Files.get()を使用した際のexportLinksや、DriveAppでのgetDownloadUrl()で得られるURLはGoogleにログインしている状態でアクセスすることでファイルのダウンロードができます。しかし、GASを使ってUrlFetchApp.fetch(url)によりそれらのURLからファイルをダウンロードしようとすると、下記のようにファイルそのものではなくHTMLが取得されたり、あるいはエラーが発生してしまいます。

Drive.Files.get()の場合

例えばGoogle DocsをダウンロードしてそのBlobを取得しようと以下のようなスクリプトを用いると、ファイルは作成されますが、中身はHTMLになってしまいます。

var url = Drive.Files.get("### file ID ###").exportLinks["application/pdf"];
var blob = UrlFetchApp.fetch(url, {muteHttpExceptions: true}).getBlob();
DriveApp.createFile(blob.setName("sample"));

この作成されたHTMLを開いてみると、ログイン画面がダウンロードされていたことが分かります。(下図)

image1.png

DriveApp.getFileById()の場合

Google Docs以外であれば下記のようなスクリプトでもダウンロードURLを取得することができます。

var url = DriveApp.getFileById("### file ID ###").getDownloadUrl();
var res = UrlFetchApp.fetch(url).getBlob(); // ← ここでエラーが発生する
DriveApp.createFile(blob.setName("sample"));

この場合、下記のようなエラーが発生します。

https://doc-04-2k-docs.googleusercontent.com/docs/securesc/#####?e=download&gd=true に対するリクエストが失敗し、コード 401 が返されました

上記はいずれもスクリプト実行時に認証をしていないために目的のコンテンツが取得できないと考えられます。

解決方法

そこで、スクリプト実行時、すなわち、UrlFetchApp.fetch()を実行する際に認証できるようにします。

アクセストークンをクエリパラメータとしてダウンロードURLに追加します。

実際は"&access_token=" + ScriptApp.getOAuthToken()をダウンロードURLに追加します。内容はScriptApp.getOAuthToken()を使ってアクセストークンを発行し、access_tokenをキーとして追加します。アクセストークンを発行するScriptApp.getOAuthToken()はなかなか便利で、一般的なスコープを自動で割り当ててくれます。これによりスクリプト実行時に認証が行われ、ダウンロードURLを使ってGoogle Drive内にあるコンテンツをダウンロードすることができるようになり、スクリプトでダウンロードしたコンテンツをBlobとして扱うことができるようになります。いろいろな応用が期待できます。

上記問題点で使用したサンプルスクリプトを修正したものは下記の通りです。

サンプル 1

var url = Drive.Files.get("### file ID ###").exportLinks["application/pdf"] + "&access_token=" + ScriptApp.getOAuthToken();
var blob = UrlFetchApp.fetch(url, {muteHttpExceptions: true}).getBlob();
DriveApp.createFile(blob.setName("sample"));

サンプル 2

var url = DriveApp.getFileById("### file ID ###").getDownloadUrl() + "&access_token=" + ScriptApp.getOAuthToken();
var res = UrlFetchApp.fetch(url).getBlob();
DriveApp.createFile(blob.setName("sample"));

これらのサンプルスクリプトは、ダウンロードURLから取得したコンテンツのBlobを使ってファイルが作成されます。

Stackoverflowでもいくつか上記に関する質問がありましたので、こちらでもその解決方法について掲載させていただきました。お役に立てましたら幸いです。

29
28
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
29
28

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?