Google Apps ScriptでGET・POST【GAS】
Google Apps Scriptには、ウェブアプリケーションを公開したりするために「doGet」「doPost」という特別な関数があります。パラメータを加えて渡して上げることで、スプレッドシートのデータなどをJSONで受け取ったり、ウェブページを生成して、ウェブアプリケーションを表示したりなど、非常に重要な機能の1つです。この仕組を使うことで、自作のREST APIを作ることも可能です。
今回は、この「doPost」「doGet」を利用して、実行をするとスプレッドシートに書き込まれるといったものを作ってみたいと思います。
今回使用するスプレッドシートや資料
- doPost関数
- doGet関数
- 今回使用するスプレッドシート
- ContentServiceクラスの各種メソッド
概要
doGetは、URLに繋げてパラメータを与えて送ります。HTTP通信のGETなわけですが、こちらのほうが利用する範囲が広いんじゃないかなぁと。思いつくだけで言えば、
-
- パラメータ付きで送ってスプレッドシートの値をJSONで取得する(しかも、フィルタした後の値とか)
- 予め組んで置いたURLをメールに記載して、クリックすると発動する何か(例えば、承認されるとか、ファイルが作られるとか)
- 与えるパラメータに応じて表示するHTMLを切り替える
- パラメータを可変でユーザが選んだり、与えたパラメータによってデータを書き換える。
- Google Apps Scriptではウェブアプリケーション公開用のメソッドでもある。
doPostは、URLに繋げるのではなくHTTP通信にパラメータを渡すPOST通信です。GETと違いパラメータはURLには出てこないので、認証などを要するようなケースで利用されます。また、バイナリデータを送ったり(アップロード)などでもPOSTを使いますね。
両者の違い、用途としてデータを取得する場合にはGET、送る場合にはPOSTといった感じで使い分けをすると良いでしょう。
※doGetおよびdoPostは、同居は可能ですが1プロジェクトで1個しか用意できないので、複数用意したい場合には仕組みで分けるか?複数プロジェクトを作って運用する必要があります。また、Apps Script APIを利用する事で、1つのプロジェクトで直接関数を叩けるようになるので、複数用意したい場合は以下のエントリーを参考に構築しましょう。
doGet
仕組み
仕組みは至って簡単なものです。以下のような感じです。
- doGetはパラメータを受け取れるようにdoGet(e)という形で記述を行う。
- 送る側は、公開されてるウェブアプリケーションのURLにパラメータをくっつけて、叩くだけ。
- 付け加えるパラメータは、?param1=kinoko¶m2=takenoko みたいな感じ。この場合2つのパラメータを取得できる
- パラメータを受け取る側は、e.parameter.param1でkinokoという値が取得できるという塩梅です。
- 受け取ったパラメータを後は煮るなり焼くなり好きにする。
- 最後にreturnで、例えばHTML表示をしたり、JSONデータを返して上げれば、プログラムがそのままURLからデータを取得出来るようにもなる。(WebAPI的なものが作れるわけです)。
実行結果
コードを作ってGETパラメータ文字列を組み立ててURLを叩きます。例えば今回使用するスプレッドシートに於いて、【情報通信業】の【2009】の年のデータを引き出したい時には以下のようなURLを組み立てます。
すると、{“value”:194} といったようなJSONで返ってきます。param1が業態の指定・param2が年度の指定になります。業態の指定がおかしかったり、指定した年度の情報がない場合には、valueの値はerrorとして返すようにしています。上記のURLをクリックすると実際に値が返って来ます。
※ただし出力時に、URLはリダイレクトしますので、何かプログラムでデータを取得する場合にはそれを考慮する必要があります。
ソースコード
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
//書き込みスプレッドシートID var gasheet = "書き込み先のスプレッドシートのIDをここに記入"; function doGet(e) { //受け取るパラメータを用意する var filterparam = e.parameter.param1; var nendoparam = e.parameter.param2; var rowData = {}; //JSONオブジェクト格納用の入れ物 if (e.parameter == undefined) { //パラメータ不良の場合はundefinedで返す var getvalue = "undefined" rowData.value = getvalue; var result = JSON.stringify(rowData); return ContentService.createTextOutput(result); } else { var id = gasheet; //スプレッドシートのID var sheet = SpreadsheetApp.openById(id).getSheetByName("シート1"); var range = sheet.getRange("A1:Q").getValues(); var record = range.length; var colman = range[0].length; //年度の特定 var nencnt = 0;; for(var i = 1;i<record;i++){ if(nendoparam == range[i][0]){ nencnt = i; break; } } //年度で見つからなかった場合の処理 if(nencnt == 0){ var getvalue = "error" rowData.value = getvalue; var result = JSON.stringify(rowData); return ContentService.createTextOutput(result); } //業態の特定 var gyocnt = 0; for(var j = 1;j<colman;j++){ if(filterparam == range[0][j]){ gyocnt = j; break; } } //業態が見つからなかった if(gyocnt == 0){ var getvalue = "error" rowData.value = getvalue; var result = JSON.stringify(rowData); return ContentService.createTextOutput(result); } //みつかった値をJSONで返す var getvalue = range[nencnt][gyocnt]; rowData.value = getvalue; var result = JSON.stringify(rowData); //ログ出力と値の出力 Logger.log(result); return ContentService.createTextOutput(result); } } |
ポイント
- 今回の事例は非常に単純な指定したパラメータで値を返すだけですが、複数データを返すような場合には、JSONオブジェクト作成の部分で階層的なコードを書く必要性があるでしょう。
- 複雑なデータの出力については、SheetAsJsonのコードを再利用するとやりやすいかもしれません。
- param1やparam2といった部分はソースコード内で決めることができるので、自由にネーミングを付けて下さい。
- 最終的にContentService.createTextOutputにてJSON文字列を返してあげます。これをやらないと、他のプログラムからJSON出力を取得できません。
- 以前は、doGet出力のexecで終わるURLに対して、access_token=のパラメータを付けてAccess Token(ScriptApp.getOAuthToken()で取得)したものを繋げてアクセスすると認証なしでアクセスが出来たのですが、現在はこの手法は401エラーが返ってくるようになっています。OAuth2.0認証で通さないと駄目のようです。
裏技的なリクエスト
Googleにログインしてる状態であるならば、GASのdoGetで出力したページに対してWebブラウザからexecで終わるURLにアクセスすれば前述のような結果が普通に出力されます。これは通常の動作です。
問題はこれをWebブラウザ以外の手段や別のアプリケーションから同じURLにただHTTPリクエストを投げても、「ログインを要求」される為、通常はOAuth2.0認証をしてAccess Tokenを取得し、そのtokenをヘッダに加えてexecで終わるURLに対してリクエストといったようなことが必要になります。
しかし、裏技的な手法として、もし別の方法で既にAccess Tokenを取得出来ているのであるならば、以下のようなリクエスト方法でも認証を求められずにAccess Tokenをつけてのリクエストが出来ます。例えばcurlコマンドであったり、Chrome ExtensionやJSのfetchからのリクエストなどなど。
exec?の後ろにaccess_tokenのパラメータをつなげて、取得済みのToken文字列を入れて上げます。
1 2 |
//curlコマンドの場合 curl -L "https://script.google.com/macros/s/xxxx/exec?access_token=ここにAccess Tokenをいれる" |
但しこれを実現するには以下のような設定をしておく必要があります。
- ScriptApp.getOAuthToken()で取得したAccess Tokenである必要がある(つまり、必要なスコープを満たした結果出力してくれるTokenでなければならない)
- この時例えばスプシにアクセスして出力するJSONならば以下のようなスコープをappsscript.jsonに記述して事前に認証を済ませて、Tokenを取得しておく必要がある。
12345"oauthScopes": ["https://www.googleapis.com/auth/script.external_request","https://www.googleapis.com/auth/spreadsheets","https://www.googleapis.com/auth/drive"]
Drive APIは必須です。 - この認証を済ませておかないと、401 Unauthorizeというエラーが返ってきてしまう。
- ウェブアプリケーションとしてデプロイ時は今回は実行権限もアクセス権限も「自分のみ」としています。
- ゲストプロフィールのChromeから上記で構築したURLにアクセスするとログインしていなくても、値が取得出来ました。
図:ターミナルからリクエストしてみた
doPost
実行結果
※入力して送信するとスプレッドシートに書き込まれます。
ソースコード
GAS側コード
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
//書き込み先スプレッドシートID var gasheet = "ここに参照先スプレッドシートのIDを入れる"; //POSTで受け取ってスプレッドシートへ書き込み function doPost(e) { var test = e.parameter.name; var ss = SpreadsheetApp.openById(gasheet); var sheet = ss.getSheetByName("POST"); var array = [e.parameter.name,e.parameter.sex,e.parameter.food,e.parameter.mycar]; sheet.appendRow(array); //結果をリターン return makeContent(makeResponse(e,"POST")); } //スプレッドシートのIDチェック用 function checkId(id) { var ss = SpreadsheetApp.openById(gasheet); var sheet = ss.getSheetByName('POST'); var range = sheet.getRange(1, 1, sheet.getLastRow(), 1); var values = range.getValues(); var result = false; values.forEach(function (row) { row.forEach(function (val) { if (result) { return; } if (val === id) { result = true; return; } }); }); return result; } //投稿内容をJSONで組み立てて返す function makeResponse (e, type) { var valid = checkId(e.parameter.presentCode); e.parameter.valid = valid; var s = JSON.stringify({type: type, params: e}); if (!e.parameter.callback) { return {mime:ContentService.MimeType.JSON, content: s}; } else { return {mime: ContentService.MimeType.JAVASCRIPT, content: e.parameter.callback + "(" + s + ");" }; } } //投稿コンテンツ内容をJSONで返す function makeContent(content) { return ContentService.createTextOutput(content.content).setMimeType(content.mime); } |
意外とシンプルです。getActiveSpreadsheetが使用できないので、openByIdで開くようにしています。また、formから送られてくるデータはformの各コントロールに付与してるname属性を利用しています。なので、e.parameterの後にname属性を付けると、その値が取得できるので、これを順番に配列に格納し、appendRowで最終行に登録しています。
HTML側コード(POST送信用)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
<html> <head> <title>Google Spreadsheet書き込みテスト</title> <link rel="stylesheet" href="https://ssl.gstatic.com/docs/script/css/add-ons1.css"> <script type="text/javascript"> function disp(){ // 「OK」時の処理開始 + 確認ダイアログの表示 if(window.confirm('本当にいいんですね?')){ //FORMデータを送信する document.getElementById("formman").submit(); document.getElementById("kinoko").innerHTML = "<b>ありがとう</b>"; }else{ window.alert('キャンセルされました'); // 警告ダイアログを表示 } } </script> </head> <body> <div id="kinoko"> <form id="formman" action="ここにPOST側ウェブアプリケーションURLを入れる" method="post" target="_blank"> ニックネーム:<input type="text" name="name" id="input1"/><p> 性別: <input type="radio" name="sex" id="input2" value="男" />男 <input type="radio" name="sex" id="input3" value="女" />女<p> 好きな食べ物: <select name="food" id="input4"> <option value="すき焼き">すき焼き</option> <option value="寿司">寿司</option> <option value="天ぷら">天ぷら</option> <option value="あげパン">あげパン</option> <option value="カレーライス">カレーライス</option> </select><p> 愛車: <select name="mycar" id="input5"> <option value="GT-R">スカイラインGT-R</option> <option value="トレノ">スプリンタートレノ</option> <option value="シビック">シビックEK9</option> <option value="インプレッサ">インプレッサ</option> <option value="ランエボ">ランサーエボリューション</option> </select><p> <center> <p><input type="button" value="確認ダイアログ" onClick="disp()" class="action"></p> </center> </form> </div> </body> </html> |
Formの各要素のname属性がdoPost側に渡るe.parameterの値を取り出すときの要素になるので、重複しないようにname属性は付けなければなりません。また、送信ボタンで実行する関数の中で、document.getElementById(“formman”).submit();とあるけれど、これがフォームデータを送るコマンド。その送信先が、formタグのactionに記入されてるURL。これはスプレッドシートの公開URLです。
※全て用意が完了したらウェブページとして一度公開し、URLを取得。一度公開を無効化して、URLをHTML側のFORMの送信先に入れて、再度公開すると使えるようになります。
WordPressで設置してみる
前述の方法は、クライアント側まで含めてGoogle Apps Scriptで作成していますが、GAS側はdoPostだけをオープンにしておいて、HTML側はWordPress上に構築して送信するといった事が可能です。GASでUIを作ってしまうと、Googleアカウントが必要であったり色々面倒な部分も多いので、切り離して管理すると楽になれるかもです。
また、Google Formsを魔改造してこのサイトに、お問い合わせフォームとして設置していますが、非常に面倒な上に本来Google Formを経由しなくても良いので、doPostだけで実現する手法の方がUIの制限も無く作れるのでオススメです。
GAS側コード
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
//書き込み先スプレッドシートID var gasheet = "ここに書き込み先スプレッドシートのIDを入れる"; //POSTで受け取ってスプレッドシートへ書き込み function doPost(e) { //パラメータを受け取る let postContent = e.postData.getDataAsString(); //レコードに書き込み editrecord(postContent); //結果をリターン return ContentService.createTextOutput(JSON.stringify({statusText: "送信できたちょ"})).setMimeType(ContentService.MimeType.JSON) } //レコードに書き込む function editrecord(data){ //JSONをパースする let json = JSON.parse(data); var ss = SpreadsheetApp.openById(gasheet); var sheet = ss.getSheetByName("POST"); var array = [json.name,json.sex,json.food,json.mycar]; sheet.appendRow(array); } |
- 前述のコードで例えばローカルのHTMLから送信をするとCORSの制限によって受信が拒否されます。
- また、今回は送信が成功したら、responseを受け取り、送信元に表示するよう結果をリターンしています。
- 前述の場合と異なり、e.postData.getDataAsString()にて送信内容を取得する必要があります。
図:CORSエラーが出た様子
HTML側コード
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
<html> <head> <title>Google Spreadsheet書き込みテスト</title> <link rel="stylesheet" href="https://ssl.gstatic.com/docs/script/css/add-ons1.css"> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script> <script type="text/javascript"> //送信された時の処理 function senddata(){ //ラジオボタンの値を取得 let sex = $('input:radio[name="sex"]:checked').val(); //送信データ const obj = { name:$("#input1").val(), sex:sex, food:$("#input2").val(), mycar:$("#input3").val() }; fetch("ここに送信先のGASのウェブアプリケーションURLを記述する", { method: 'POST', body: JSON.stringify(obj), headers: { 'Content-Type': 'text/plain;charset=utf-8', } }) .then(response=>response.json()) .then(data=>{ //成功したので、表示切り替え $('#main').css('display', 'none'); $('#thanks').css('display', 'block'); //返り値を反映する $("#returnvalue").html(data.statusText); }) .catch(err => { console.log("Error:" + err); }); } </script> </head> <body> <div id="main" style="display:block"> <form id="formman" method="post"> ニックネーム:<input type="text" name="name" id="input1"/><p> 性別: <input type="radio" name="sex" value="男" />男 <input type="radio" name="sex" value="女" />女<p> 好きな食べ物: <select name="food" id="input2"> <option value="すき焼き">すき焼き</option> <option value="寿司">寿司</option> <option value="天ぷら">天ぷら</option> <option value="あげパン">あげパン</option> <option value="カレーライス">カレーライス</option> </select><p> 愛車: <select name="mycar" id="input3"> <option value="GT-R">スカイラインGT-R</option> <option value="トレノ">スプリンタートレノ</option> <option value="シビック">シビックEK9</option> <option value="インプレッサ">インプレッサ</option> <option value="ランエボ">ランサーエボリューション</option> </select><p> <center> <p> <button type="button" onclick="senddata();">送信</button> </p> </center> </form> </div> <div id="thanks" style="display:none"> <p id="returnvalue"></p> </div> </body> </html> |
- ローカルのただのindex.htmlからの送信で今回はテストしています。
- 前述のformでのsubmitだとページ遷移してしまうため、formの内容を1つずつ取得し、JSON.stringify()で送信しています
- 送信はfetch APIにて送信する必要があります。
- responseはJSONとして取得し、GAS側から送られてくる返り値のstatusTextの内容をIDがreturnvalueの項目に表示しています。
- responseの中にはstatusなども含まれているので、これで送信成功かどうかを判定する事も可能です。
- wordpressのページに上記のコードを貼り付けて、送信すれば、Googleスプレッドシートに書き込まれる仕組みです。
WordPress上でテスト
ポイント
- 今回書き込むシートのシート名はPOSTである。
- ウェブアプリケーションとして公開した時の公開URLは別途必要になる。
- ウェブアプリケーションとして公開する場合、実行権限は今回は自分自身のみにして、他の人が実行しても自分が実行した事になるようにしている。
- 完全フリーで公開する場合には、実行権限は自分自身であっても、投稿許可は匿名も可にしておく必要性がある。
WordPressで設置してみる2
前述の手法は送信のメソッドをGAS側へ送ってレスポンス結果だけを受け取る手法ですが、GAS側のウェブアプリの出力結果をWordPressに貼り付ける事も可能です。このサイトの作成アプリ一覧は、WordPress上で記述したものではなく、GAS上で生成した結果を呼び出してるだけのものです。この手法をするメリットは
- WordPress上で複雑なHTMLやCSS、JavaScriptを記述する必要性がない
- スプレッドシートに一覧を記載して出力が可能になるので、コンテンツ管理が容易になる(ただし、google.script.run.withSuccessHandlerで取得してレンダリングは出来ない)
- ただしVueなどのライブラリはWordPress側で呼び出してあげる必要がある
- また、Widthなどは明示的に指定してあげる必要がある(出力結果が特にモバイルではみ出てしまうため)
- iFrameで貼り付けるケースと違ってサイトのデザインを損ねたり、iFrameの高さで制限を受けて妙なスクロールバーが出たりせず一体感をもたせられるので非常に便利です。
ただし、特定のテーマなどの場合、VuetifyのCSSがサイドバーがバッティングする可能性があるので、デザイン設定などではそのページのみ「1カラム」にしてサイドバーを非表示にしてあげなければいけないケースがあります(Lightningテーマなどはこれが該当する)
GAS側コード
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
//フォーム表示用 function doGet(){ var html = HtmlService.createHtmlOutputFromFile('index') .setSandboxMode(HtmlService.SandboxMode.IFRAME) .setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL); //追加のメタタグ(スマフォ対応) html.addMetaTag('viewport', 'width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no, minimal-ui'); html.addMetaTag("mobile-web-app-capable", "yes"); html.addMetaTag("apple-mobile-web-app-capable", "yes"); //HTMLテキストを出力 var content = html.getContent(); return ContentService.createTextOutput(content); } |
WordPress側コード
1 2 3 4 5 6 |
<script type="text/javascript" src="https://code.jquery.com/jquery-2.1.4.min.js"></script> <link href="https://cdn.jsdelivr.net/npm/vuetify@2.x/dist/vuetify.min.css" rel="stylesheet"> こちらのページに記載されているアプリ達は、本サイトの各エントリーで紹介してきた内容を元に作成したアプリになります。個人利用に於いては無償で利用出来ます。ノーサポートになりますが、特に制限を設けていませんので、改造して利用することも可能です。 カスタマイズのご依頼や、これらをベースにアプリの制作依頼などはお問い合わせフォームからお願いいたします。 |
- IDがlistの場所にGAS側からのHTML出力内容を呼び出す
- vueやvuetifyのCDNのjsやcssをロードする記述は必要になります。
- GAS側はウェブアプリとしてデプロイしておき、そのURLに対してJavaScriptのFetch APIにてリクエスト
- レスポンスはresponse.text()で一旦受け取っておく
- 受け取った内容をdataに格納し、その内容をIDがlistの中に書き出す(この手順を踏まないと、object promiseと出て出力されない)
WordPressで設置してみる3
前述のコードだと、GAS側でスプレッドシートのデータを元にレンダリングをしたい場合、スプレッドシート連携でgoogle.script.run.withSuccessHandlerが利用できないのでそのままだとVueでレンダリングが出来ません。 そこでをgoogle.script.run.withSuccessHandler使わずにデータをレンダリングしたい場合は以下のコードを利用します。こちらにサンプルスプレッドシートもアップしてあります。
GAS側コード
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
//フォーム表示用 function doGet(){ var data = getTable(); //HTML生成と同時に配列情報を渡す var output = HtmlService.createTemplateFromFile('index').evaluate().getContent(); var html = HtmlService.createTemplate(output + "<script>\n" + "doIt( " + data + ");\n</script>") .evaluate() .setSandboxMode(HtmlService.SandboxMode.IFRAME); //追加のメタタグ(スマフォ対応) html.addMetaTag('viewport', 'width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no, minimal-ui'); html.addMetaTag("mobile-web-app-capable", "yes"); html.addMetaTag("apple-mobile-web-app-capable", "yes"); var content = html.getContent(); return ContentService.createTextOutput(content); } //スプレッドシートデータを取得する function getTable(){ var id = "1qc9hy1_esLl2h8Jw35zLT2ra_1bh9fGATClGEqBXAdQ" var sheet = SpreadsheetApp.openById(id).getSheetByName("data"); var ss = sheet.getDataRange().getValues(); //タイトル行を取得する var title = ss.splice(0, 1)[0]; //JSONデータを生成する return JSON.stringify(ss.map(function(row) { var json = {} row.map(function(item, index) { json[title[index]] = item; }); return json; })); } |
- createTemplateで出力時に同時にdoIt関数で変数の値を渡す手法を利用します。
HTML側コード
1 2 3 4 5 |
<script type="text/javascript"> function doIt(data){ vm.recdata = data; } </script> |
- 上記のコードでHTML側で用意したdoIt関数で受け取ることが可能です。これを直接vueのrecdata変数に突っ込みます。
WordPress側は前述と同じコードで問題なく表示が可能。スプレッドシートに記述した内容がそのまま、WordPress側で表示が可能になります。試しにランダムでスプレッドシートから1レコードカード形式で表示するものが以下のものになります。
スマフォのショートカットアプリで使う
GASで作成したdoGetやdoPostのURLに対してパラメータを投げることで、ボタン一発で色々発動させる事が可能です。例えば、ボタン一発で現在まで届いてる申請のサマリーを自分宛てにPDFで送りつけるスクリプトを作っておけば、PC立ち上げてなんてやらずとも、スマフォだけで完了します。緊急一斉通知用に作って置くと、何かの役に立つかもしれません。
また、パラメータを変更して、いつでもボタンぽち1発でメンバー招集する投稿をSlackに投げて飲みに行ったりなど、よく使うものを作り込んでおくと、恐ろしく簡単に自動化が可能です。IFTTTでタスクランナーを噛ましておけば、様々なウェブサービスを手元で発動も可能。
iOSで使ってみる
iOS12よりショートカットアプリという新機能が搭載されました。いわゆるPCのショートカットリンクと同じもので、特定のリンクをポチるだけで、起動させることが出来るもので、これにGoogle Apps Scriptの今回の機能を利用する事で、ボタンひとつで遠隔でGoogle Apps Scriptを実行させてしまおうというものです。使い方は以下の通り
- ショートカットアプリをインストールしておき、起動する
- 右上の+をクリックし、出てきた検索窓に「URL」と入力
- 「URL」という項目を選び、続けて「URLの内容を取得」も選びます
- URLにdoGetで作ったexecの付くURLを入力します。
- URLの内容を取得ボックスの方法は今回は「GET」を選択。
- 完了ボタンの下にある変なマークのアイコン⇒設定⇒名前で名前をつけておきましょう。アイコンは独自画像も使えます。
- 同じく設定にて、「Siriに追加」をタップ⇒赤丸をタップ⇒付けた名前で呼ぶ⇒設定完了。
- ホーム画面に追加をするとブラウザが立ち上がる。支持にしたがって、ホーム画面に追加をすると完了。
- POSTなども選べます。また送信時用のヘッダも付けられるので、ちょっと複雑なものもつくれそうです。
- 完了ボタン押して終了です。
※コンテンツとプライバシーの制限の許可されたAppにてSiriと音声入力がONになっていないとSiriから呼び出しは出来ません。
図:ショートカットアプリの設定画面
図:ショートカットの細かな設定はやっておきましょう。
図:Siriで実行してみた
Androidで使ってみる
Androidの場合、HTTP Requestを行うアプリは結構あります。HTTP Request Shortcutsというアプリでは、非常に詳細で細かくパラメータ、ヘッダー、オプション、Authenticationなどを設定可能で、iOSのそれよりも高機能です。
- アプリをインストールしておく
- プラスボタンを押して、新しいショートカットを作る
- From scratchを選択する
- 名前、説明、show as app shortcut on launcherにチェックを入れる
- MethodはGETやPOSTを選ぶ。今回はGETで。
- URLにGASで作成したexecのついたURLを入力しておく
- Authenticationは認証が必要な場合。Basic認証やDigest認証が使えます。OAuth2認証(Bearer認証)使えないので、doGet/doPostは公開されてるURLである必要がある。そのためここは、今回はNo Authenticationを選ぶ
- Add Headerでヘッダを加えられる。今回はヘッダは無し。
- Response Settingsではレスポンスを受け取ったらどういう動作を行わせるかを決定できる。simple toastで通知のみにした。
- Actionでは成功時や失敗時などのアクションを指定できる。成功したら別のショートカットを起動といったリレーも可能。
- Advanced Settingsでは、実行時に確認求めたり、タイムアウトの設定など細かい設定が可能
- 隣にある{}マークのアイコンは、細かなパラメータバリューを送る時に利用します。
- チェックマークを押す
- その後作ったショートカットをロングタップすると、Place on home screenというのがあるので、選択すると画面に一発実行用ショートカットが配置されます。これは、Chromeのホーム画面に追加と同じようなものになります。
図:マニアックでサイバーなアプリですね
console.logでログを取得
Google Apps ScriptではデバッグなどでLogger.logやconsole.logを使うことがありますが、doGetやdoPostなどに於いて、外部からアクセスした場合にもデバッグしたいことは普通にあります。しかし、実はGASではそのままでは、外部からGETやPOSTでウェブアプリケーションとして公開したURLを叩いても、console.logなどでログを取ることが出来ません。
doGetやdoPostでもconsole.logでログを取れるようにするためには以下の手順でGoogle Apps ScriptのプロジェクトをGoogle Cloud Console側のプロジェクトに移動させておく必要があります。
- スクリプトエディタのサイドバーからプロジェクトの設定を開く
- 下の方にあるGCPプロジェクトの項目で、プロジェクトを変更をクリック
- 予め、GCP側でプロジェクトを作っておきます。
- GCPのホーム画面にアクセスする
- タイトルの横にある▼をクリックして、自分が作ったプロジェクトを選択して変更する
- ダッシュボードのプロジェクト情報にある「プロジェクト番号」をコピーする
- スクリプトエディタに戻り、GCPのプロジェクト番号の欄に6.を入力して、プロジェクトを設定をクリック
- これでログが取れるようになったので、あらためて、ウェブアプリケーションとしてデプロイの作業をする
- 実際にGETやPOSTで叩くとparameterなどが取れるようになるのでデバッグが捗る
図:GCP側のプロジェクト番号が重要
図:プロジェクト移動できちんとログが残るようになった
関連リンク
- Insert new rows into Google Spreadsheet via cURL/PHP – HOW?
- Google Apps Script ウェブアプリケーション Google Sites ガジェット URLリクエストパラメータ
- 【GAS】複数のdoGet関数の結果を1つのプロジェクトに収納するシンプルな方法
- How to get a URL string parameter passed to Google Apps Script doGet(e)
- How to Make a RESTful API or Service with Google Apps Script
- Google Apps Script で spreadsheet のデータを JSON として読み込む
- pamelafox / exportjson.js
- SheetAsJson
- Google Apps Scriptを使って簡易APIをサクッと作る
- スプレッドシートとgoogle apps scriptで簡易APIを作ってalamofireからget/postする
- 拡張なしでオブジェクトのJSON文字列化、JSON文字列のパースを行う方法
- iOS12の「ショートカット」アプリで、なんちゃってプログラミングしてみた
- Google Apps Scriptでトリガー実行(doGet,doPost)のログを表示するにはGCPプロジェクトに紐付ける必要があるらしい
- (GASでHTML)HTMLのフォームデータをGASで受け取り、内容により違うHTMLページを返す。
- Google AppScriptWebアプリのGETおよびPOSTリクエストがCORSポリシーによってブロックされました
- Read the body of a Fetch Promise
- Taking advantage of Web Apps with Google Apps Script
- How do i allow a CORS requests in my google script?
- GASでCORSエラーを回避したウェブアプリを作成する方法
- [備忘録] GASのdoPost()にJavaScriptからJSONを渡す方法
- Google Apps Script で Web アプリを活用する
- Chrome Extension (Manifest v3) call Google Apps Script deployed as WebApp with OAuth2
- Google Apps Scriptでエンドポイント付きAPIを作る