4
3

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 3 years have passed since last update.

GASの関数を実行可能APIじゃない方法で実行する

Last updated at Posted at 2020-06-08

はじめに

前にこんな記事を書きました。
WebサイトのJSからGASの実行可能APIを最短最高で叩く
内容は名前のまんま「実行可能APIを叩く」というものなんですが、自分が少し勘違いをしていたみたいで、自分が求めていた機能ではなかったみたいです。「実行可能API」は「API」ですから実行の主体はユーザー自身らしいのですよね。なのでDriveなどの操作をすると「ユーザーのDrive」に対して操作をしてしまい、共有のPermissionなどの関係で自分が意図した動作になりませんでした。私(開発者)の名義で関数を実行し、それをレスポンスしたいと思います。

どうやって?

GAS側で普通に関数を作り、doGet(e)ですべてのリクエストを受け取り、パラメータによって実行する関数を変えてその結果を返すというような感じです。クライアント側はjQueryajax()を用いてリクエストを送るだけです。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です。正直よくわからないですが、dataTypeJSONPにするとsuccess:が呼ばれなくなりその代わりcallbackとしてパラメータになります。さらにCORBを回避できるみたいです。

index.html
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にめっちゃ時間かかりましたね...

Twitter→https://twitter.com/CyberHacnoshuke

4
3
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
4
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?