自作のツールを公開すると後々何らかのメッセージを表示させたり、最悪動かせない様に止めたいなーと思う事が多々あると思います。
今回はその中でも「メッセージを受信する(受信した後に何らかのアクションを起こす)」という機能を、GoogleAppsScript(以下GAS)とスプレッドシートを組み合わせて実装する際の手順を紹介致します。
ちなみに私が以前から公開しており、つい最近更新を行った「くりったー」というツールで「最新バージョンの有無を通知する」という機能を同じ仕組みで実装してるので、そちらで実装した内容を例に紹介していきます。
※コードはC#のものです。
仕組みについて
まず最初に「メッセージ(バージョン番号)を受信する」という性質上、ツールを使用するPCがインターネット接続環境にある事は必須です。オフライン向けのツールには使用できません。
では本題ですが、バージョン番号を受け取って何らかのアクションを実行するまでの処理は大体以下の様な流れになります。
①(ツール)GASに最新バージョンの番号を要求する
②(GAS)スプレッドシートを参照し、バージョン番号を取得する
③(GAS)バージョン番号をツールに返す
④(ツール)受け取ったバージョンを判定し、自身の方が古ければ通知する
図にすると以下の様な感じです。
流れが分かった所で早速それぞれの機能を作っていきます。
スプレッドシート側の書き方
まずスプレッドシート上の書き方ですが、ここは好きなレイアウトで問題ありません。
値の取得はGAS側に書くので、そちらで分かり易い様な形にしておけば大丈夫です。
ちなみに私の場合はこんな感じ。
GAS側の書き方
まずはコードをそのまま載せます。
※「SHT_ID」は伏せ字にしているので、各々で修正して下さい
var FRIMATOOL_VERSION = "B2"; var CLITTER_VERSION = "B3"; var SHT_ID = "*************************************"; function doGet(e) { var version = "" var sht = SpreadsheetApp.openById(SHT_ID).getSheetByName("main"); var toolName = e.parameter.toolname; if(toolName == "clitter"){ version = sht.getRange(CLITTER_VERSION).getValue(); }else if(toolName == "frimasupport"){ version = sht.getRange(FRIMATOOL_VERSION).getValue(); } return ContentService.createTextOutput(version); }
ツールからGET形式でアクセスしてもらう事を想定し、関数はdoGetで用意しておきます。
そして上記のGASは各ツールのバージョン返却用総合窓口として作っているので、アクセス元のツール名を「toolname」に格納して自己申告してもらう様にしています。
※特定のツールに限定して作るのであれば、変数への格納部分やIF文の所は丸ごとカットして問題ありません。
ツール名の送信の仕方はツール側で記述するので、今は『「e.parameter.toolname」でどのツールがアクセスしてきたかが分かる』とだけ考えてもらえれば良いです。
その後、ツール名を判定して返すバージョン値を格納。
returnでバージョン値をツールに返すという流れになります。
ウェブアプリケーションとして公開する
このままでは作成したGASにアクセスする事ができませんので、どこからでもアクセス出来るようにウェブアプリケーションとして公開する必要があります。
手順は「公開」タブから「ウェブアプリケーションとして導入」を選択し、
アクセス権の設定を「匿名ユーザー含む全員」にして公開(Deploy)するだけ。
すると以下の様なURLが発行されるので、これでGAS側の準備は全て完了です。
https://script.google.com/macros/s/********************/exec
ちなみに上で掲載しているGASのコードの場合、以下のURLをブラウザで叩くとスプレッドシートに入力している値が返ってきているのが確認できます。
■「toolname」に「clitter」を指定した場合
https://script.google.com/macros/s/***/exec?toolname=clitter
⇒14
■「toolname」に「frimasupport」を指定した場合
https://script.google.com/macros/***/exec?toolname=frimasupport
⇒300
ツール側の書き方
ツール側のコードは以下の様な形になります。
const int MY_VERSION = 14; private void Form_Load(object sender, EventArgs e) { var url = "https://script.google.com/macros/s/***/exec?toolname=clitter"; var request = (HttpWebRequest)WebRequest.Create(url); var response = (HttpWebResponse)request.GetResponse(); string responseContent = string.Empty; using (var responseStream = response.GetResponseStream()) using (var stRead = new StreamReader(responseStream)) { responseContent = stRead.ReadToEnd(); } if(MY_VERSION < int.Parse(responseContent)) { this.MenuItem_VersionNotice.Enabled = true; } }
上記コードの例では要求タイミングがフォームロード時になっていますが、別にここでないといけない理由は無いので好きな場所に変更して構いません。
また、今回はWebRequestを使用していますが他の方法でも問題ありません。あくまで一例です。
アクセスする時点でURLに「?toolname=clitter」を記述していますが、ここに自身のツール名を入力しておきます。別のツールに移植する場合は「=」より後ろを変えるだけで済むので手間も掛かりません。
ちなみにGASのコード側で「e.parameter.toolname」と書いて受け取ったツール名を取り出しましたが、この「toolname」という名前はURLでアクセスする際にその名前で指定したからです。
例えばこの部分を
url = “https://script.google.com/macros/s/***/exec?name=clitter”
とすれば、GAS側は
「e.parameter.name」
で値を取得する事ができます。
値を複数渡すことも可能で、その場合は
exec?name=clitter&date=20191106&id=abcde
この様に「&」で要素を繋いだ状態にすればOKです。
GAS上ではそれぞれ以下の記述で値を取り出す事が出来ます。
e.parameter.name ⇒ clitter
e.parameter.date ⇒ 20191106
e.parameter.id ⇒ abcde
最終的に「responseContent」の中にGASから返されたバージョン値が格納されるため、「if(MY_VERSION < int.Parse(responseContent))」で自身のバージョン値との比較を行っています。
最新バージョンが自身のバージョン値より上回っていれば、「バージョンを通知するコントロールを有効にして知らせる」という仕様になっています。
ただ上のコードだと少し問題があり、GASからの応答が無かった場合は「int.Parse()」の部分でブランクを変換できずにエラーとなるはずです。ここは返却値がブランクでは無い事を判定する処理を挟んだり、「try~catch」などのエラートラップを入れるなりした方が良いです。
他の利用法
今回のコードはバージョン管理の手順でしたが、GASから受け取ったメッセージをそのまま表示すればユーザーへのお知らせに使えます。
他には「ツールを動作させるかどうか」というフラグとして扱えば遠隔でツールの利用を止めることも出来ますし、応用すれば認証用コードを渡したユーザーのみが使える様な仕様にする事も可能です。
元々こういった制御は自分でサーバを借りる必要があったので中々敷居が高かったのですが、GASのお陰で凄く実装しやすくなりました。
もっと色々活用していきたいですね。