LoginSignup
1
6

More than 5 years have passed since last update.

GoogleAppsScript で SinglePageApplication を作るTips

Last updated at Posted at 2016-11-24

はじめに

先日の 複数のGoogleカレンダーをマージする で、GoogleAppsScriptの知見が溜まってきたので、一旦分かるところまで纏めておきます。

サーバーサイドjs

server.js
// GETリクエストのハンドリング
function doGet(e) {
  // なんか処理
  var result = func(e.parameter);

  // index.htmlからテンプレートを生成し、変数をバインド
  var html = HtmlService.createTemplateFromFile('index');
  html.title = 'title';
  html.hoges = ['hoge', 'fuga'];

  // HTMLの生成とviewpoetの設定
  var output = html.evaluate().setSandboxMode(HtmlService.SandboxMode.IFRAME);
  output.addMetaTag('viewport', 'width=device-width, initial-scale=1, maximum-scale=1')
  return output;
}


// POSTリクエストのハンドリング
function doPost(e) {
  // doGetと同じ感じで
}

// なんか処理
function func(params) {
  // 結果の返却
  return {
    res1: params.param1,
    res2: params.param2,
  };
}

GET/POSTリクエストのハンドリング

  • doGetメソッドはGETリクエストを受けた場合に実行される
  • doPostメソッドはPOSTリクエストを受けた場合に実行される
  • パラメータの取得は、引数eからe.parameter.[パラメータ名]で取得
function doGet(e) {
  var param1 = e.parameter.param1;
  var param2 = e.parameter.param2;
}

function doPost(e) {
  var param1 = e.parameter.param1;
  var param2 = e.parameter.param2;
}

HTMLへの変数の埋め込み

  • テンプレートを読み込むにはHtmlServiceを利用
  • テンプレートへの変数の受け渡しはhtmlへプロパティを設定
  • HTMLテンプレート側では<?= [変数名] ?>で取り出し
var html = HtmlService.createTemplateFromFile('index');
html.title = 'title';
return html.evaluate();
<title><?= title ?></title>
  • viewportの設定はhtmlファイルにベタ書きしても効かないのでsetSandboxModeaddMetaTagで設定する
var output = html.evaluate().setSandboxMode(HtmlService.SandboxMode.IFRAME);
output.addMetaTag('viewport', 'width=device-width, initial-scale=1, maximum-scale=1')
return output;

その他

パラメータのバリデートとかもできるっぽい...?(勉強中)

HTMLテンプレート

index.html
<!DOCTYPE html>
<html lang='ja'>
<head>
  <meta charset='UTF-8'>
  <title><?= title ?></title>

  <!-- including stylesheets -->
  <link rel='stylesheet' href='https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css'>
  <link rel='stylesheet' href='https://maxcdn.bootstrapcdn.com/font-awesome/4.6.2/css/font-awesome.min.css'>
</head>

<body>
  <div class='container'>
    <div class='row'>
      <div class='col-xs-12'>

        <!-- NAVBAR -->
        <nav class='navbar navbar-default' role='navigation'>
          <div class='navbar-header'>
            <a class='navbar-brand' href=''><?= title ?></a>
          </div>
        </nav>

        <div class='raw'>
          <div class='col-xs-12'>
            <button class='btn btn-primary' onclick='triggerServerSideFunc();'>
              trigger serverside func
            </button>
          </div>
        </div>

        <div class='raw'>
          <div class='col-xs-12'>
            <ul class="list-group">
              <? hoges.forEach(function(hoge) { ?>
                <li class="list-group-item"><?= hoge ?></li>
              <? }); ?>
            </ul>
          </div>
        </div>

      </div>
    </div>
  </div>

  <!-- includint javascript -->
  <script src='https://code.jquery.com/jquery-2.2.3.min.js'></script>
  <script src='https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js'></script>
  <?!= HtmlService.createHtmlOutputFromFile('client.js').getContent(); ?>
</body>
</html>

Javascriptコードの埋め込み

  • 変数の取り出しは<?= [式] ?>
  • 文の記述は<? [文] ?>
<ul class="list-group">
  <? hoges.forEach(function(hoge) { ?>
    <li class="list-group-item"><?= hoge ?></li>
  <? }); ?>
</ul>

インクルード

  • 他のテンプレートをインクルードするなら<?!= [式] ?>HtmlService#createHtmlOutputFromFileを使用
<?!= HtmlService.createHtmlOutputFromFile('client.js').getContent(); ?>

その他

bootstrapとfont-awesomeは個人的な好みです

クライアントサイドjs

client.js.html
<script>
$(function(){
  // 初期化処理
});

// merge/clean
function triggerServersideFunc() {
  var params = {
    param1: 'param1',
    param2: 'param2',
  };

  google.script.run.withSuccessHandler(function(result) {
    // resultはサーバーサイド関数の戻り値
    console.log(result.res1);
    console.log(result.res2);

  }).withFailureHandler(function(err) {
    // errはエラーオブジェクト
    console.log(err)

  }).func(params);
}
</script>
  • クライアントサイドからサーバーサイドの関数を実行するにはgoogle.script.run.[関数名]、引数はサーバーサイド関数の引数でOK
  • 成功時のコールバックは.withSuccessHandler()
  • 失敗時のコールバックは.withFailureHandler()

その他Tips

コードにべた書きしたくない設定ファイルはスクリプトプロパティに書いておける

script-prop.js
// 「スクリプトのプロパティ」からPROP1とPROP2を取得
var sp = PropertiesService.getScriptProperties();
var scProp1 = sp.getProperty('SC_PROP1') || 'prop1 default value';
var scProp2 = sp.getProperty('SC_PROP2') || 'prop2 default value';

// 「スクリプトのプロパティ」へPROP1とPROP2を設定
sp.setProperties({
  'SC_PROP1': params.param1,
  'SC_PROP2': params.param2,
});

トリガーの取得と設定

trigger.js
// 設定されているトリガーをすべて削除
ScriptApp.getProjectTriggers().forEach(function(trigger) {
  ScriptApp.deleteTrigger(trigger);
});

// 時間ベースのトリガーを設定
ScriptApp.newTrigger('triggeredFunction')
.timeBased().everyMinutes(10) // every 10 min.
.create();

外部サービスへのアクセスはUrlFetchAppを使う

access-api.js
// アクセス先
var url = 'https://url/to/application/api/you/want/to/access';

// リクエストパラメータ
var payload = { param1: 'param1', param2: 'param2' };

// フェッチ
var options = { method: 'POST', payload: payload };
var response = UrlFetchApp.fetch(url, options);

// JSON形式の返却値をオブジェクトへパース
var obj = JSON.parse(response.getContentText());

1
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
6