ひとつの 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 で実行者をかえたい時の対処でした。
ありがとうございました。