はじめに
先日の 複数の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ファイルにベタ書きしても効かないので
setSandboxMode
とaddMetaTag
で設定する
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());