Google Apps ScriptでWebアプリケーション作成 その2

2020年4月30日

前回は静的なサイトを作成しました。今回は表示を動的に変更します。

新しいStandalone Scriptsを作成

前回のもはそのままにして、新規にStandalone Scriptsを作成します。スクリプトの種類はStandalone Scripts(ドライブ上に単独で存在するもの)とContainer-bound Scripts(Sheets、Docs、またはFormsにバインドされるもの)があります。

前回はGoogleDriveの画面から作成しました。2018年1月に「Dashboard」の機能が追加されました。こちらからStandalone Scriptsを作成することも可能です。

The Apps Script Dashboardは、作成したGoogle Apps Scriptを管理するためのダッシュボードです。以下のURLからアクセスできます。

https://script.google.com

前回、作成したスタンドアロンスクリプトのプロジェクトがあります。Standalone Scriptsだけではなく、Container-bound Scriptsのプロジェクトも表示されます。

実行数やエラー率も確認できます。

新規スクリプトの作成

ダッシュボードから作成します。新規スクリプトをクリックします。

ブラウザの新規タブにスクリプトエディタが表示されます。プロジェクト名を変更してOKをクリックします。

ルートフォルダに作成されました。フォルダを指定できれば便利ですができません。フォルダ管理したほうがいいので、ダッシュボードで作成するよりもGoogleDriveで作成したほうがよさそうです。

Apps Script Dashboardにも表示されました。

ここでもフォルダの場所は表示されませんね。

Webアプリケーションの要件

スクリプトは、次の要件を満たしていれば、Webアプリケーションとして公開することができます。

  • doGet(e)またはdoPost(e)関数を含んでいます。
  • この関数は、HTMLサービス HtmlOutputオブジェクトまたは コンテンツサービス TextOutputオブジェクトを返します。

doGet(e) HTTP GETリクエストを受信すると実行する関数
doPost(e) HTTP POSTリクエストを受信すると実行する関数

リクエストパラメーター

e 引数は、任意の要求パラメータに関する情報を含むことができるイベントパラメータを表します。

e.queryStringURLのクエリ文字列部分の値、クエリ文字列が指定されていない場合はNull
name=alice&n=1&n=2
e.parameterリクエストパラメータに対応するキー/値のペアのオブジェクト。複数の値を持つパラメータの場合、最初の値のみが返されます。
{"name": "alice", "n": "1"}
e.parameterse.parameter各キーの値の配列に似ていますが、値の配列を持つオブジェクト
{"name":["alice"]、 "n":["1"、 "2"]}
e.contextPath使用されず、常に空文字列。
e.contentLengthPOSTリクエストの長さ。GETリクエストの場合は-1
332
e.postData.lengthe.contentLengthと同じ
332
e.postData.typePOSTリクエストのMIMEタイプ
text/csv
e.postData.contentsPOSTリクエストの内容テキスト
Alice,21
e.postData.name常にpostData
postData
function doGet(e) {
  var params = JSON.stringify(e);//JSON形式にして
  return HtmlService.createHtmlOutput(params); // HtmlOutputオブジェクトとして返す
}

次のパラメータ名はシステムによって予約されているため、URLパラメータまたはPOST本体で使用しないでください。

  • c
  • sid

HTMLファイルを作成する

AppsスクリプトプロジェクトにHTMLファイルを追加するには、スクリプトエディタを開き、ファイル/新規/ HTMLファイルを選択します。

HTMLファイル内では、最も標準的なHTML、CSS、およびクライアントサイドのJavaScriptを記述できます。ページはHTML5として配信されますが、HTML5の一部の高度な機能は利用できません。

<!DOCTYPE html>
<html>
  <head>
    <base target="_top"> <!--リンクターゲット属性-->
  </head>
  <body>
    Hello, World!
  </body>
</html>

HTML5で導入されたiframeのsandboxモードで動きます。sandboxモードでは、リンクターゲット属性(_topまたは_blank)を設定する必要があります 。headセクションのなかにbaseタグですべてのリンクターゲット属性を指定できます。

doGet()関数の作成

HtmlTemplateオブジェクトを作成して、evaluateメソッドでHtmlOutputオブジェクトを返します。

