背景
先日、Google Apps ScriptのUrlFetchAppを使ってmultipart/form-data
タイプでファイルをやり取りする状況が発生しました。オフィシャルドキュメントでは、payloadにオブジェクトを与えると自動でapplication/x-www-form-urlencoded
またはmultipart/form-data
としてリクエストされるとありましたが、残念ながら今回の用途には使用できませんでした。また、Javascriptのfetchで使用するFormData()のようなサンプルがあればと探しましたが残念ながら見つからず、丁度いくつかのアプリで使用する予定もありましたのでライブラリとして作成しました。リポジトリはこちらです。
ライブラリのプロジェクトキー
1sm9V-w8-0i3U4-10N6XyaRjHk5voiuJ1ArKSLo3htOUasB6GcPcIq8Kb
インストール方法
- 最初にスクリプトディタを立ち上げてライブラリをインストールします。インストール方法はこちらをご覧ください。
- このとき使用するライブラリのプロジェクトキーは、**
1sm9V-w8-0i3U4-10N6XyaRjHk5voiuJ1ArKSLo3htOUasB6GcPcIq8Kb
**です。
- このとき使用するライブラリのプロジェクトキーは、**
使い方
使用方法は、サンプルスクリプトをご覧頂く方が分かりやすいのではないかと思いましたので、サンプルスクリプトを使用します。
サンプルスクリプト 1
このスクリプトでは、単体のリクエストを実行しています。基本はUrlFetchApp.fetch()
と同じですが、formDataを与えるbodyのプロパティを追加しています。
スクリプトの動作内容
Drive API v3を使用してPDFファイルあるいは画像ファイルをOCRを行いGoogle Documentに変換します。
スクリプト
function sample1() {
var fileId = "### fileId of PDF ###";
var metadata = {
name: "sampleDocument", // Filename of created Google Document
mimeType: MimeType.GOOGLE_DOCS // MimeType of Google Document
};
var fileBlob = DriveApp.getFileById(fileId).getBlob();
var form = FetchApp.createFormData(); // Create form data
form.append(
"metadata",
Utilities.newBlob(JSON.stringify(metadata), "application/json")
);
form.append("file", fileBlob);
var url =
"https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart";
var params = {
method: "POST",
headers: { Authorization: "Bearer " + ScriptApp.getOAuthToken() },
body: form
};
var res = FetchApp.fetch(url, params);
Logger.log(res);
// DriveApp.createFile(blob) // This comment line is used for automatically detecting scope for running this sample script.
}
サンプルスクリプト 2
このスクリプトでは、複数のリクエストを一度に実行しています。基本はUrlFetchApp.fetchAll()
と同じですが、formDataを与えるbodyのプロパティを追加しています。
スクリプトの動作内容
Drive API v3を使用してテキストファイルを既存のGoogle Documentに上書きします。リクエスト自体は非同期で実行されます。Drive APIを用いたファイルのアップデートはバッチリクエストでは実行できないことを考えると、下記のようなスクリプトはAPI使用回数はリクエスト数と同数にはなりますが、現状の一つの回避策になるかもしれません。
スクリプト
function sample2() {
var contents = [
{
fileName: "newFilename1", // new filename
docs: "### GoogleDocumentId1 ###", // Destination fileId of existing Google Document.
textFile: "### textFileId1 ###" // Source fileId of text file.
},
{
fileName: "newFilename2",
docs: "### GoogleDocumentId2 ###",
textFile: "### textFileId2 ###"
}
];
var accessToken = ScriptApp.getOAuthToken();
var requests = contents.map(function(e) {
var metadata = { name: e.fileName };
var form = FetchApp.createFormData(); // Create form data
form.append(
"metadata",
Utilities.newBlob(JSON.stringify(metadata), "application/json")
);
form.append("file", DriveApp.getFileById(e.textFile).getBlob());
var url =
"https://www.googleapis.com/upload/drive/v3/files/" +
e.docs +
"?uploadType=multipart";
params = {
url: url,
method: "PATCH",
headers: { Authorization: "Bearer " + accessToken },
body: form
};
return params;
});
var res = FetchApp.fetchAll(requests);
Logger.log(res);
// DriveApp.createFile(blob) // This comment line is used for automatically detecting scope for running this sample script.
}