はじめに
前にこんな記事を書きました。
WebサイトのJSからGASの実行可能APIを最短最高で叩く
内容は名前のまんま「実行可能APIを叩く」というものなんですが、自分が少し勘違いをしていたみたいで、自分が求めていた機能ではなかったみたいです。「実行可能API」は「API」ですから実行の主体はユーザー自身らしいのですよね。なのでDriveなどの操作をすると「ユーザーのDrive」に対して操作をしてしまい、共有のPermission
などの関係で自分が意図した動作になりませんでした。私(開発者)の名義で関数を実行し、それをレスポンスしたいと思います。
どうやって?
GAS側で普通に関数を作り、doGet(e)
ですべてのリクエストを受け取り、パラメータによって実行する関数を変えてその結果を返すというような感じです。クライアント側はjQuery
のajax()
を用いてリクエストを送るだけです。jQuery
は導入したという前提でいきます。
GAS側の実装
function doGet(e) {
var params = e.parameter;
var res = {};
switch(params.function) {
case "exampleFuncA":
res = exampleFuncA();
break;
case "exampleFuncB":
res = exampleFuncB(params.parameters);
break;
}
var callback = params.callback;
var output = ContentService.createTextOutput();
var responseText;
if (callback) {
responseText = callback + "(" + JSON.stringify(res) + ")";
output.setMimeType(ContentService.MimeType.JAVASCRIPT);
} else {
responseText = JSON.stringify(res);
output.setMimeType(ContentService.MimeType.JSON);
}
output.setContent(responseText);
return output;
}
後述するCross-Origin Read Blocking(CORB)
によって値のレスポンスが少し特殊です。e.parameter
でリクエストのdata
の部分を取得できます。今回はJSONです。e.parameter.callback
にもし値が入っているならば「コールバック関数を呼んで引数として実行した結果(JSON)を渡します。」というレスポンスをします。なかった場合は結果をJSONでレスポンスするだけです。
これを書いたら公開>ウェブアプリケーションとして導入
でURLを取得してください。
クライアント側の実装
気を付けるのはCross-Origin Read Blocking(CORB)
です。さらっと読んだだけですので詳しくはわかりませんが、どうやら違うドメイン間のajax
などのリクエストは(連続でやると)攻撃になる可能性があるので注意が必要ですよということらしいです。ふつうにajax
したらエラーになります。そこで使うのがJSONP
です。正直よくわからないですが、dataType
をJSONP
にするとsuccess:
が呼ばれなくなりその代わりcallback
としてパラメータになります。さらにCORB
を回避できるみたいです。
function callAppsScript(functionName, parameters, callbackFunc) {
var request = { 'function': functionName, 'parameters': parameters };
$.ajax({
type:"get",
url: GOOGLEAPPSSCRIPT_URL,
data: request,
dataType: "jsonp",
success: function(data) {
callbackFunc(data);
}
}).fail(function(jqXHR, textStatus, errorThrown ) {
console.log("XMLHttpRequest : " + jqXHR.status + "\ntextStatus : " + textStatus + "\nerrorThrown : " + errorThrown.message);
});
}
data:
でパラメータたちをJSON
として送信します。これはGAS側のe.parameter
に当たります。わかりにくいですがparameters
が関数に引数です。自分は1つしか渡さなくていいようになっていたのでただの文字列ですが第2引数以降が存在する場合はちょっと改造が必要です。自分が試した限りでは配列で渡すと失敗するので第1引数,第2引数,...
という感じで渡してGAS側で,
でsplitするのがいいと思います。下は実際に実行してみます。
callAppsScript("exampleFancA", "", function(data) {
// dataが返却値
});
callAppsScript("exampleFancB", "something", function(data) {
// dataが返却値
});
最後に
今回はGASのウェブアプリケーションにリクエストを送って任意の関数を実行してみました。結局、ユーザーのMailAdressを取得するのに「実行可能API」を使い、何か実行させるときはAjaxで叩くという意味わからない?仕様になってしまいました。自分はCORB
にめっちゃ時間かかりましたね...