function doGet() {
 // テンプレートhtmlからHtmlTemplate クラスのオブジェクト を生成
 var template = HtmlService.createTemplateFromFile('helloworld'); 
 
 // HtmlOutput クラスのオブジェクトを生成 
 return template.evaluate(); 
 
 // また、HtmlService.createHtmlOutputFromFile(fileName) でHtmlOutput クラスのオブジェクトを生成可能
 // 今回のようになにも変更しない場合は以下の1行のコードでも同じ意味になる
 // return HtmlService.createHtmlOutputFromFile('helloworld');
}

Webアプリケーションとしてのスクリプトのデプロイ

「公開」ー「ウェブアプリケーションとして導入」を選択して、バージョンを入力。アプリケーションの実行ユーザーとアクセスユーザーを設定して「導入」します。

URLにアクセスすると実行されます。

HTMLをGoogle Docs、Sheets、またはFormsのユーザーインターフェースとして提供することも可能です。

スクリプトがコンテナにファイルにバインドされている場合、HTMLサービスはGoogleドキュメント、スプレッドシート、またはフォームに ダイアログまたはサイドバーを表示できます。

Templated HTML

Apps ScriptのコードとHTMLを混在させることで、最小限の労力で動的なページを作成できます。スクリプトレットコードは、ページが提供される前に実行されるため、ページごとに1回しか実行できません。スクリプトレットはページが読み込まれた後に再度実行することはできません。ページからApps Scriptデータにインタラクティブにアクセスするには、代わりにgoogle.script.run APIを使用します。

Standard scriptlets

<? ... ?>

結果はページに出力されません。if文のときに使う。結果はhtmlタグ。

<!DOCTYPE html>
<html>
 <head>
 <base target="_top"><!--リンクターゲット属性-->
 </head>
 <body>
 <? if (true) { ?>
 <p>This will always be served!</p>
 <? } else { ?>
 <p>This will never be served.</p>
 <? } ?>
 </body>
</html>

Printing scriptlets

<?= ... ?> 出力スクリプトレットタグ

contextual escaping(コンテキストエスケープ)を使用してコードの結果がページに出力されます。

contextual escaping(コンテキストエスケープ)はAppsスクリプトがHTML属性内、クライアントサイドscriptタグ内、または他の場所で、ページ上の出力のコンテキストを追跡し、クロスサイトスクリプティング(XSS)攻撃から保護するためのエスケープ文字を自動的に追加 することを意味します。

<!DOCTYPE html>
<html>
 <head>
 <base target="_top"><!--リンクターゲット属性-->
 </head>
 <body>
 <p>Hello, World! The time is <?= new Date() ?>.</p>
 <?= 'My favorite Google products:' ?>
 <? var data = ['Gmail', 'Docs', 'Android'];
 for (var i = 0; i < data.length; i++) { ?>
 <b><?= data[i] ?></b>
 <? } ?>
 </body>
</html>

Force-printing scriptlets

<?!= ... ?> 

Printing scriptletsと似ていますが、コンテキストエスケープされません。通常は使いません。変数を文字列ではなく数値として出力したいときに使えます。

Apps Script code in scriptlets

スクリプトレットは、Apps Scriptのコードファイルまたはライブラリで定義された関数を呼び出すことができます。また、Apps Scriptコードは、スクリプトレットで直接使用することもできます。また、HtmlTemplateオブジェクトのプロパティとして変数を割り当てることで、変数をテンプレートにプッシュできます。

テンプレートのデバッグ

HtmlTemplateオブジェクトのgetCode()メソッドでテンプレートの実際の出力コードを確認できます。

https://developers.google.com/apps-script/reference/html/html-template#getCode()

Communicate with Server Functions

google.script.run.[関数名]()でサーバー側のApps Script関数を呼び出すことを可能です。非同期のクライアントサイドJavaScript APIです。非同期のため順番は保証されません。

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
    <script>
      google.script.run.doSomething();
    </script>
  </head>
</html>

https://developers.google.com/apps-script/guides/html/communication

パラメータと戻り値

クライアントからのパラメータを使用してサーバ関数を呼び出すことができます。同様に、サーバ関数は成功ハンドラに渡されるパラメータとしてクライアントに値を返すことができます 。

GoogleAppsScript

Posted by zzz