見出し画像

ひとつの GAS アプリケーションで実行者をかえたい

【この記事は Qiita から note に移行しました】

[2019/05/24 ContentService を使った正しい GET 通信に書き直しました.]
[2019/05/24 お問い合わせは Twitter か メール が確実です.]

---

Qiita Advent Calendar 初参加です。よろしくお願いします。
Twitter: @TakumaNitori | @YutaNakamizo

---

「自分として実行」と「Web アプリケーションにアクセスしているユーザーとして実行」を併用したい

Web アプリケーションとして公開するときも、実行可能 API として公開するときも、
「自分が作ったWeb アプリ / API からはこのスプレッドシートを編集させたいしユーザー ID 取りたいけど、ネイティブのスプレッドシートからは編集させたくない」
というときがあると思います。あるはずなんです。てかあります (断定)。

このとき、Web アプリの場合は「Web アプリケーションにアクセスしているユーザーとして実行」にしないといけないですし、実行可能 API の場合はそもそも選択できないですし...
でもファイルの編集権限は渡したくないんや!!

そこで登場「UrlFetchApp」

UrlFetchApp というクラスが GAS にはありまして、引数に指定した URL とかパラメータを使って他のページとかからデータを取ってくるというやつです。GET リクエストや POST リクエストを送信することができます。
こいつを使って、
「Web アプリ / API として公開するプロジェクトファイル (Web アプリケーションにアクセスしているユーザーとして実行)」
から
「実際に編集する関数などを格納したプロジェクト(自分として実行)」を呼び出してやる
という処理をします。

簡単なサンプルコード

スプレッドシートに文字列を一つ追加するという簡単なサンプルです。

○ Web アプリ / API 側

function append(str) {
var payload = {
  value: str
}

var res = UrlFetchApp.fetch(
  "自分として実行するスクリプトの Web アプリ公開 URL",
  {
    method: "GET",
    contentType: "text/json",
    payload: payload
  }
).getContentText(); // <- Web アプリの URL にパラメータを付けて GET リクエスト
  Logger.log(res);
}

○ 自分として実行する側

function doGet(e) {
  var sheet = SpreadsheetApp.openById("スプレッドシートID").getSheets[0];
  sheet.appendRow([e.parameter.value]); // <- パラメータを取得して row 追加
  return;
}

実行結果を取得したい場合

実行結果を `success` と返してみましょう。

function doGet(e) {
  var sheet = SpreadsheetApp.openById("スプレッドシートID").getSheets[0];
  sheet.appendRow([e.parameter.value]);
  return "success"; // <- 文字列を返してみる
}

さてこのようにすると app.gs のログはどうなるかというと...

html[17-12-02 17:04:37:175 JST] <!doctype html><html><head><meta name="chromevox" content-script="no"><link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons"><link rel="stylesheet" href="https://www.gstatic.com/external_hosted/material_design_lite/mdl_css-indigo-pink-bundle.css"><script defer...

"success" を表示しようとする JavaScript を含んだ HTML が返ってきてしまいます。これは GAS の仕様で、純粋な文字列を返す場合には ContentService クラスを利用する必要があります。つまり以下のように書き換えることで対応できます。

return ContentService.createTextOutput("success");

あるいは JSON を返すこともできます。MimeType を設定すれば他にも JavaScript として返すことも可能です。

var rtnJson = {
  status: "success",
  requestText: e.parameter.value
}
return ContentService.createTextOutput(JSON.stringify(rtnJson))
                     .setMimeType(ContentService.MimeType.JSON);

まとめ

というわけで以上、GAS で実行者をかえたい時の対処でした。
ありがとうございました。

いいなと思ったら応援しよう!