どうも。つじけ(tsujikenzo)です。このシリーズでは 「Googleフォームとイベントオブジェクトを極めよう」 について全6回でお送りします。今日は3回目です。
前回のおさらい
前回は、 「フォームの回答を集計しよう」 をお届けしました。集計ページの印刷やURLの公開、csv出力をご紹介しましたね。
さらに、「スプレッドシート連携」 と、 「フォーム送信時をトリガーとしたGASの実行」 ということで 「イベントオブジェクト」 も登場しました。

今回は、「トリガーとイベントオブジェクト」 をお届けします。
アジェンダ
1. JavaScriptにおけるイベントハンドラー
2. シンプルトリガー
3. インストーラブルトリガー
4. イベントオブジェクト
JavaScriptにおけるイベントハンドラー
「JavaScript」 とは、ブラウザで読み込みする、 「WEBの動作」 について記述されたソース言語(ファイル)のことです。
「WEBの動作」 とは、「ポップアップウィンドウを開く」 や 「ユーザーがクリックしたらブラウザ内の背景色を変える」 などの、WEBの表示に 動き を加えたものです。
WEBの動作は 「イベント」 とも呼ばれており、ブラウザ内で起こるさまざまな動作や出来事が 「イベントリファレンス」 として定義されています。
インターネットが登場して間もない頃は、「クリックする」「ウィンドウサイズを変更する」などの単純な動作しか操作できませんでしたが、ブラウザ上で 「ドラッグアンドドロップする」 が登場したときの驚きは今でも忘れられません。
さらに、ブラウザは日々進化しています。 [動画] に関するイベントや、 [WebVRイベント] と呼ばれる、VRディスプレイに対応したイベントなどが次々に開発されています。

この、 「イベント」 が発生したときに、呼び出される処理を 「イベントハンドラー」 と呼びます。JavaScriptでは、 「クリックする」 や 「ページが読み込まれる」 といった動作を 「イベント」 と呼び、イベントが発生したときに呼び出される 「onclick」 や 「onopen」 を 「イベントハンドラー」 と呼んでいますのでご注意ください。
通常は、 「onclick」 にユーザーが定義した関数などの処理が書かれていますので、onclick & 実行される関数 のことを 「イベントハンドラー」 と呼ぶことがありますが、間違いではありません。
GASにおけるイベントハンドラー
GASでは、 「イベントハンドラー」 のことを 「トリガー」 と呼んでいます。JavaScriptと同じように、 「onOpen」 や 「onEdit」 など、イベントよって動作するトリガー(※1)が用意されています。
※1 イベントによってトリガーが動作することを 「発火」 と呼びます。英語の trigger fire を直訳したものです。
トリガーは 「シンプルトリガー」 と 「インストーラブルトリガー」 の2種類が用意されています。種類によって発火する条件や、設置する条件が異なりますので、1つずつ見ていきましょう。
シンプルトリガー
公式リファレンスはこちらです。

メリット
- 使用する時は、アクティブ化する必要がない(ユーザーに承認を求めることなく自動的に起動する)
- GASの実行で発火することがない(Range.setValue()を実行しても、onEditトリガーは実行されない)
デメリット
- Googleスプレッドシート、スライド、ドキュメント、またはフォームのコンテナバインドに設置する必要がある
- ファイルが「読み取り専用」で開かれている場合は実行されない
- トリガー名を自由に設定できない
- 承認が必要なサービス(Gmail送信など)を呼び出すことができない
- バインドされているファイルは変更できるが、承認が必要な他のファイルにアクセスできない
- getActiveUser()が使える場合と使えない場合がある
- 30秒を超えて実行できない
※これらの制限は、 doGet(e) または doPost(e) には適用されません。
6種類のシンプルトリガー
シンプルトリガーの種類は多くありません。トリガー名も決まっているため、すべて覚えてしまってもかまいません。
下記は、トリガー名と発火条件になるイベント名の一覧です。それぞれ、スプレッドシートやフォームのコンテナバインドスクリプトに設置されることをイメージしてください。
トリガー名: イベント名
onOpen(e): 起動時
onEdit(e): 編集時
onSelectionChange(e): 選択変更時
onInstall(e): インストール時
doGet(e): GETリクエスト
doPost(e): POSTリクエスト
※(e)はイベントオブジェクト
インストーラブルトリガー
続いて、インストーラブルトリガーです。公式リファレンスはこちらです。

