みなさん、こんにちは!
タカハシ(@ntakahashi0505)です。
初心者向けにApp Makerのチュートリアルについてシリーズでお伝えしています。
前回の記事はこちら。
App Makerでスクリプトエディタでクライアントスクリプトを仕込む方法についてお伝えしました。
ただ仕込んだスクリプトについて解説をしていませんでしたので、今回ガツっと紹介していきます。
App Makerでクライアントスクリプトからサーバースクリプトを呼び出す方法です。
非同期通信なので、ちょっと一工夫入りますよ。
では、行ってみましょう。
前回のおさらい
まず、これまでのおさらいです。
メール送信アプリを作成していまして、ページの構成は以下のようになっています。
ボタン「SEND EMAIL」のonClickイベントに
var widgets = widget.parent.descendants;
var to = widgets.To.value;
var subject = widgets.Subject.value;
var msg = widgets.Msg.value;
widgets.EmailStatus.text = 'Sending email...';
sendMessage(to, subject, msg);
ボタン「CLEAR EMAIL FORM」ボタンのonClickイベントに
clearEmailForm();
というスクリプトを仕込んでいます。
また、これらのスクリプト内で関数sendMessageと関数clearEmailFormを呼び出していますが、これらはクライアントスクリプトとして以下のものを仕込みました。
/**
* Clears the entire email form
*/
function clearEmailForm(){
var formWidgets = app.pages.Email.descendants;
formWidgets.EmailStatus.text = "";
formWidgets.To.value = "";
formWidgets.Subject.value = "";
formWidgets.Msg.value = "";
}
/**
* Sends an email message.
* @param {string} to - Message recipient
* @param {string} subject - Message subject
* @param {string} msg - Body of message (HTML from Text Editor)
*/
function sendMessage(to, subject, msg){
var status = app.pages.Email.descendants.EmailStatus;
google.script.run
.withFailureHandler(function(error) {
// An error occurred, so display an error message.
status.text = error.message;
})
.withSuccessHandler(function(result) {
// Report that the email was sent.
status.text = 'Email sent...';
clearEmailForm();
})
.sendEmailMessage(to, subject, msg);
}
今回はこのクライアントスクリプトの内容について解説をしていきます。
メールフォームをクリアする関数
まず、関数clearEmailFormから解説をしていきます。
この関数はメールフォームの各ウィジェットをクリアするといった処理をします。
/**
* Clears the entire email form
*/
function clearEmailForm(){
var formWidgets = app.pages.Email.descendants;
formWidgets.EmailStatus.text = "";
formWidgets.To.value = "";
formWidgets.Subject.value = "";
formWidgets.Msg.value = "";
}
ページのすべてのウィジェットを取得する
5行目ですが、appは現在実行してるアプリケーションを表すAppオブジェクト、pagesプロパティはAppオブジェクトに含まれるページのコレクションを取得しています。
ページのコレクションはプロパティマップで取得できますので、ピリオドに続けてnameプロパティを指定することで、各ページを取得することができます。
つまり、例では
まででページ「Email」を取得したということになります。
さらに、descendantsはその子ウィジェットをプロパティマップとして取得します。
つまり、ButtonウィジェットのonClickイベントに仕込んでいる
と同じことになるのですが、今回の仕込み先はウィジェットではなく、スクリプトエディタになりますので、こちらの記法を使ってるということになると思います。
各ウィジェットをクリアする
続くステートメントはわかりますね。
- Labelウィジェット「EmailStatus」のtextプロパティ
- Text boxウィジェット「To」のvalueプロパティ
- Text boxウィジェット「Subject」のvalueプロパティ
- Text editorウィジェット「Msg」のvalueプロパティ
を全て空文字に設定する、つまりクリアするという処理になります。
サーバースクリプトの関数を呼び出す
さていよいよここから本番で、サーバースクリプトに記述した関数を呼び出す方法です。
関数sendMessageは、各ウィジェットに入力されている
- to:メール送信先アドレス
- subject:件名
- msg:メール本文
を受け取り、サーバースクリプトに仕込まれている、Emailを送信するための関数sendEmailMessageを呼び出すというものです。
/**
* Sends an email message.
* @param {string} to - Message recipient
* @param {string} subject - Message subject
* @param {string} msg - Body of message (HTML from Text Editor)
*/
function sendMessage(to, subject, msg){
var status = app.pages.Email.descendants.EmailStatus;
google.script.run
.withFailureHandler(function(error) {
// An error occurred, so display an error message.
status.text = error.message;
})
.withSuccessHandler(function(result) {
// Report that the email was sent.
status.text = 'Email sent...';
clearEmailForm();
})
.sendEmailMessage(to, subject, msg);
}
しかし途中に何やらいろいろありますね。解説をしていきます。
google.script.runは非同期通信でサーバースクリプトを呼び出す
App Makerでは、クライアント側からサーバー側の関数にアクセスをするためにgoogle.script.runというもの(JavaScriptAPI)が用意されています。
書式としては、以下のように記述します。
ただし、この場合のクライアントとサーバーのやり取りは非同期通信となります。
というのも、クライアントスクリプトが実行されるのはブラウザですから、 サーバーに依頼を出してからその回答が来るまで待っていたら、その間ブラウザの操作ができないことになります。
なのでブラウザは他の処理を進めながら、その回答を待つということになります。また必ずしも望んだ回答が返ってこないこともあるので、その場合も想定する必要があります。
withSuccessHandlerとwithFailureHandler
それをコントロールするために、withSuccessHandlerとwithFailureHandlerを使用し、以下のように記述します。
.withFailureHandler(function(変数1) {
// エラーが起きたときの処理
})
.withSuccessHandler(function(変数2) {
// サーバーが正しく応答したときの処理
})
.関数(引数)
google.script.runに続いて
- コールバック関数を与えたwithFailureHandler
- コールバック関数を与えたwithSuccessHandler
- 呼び出す関数
がピリオドで連続的に連結して記述しているのに注目してください。メソッドチェーンというやつですね。
サーバーから正しい応答が戻ってきた場合
サーバーから正しく応答がなされればwithSuccessHandlerに指定したコールバック関数を実行します。
その際サーバースクリプトからの戻り値があれば、コールバック関数の引数として指定した変数に格納されます。
つまり、今回の例ではサーバースクリプトと呼び出しが成功したら、 Labelウィジェット「EmailStatus」のテキストを「Email sent…」とし、関数clearEmailFormを呼び出すということになります。
サーバーからの応答がエラーとなった場合
一方で、サーバーからの応答がエラーとなればwithFailureHandlerに指定したコールバック関数を実行します。
その際、Errorオブジェクトがコールバック関数の引数として指定した変数に格納されます。
ですから、この例ではLabelウィジェット「EmailStatus」のテキストとしてエラーメッセージを表示するということになります。
ややこしそうな見栄えはしてますが、分かってしまえばなんてことないと思います。
まとめ
以上、App Makerでクライアントスクリプトからサーバースクリプトを呼び出す方法についてお伝えしました。
withSuccessHandlerとwithFailureHandlerによる非同期通信の応答による分岐処理のところは、ややこしそうに見えますが構文をそのまま当てはめていただければ、 組みやすいと思います。
なお、クライアントからの呼び出しはGASでも同様の方法で行われますので、ここで覚えてしまえばGASでも使うことができますよ。
では、次回はいよいよサーバースクリプトを仕込んで行きたいと思います。
どうぞお楽しみに!