メリット
- 時間トリガーを設定できる
- GASの実行で発火することがない(FormResponse.submit() を実行しても、フォーム送信時トリガーは実行されない)
- 承認が必要なサービスを呼び出すことができる
- トリガー名を自由に設定できる
- onOpen()を設置したユーザーの承認を得たアカウントのみ実行させることができる
- GASで「削除、変更、追加」などの管理ができる
デメリット
- 使用する時は、アクティブ化する必要がある
- ファイルが「読み取り専用」で開かれている場合は実行されない
- 発火させたアカウントではなく、トリガーを作成したアカウントで実行される ※2
※2 について対応策は、後ほど紹介します。
インストーラブルトリガーのイベントソースとイベント
インストーラブルトリガーも、基本的な処理はシンプルトリガーと変わりません。しかし、シンプルトリガーと比べて 発火条件 が数多く用意されています。
また、発火するイベントの元になるコンテナバインドのサービス(スプレッドシートやフォームなど)や時間主導型のことを [イベントソース] と呼びます。
つまり、トリガーが発火する条件は、以下によって決められます。
・コンテナバインドかスタンドアロンスクリプトか
・どのイベントソースか
・どのイベントか
//コンテナバインドスクリプトで設定できるイベントソース5種類
- スプレッドシート
- ドキュメント
- フォーム
- カレンダーイベント
- 時間主導型
//[スライド]のコンテナバインド、もしくはスタンドアロンスクリプトにした場合のイベントソース2種類
- カレンダーイベント
- 時間主導型
//イベントソースを[スプレッドシートから]にした場合のイベント4種類
- 起動時
- 編集時
- 値の変更時
- フォーム送信時
//イベントソースを[ドキュメントから]にした場合のイベント1種類
- 起動時
//イベントソースを[フォームから]にした場合のイベント2種類
- 起動時
- フォーム送信時
//イベントソースを[時間主導型]にした場合のトリガータイプ5種類
- 特定の日時
- 分ベースのタイマー
- 時間ベースのタイマー
- 日付ベースのタイマー
- 週ベースのタイマー
- 月ベースのタイマー
//イベントソースを[カレンダーから]にした場合の設定
- カレンダー更新済み
- [カレンダーのオーナーのメールアドレスを入力]
インストーラブルトリガーのトリガー名は自由に設定できます。しかしながら、インストーラブルトリガーにもかかわらずトリガー名を onOpen() とするのは、あとでコードを読む人に不親切かもしれません。 onUserOpen() など、シンプルトリガーとは違うことを明示したほうがよいでしょう。
イベントオブジェクト
「シンプルトリガー」 と 「インストーラブルトリガー」 のどちらにも共通していることは、イベントが発生したときの情報を、 イベントオブジェクト(e) としてトリガーに渡すことです。
イベントオブジェクトはその名の通り、 オブジェクト です。下記のような {key:value}形式 で情報が格納されています。
//ドキュメントのonOpen()トリガーで返されるイベントオブジェクト例
e = {
authMode:enum property,
source: { Spreadsheet object },
triggerUid: '123456789',
user: { user object 'hoge@gmail.com'}
}
//スプレッドシートのフォーム送信時トリガーで返されるイベントオブジェクト例
e = {
authMode:enum property,
namedValues: {
'名前': ['つじけ'],
'Timestamp': ['6/7/2021 20:54:13'],
'参加されますか?': ['はい、参加します']
},
range: { range object },
triggerUid: '123456789',
values: ['2021/05/04 15:00', 'amin@example.com', 'つじけ', 'はい、参加します']
}
オブジェクトの値へのアクセス方法
イベントオブジェクトに 数値型や文字列 が格納されているプロパティは、ドット記法で直接呼び出すことができます。
console.log(e.triggerUid); //'123456789'
console.log(e.values); //['2021/05/04 15:00', 'amin@example.com', 'つじけ', 'はい、参加します']
一方で、イベントオブジェクトのなかには、 オブジェクト が格納されているプロパティもあります。
//オブジェクトが格納されているプロパティ例
//スプレッドシートから編集時トリガーで返される、rangeプロパティ
e = {range:{range object}}; //Range objectが格納されている
//フォームからフォーム送信時トリガーで返される、responseプロパティ
e = {response:{FormResponse object}}; //FormResponse objectが格納されている
オブジェクトが格納されているプロパティは、 各オブジェクトに用意されてるメソッド を使用して、アクセスします。
console.log(e.range.getA1Notation()); //'A1'
console.log(e.response.getRespondentEmail()); //'hogetaro@gmail.com'
メソッドはオブジェクトの公式リファレンスを確認しながら、必要な値を操作します。GASの公式リファレンスは充実していますので、戻り値やメソッドなどを、都度確認するようにしましょう。
まとめ
以上で、 「トリガーとイベントオブジェクト」 をお届しました。 シンプルトリガー と インストーラブルトリガー の違いを見比べながら、最後は イベントオブジェクト について紹介しました。
イベントオブジェクトにはさまざまな情報が含まれております。GASのトリガーの種類が多いということは、イベントオブジェクトの種類も豊富です。すべてを覚える必要はありませんので、必要に応じて公式リファレンスを確認しましょう。

次回は、「スプレッドシートのコンテナバインドのフォーム送信時トリガー」 をお届けします。