イベントに反応してスクリプトを実行する

決まった時間になったら実行されるスクリプトとか、フォームに入力されたら実行されるスクリプトを作るのにはどうしたらいいのだろう。そういう時のために、Google Apps スクリプトは、シンプルイベントハンドラーや、インストール可能イベントハンドラーという、時間やイベントでスクリプトが実行されるような関数を簡単に書く方法を搭載してる。


それぞれのシステムの詳細や違いを見る前に、イベントに使う用語を見てみよう。イベントとは一般的に起こった事柄と考えられてる。例を下に示すと

  • 時計が一時を指した
  • スプレッドシートが開かれた
  • スプレッドシートが編集された
  • フォームが送信された
他の多くのコンピューター言語と同様に、Google Apps スクリプトではこれらのイベントは、イベントトリガーとか、単にトリガーとか呼ばれてる。そしてイベントで呼ばれるコードはイベントハンドラーとして知られている。常にではないがしばしば、イベントを表す引数がコードによってイベントハンドラーに送られる。この引数もイベントと呼ばれる。



シンプルイベントハンドラー

シンプルイベントハンドラーはGoogle Apps スクリプト言語に組み込まれてる。イベントハンドラーを使うには、どんなタイプのイベントが関数を実行するのかわかるような特別な名前を関数に与える必要がある。以下の条件でシンプルイベントハンドラーを使用する。

  • スクリプトがスクリプトギャラリーからインストールされた時、onInstall関数をつかう
  • スプレッドシートが開かれた時、onOpen関数を使う
  • スプレッドシートが編集された時、onEdit関数を使う
シンプルイベントハンドラーはスプレッドシートの編集者のアクションによって実行され、その時の実行設定等はその編集者であるユーザーのものを使用する。もしボブがスプレッドシートを開いたなら、誰がそのスプレッドシートにスクリプトを組み込んだかに関わらず、onOpen関数はボブというユーザーの下で実行される。そのため、シンプルイベントハンドラーは以下のような制限がある。

  • スクリプトを含んだスプレッドシートを編集するにはそのスプレッドシートは開かれなければならない
  • シンプルイベントハンドラーは現在のユーザーが誰かを知ることができない
  • シンプルイベントハンドラーはユーザー認証が必要なサービスにアクセスできない。例えば、Google翻訳サービスは匿名可能なので、シンプルイベントハンドラーでもアクセスできるが、カレンダー、メールやサイトは匿名不可なのでアクセスできない
  • シンプルイベントハンドラーは今開いてるスプレッドシートを更新できるが、他のスプレッドシートにはアクセスできない

イベントセキュリティの更なる情報は Understanding Permissions and Script Execution.

onOpen()

onOpen関数はユーザーがスプレッドシートを開いた時自動的に実行される。しばしばスプレッドシートのメニューバーにカスタムメニューを加えるのに使われる。


// onOpen関数はスプレッドシートが開かれる度に自動的に実行される
function onOpen() {
 
var ss = SpreadsheetApp.getActiveSpreadsheet();
 
var menuEntries = [];
 
//ユーザーが "addMenuExample" メニューを選択して、 "Menu Entry 1"をクリックした時 function1関数は実行される.
  menuEntries
.push({name: "Menu Entry 1", functionName: "function1"});
  menuEntries
.push({name: "Menu Entry 2", functionName: "function2"});
  ss
.addMenu("addMenuExample", menuEntries);
}

onEdit(event)

onEdit関数はスプレッドシートのどこかのセルが編集されると自動的に実行される。単純な使用方法としては、セルの最終更新時間をコメントに残すというのがある。関数に引き渡される引数 e は1つだけプロパティを持っている。それは source でこれは今,編集中のスプレッドシートを指す。


function onEdit(event)
{
 
var ss = event.source.getActiveSheet();
 
var r = event.source.getActiveRange();
  r
.setComment("Last modified: " + (new Date()));
}

onInstall()

onInstall関数はスクリプトギャラリーからスクリプトをインストールした時に呼び出される。よくある使用方法はonOpenと同様にカスタムメニューの設定である。onOpen関数は最初にスクリプトがインストールされた時は、すでにスプレッドシートが開かれている状態のため実行されない。インストールしてすぐに行いたいタスクのメニューが必要なとき、onInstallからonOpenを呼ぶことができる。例は次のように


// onInstallからonOpenを呼ぶ
function onInstall()
{
  onOpen
();
}
// その後スクリプトが開かれたらonOpenが実行されることになる
function onOpen()
{
// コード
}

インストール可能イベントハンドラー

インストール可能イベントハンドラーはスクリプトエディタ内のトリガーメニューで選択する。ここからここではトリガーと呼ぶことにする。トリガーを使うのは以下のような場合:

  • 特定の時間に達した時 年月日時、分、秒を指定できる。
  • フォームが送信された時
  • スプレッドシートが編集された時 シンプルイベントハンドラーのonEditとの違いは、インストール可能イベントハンドラーは、インストールしたユーザーとして動作する。
  • スプレッドシートが開かれた時 シンプルイベントハンドラーのonOpenとの違いは、インストール可能イベントハンドラーは、インストールしたユーザーとして動作する。
インストール可能イベントハンドラーは、シンプルイベントハンドラーと似ているが、次のような違いもある。

  • インストールしたユーザーとして実行される。イベントを引き起こしたユーザーとしてではなく。
  • インストールしたユーザーがアクセスできる全てのサービスに潜在的にアクセス可能である。
  • シンプルイベントハンドラーのようなアクセス制限がない、全てのことができるスクリプトである。
  • どのユーザーがイベントを引き起こしたかわからない可能性がある。時間イベントには重要なことではないが、ドキュメント変更イベントにおいて誰がドキュメントを変更したのかはわからないことになるだろう。
  • スクリプトをトリガーによって実行するのにスプレッドシートが開いてある必要がない。
ひとつ以上の関数にトリガーを接続できるし、いかなる関数も、複数のトリガーによって実行することができる。加えて、トリガー属性を加えて、トリガーの振る舞いを洗練させることができる。


トリガーがインストールしたユーザーのアイデンティティで動くのは、安全性の理由からである。あなたがインストールしたトリガーを、共同作業者が実行したとしても、あなたのアイデンティティでスクリプトは実行される。更なるこれに関する情報は、Understanding Permissions and Script Execution

イベントハンドラーをインストールするのに、カレンダーやメールやその他のサービスの認証が求められるかもしれないが、それはスクリプトが何をするかによる。


時限トリガーの使用

スクリプトを毎日、毎時間、もしくは毎週同じ日に実行したい時どうすればいいのだろうか?そういう時は以下のようにすればいい。


スクリプトをある時間、もしくは希望する時間に実行するには:

  1. Googleドキュメントから新たなスプレッドシートを作成
  2. スプレッドシートを保存
  3. ツール>スクリプトエディタを選択
  4. リソース>現在のスクリプトのトリガーを選択  No triggers set up. Click here to add one nowのメッセージと一緒にパネルが表示される
  5. リンクをクリック
  6. 実行の下のところから、スケジュールで実行したい関数を選択
  7. Eventsの下から、Timve-drivenを選択
  8. 最初のドロップダウンリストから、 Week timerDay timerHour timer, Minutes timerのいずれかを選択 そうすると選んだものによって一つ、または二つのリストが現われる。トリガーと関数をテストしたいなら、何日何時間も待たなくていいように、短い時間を選択しよう。
    1. Week timer   曜日と時間を選択
    2. Day timer    時間を選択
    3. Hour timer   時間の間隔を選択
    4. Minutes timer 分の間隔を選択
  9. 保存をクリック
  10. タイムゾーンを選択するには、ファイル>プロジェクトのプロパティからタイムゾーンを設定する


その他のインストール可能イベントハンドラーの使用

スクリプトを実行できるトリガーは3つある:


  • スプレッドシートを開く
  • スプレッドシートを編集する
  • フォームを送信する
例えば、フォームでデータをスプレッドシートに加えられる度に、データをを分析したり、既存のデータを更新したりする様な事が考えられると思う。


あるアクションがなされたらスクリプトが実行されるには:

  1. Google ドキュメントを開いて、新しいスプレッドシートを作成する
  2. 無題スプレッドシートをクリックして名前を変える
  3. ツール>スクリプトエディタを選択
  4. リソース>現在のスクリプトのトリガーを選択  No triggers set up. Click here to add one nowのメッセージと一緒にパネルが表示される
  5. リンクをクリック
  6. 実行の下のところから、トリガーで実行したい関数を選択
  7. Eventsの下から、From Spreadsheetを選択
  8. 次のドロップダウンリストからOn open,On edit、On formのいずれかから選択
  9. 保存をクリック



更に詳細なイベント

イベントイベントハンドラーに引数 e として渡される。その引数 e 属性(アトリビュート)を付け加えて、トリガーがどう働くかや、どうスクリプトがトリガーされるのかといった情報を手に入れることができる。


もし属性を使うなら、上のセクションに書いたとおり、トリガーメニューからトリガーをセットしないといけない。

ここに例として、フォームが送信された際に、ある個人に向けてスプレッドシートによって取り出した情報を元に、メールを送る関数を示す。

// フォームは二つのフィールドを持つものとする (name and age)
function onFormSubmit(e) {
 
var timestamp = e.values[0];
 
var name = e.values[1];
 
var age = e.values[2];
 
// namedValues はAppsユーザーの送信者のみ利用可能で
 
// フォームは送信する前にサインインが必要となる
 
var submitter = e.namedValues["Username"];

 
MailApp.sendEmail("email_username", "form submitted",
                   name
+ ", age " + age + " submitted by " + submitter + " on " + timestamp + ". ");
}

この関数内で、引数 e によってイベントの詳細は捕獲されスクリプト内で使用可能になる。スプレッドシートのフォーム送信イベントでは、e.valuesにアクセスして詳細を手に入れる。Google Appsではフォームは自動的に送信者のユーザー名を記録する。それは e.namedValues["Username"] で使用することができる。

補足: e.namedValuesはGoogle Appsのみで利用可能で、一般的なGoogleアカウントでは使えない。

この例では、e.values は配列になっていて、ユーザーからフォームによって送信された値を全て含んでいる。e.values[0]はフォームが送信されたタイムスタンプを返し、 e.values[1] ,e.values[2] .... e.values[nは送信者の送った値で順番はスプレッドシートの列の順になっている。

トリガーによって利用可能属性(アトリビュート)は次のテーブルの様になる:

時間イベント

NameExample DescriptionHow to access
year 2010  e.year 
month12between 1-12e.month
day-of-month31one-based e["day-of-month"]
day-of-weekMonday is day 1, Sunday is day 7e["day-of-week"]
hour23 between 0-23 e.hour
minute59  e.minute
second59  
e.second

スプレッドシートopenイベント

NameExampleDescriptionHow to access
userjohn@example.comRESERVED FIELD - NOT CURRENTLY DEFINEDn/a

スプレッドシート編集イベント

NameExampleDescriptionHow to access
userbill@example.comRESERVED FIELD - NOT CURRENTLY DEFINEDn/a
start rowFirst row of the edited rangee.range.rowStart 
end row10 Last row of the edited range e.range.rowEnd
start columnFirst column of the edited range 
("A" is column 1)
e.range.columnStart
end columnLast column of the edited range e.range.columnEnd

スプレッドシートフォーム送信イベント

NameExampleDescriptionHow to access
values["2010/03/12 15:00", "bob@example.com", "Bob", "27", "Bill", "28", "Susan", "25"]Array with values in the same order as they appear in the spreadsheet.e.values
namedValues{ Timestamp: ["2010/03/12 15:00"],
  Username: ["bob@example.com"],
  Name: ["Bob", "Bill", "Susan"],
  Age: ["27", "28", "25"]} 
Map of Column name to array of entered values.e.namedValues


イベントハンドラーのエラー

イベントハンドラーが失敗しても、スクリプトエディタでスクリプトを実行した時のようにエラー表示を見ることができない。Google Appsスクリプトは、メールでイベントハンドラーが失敗したことを知らせる。殆どの場合、スクリプトが失敗した結果のエラーが送られてくる。メールには失敗したイベントハンドラーを削除したり編集するためのリンクも一緒に書かれている。


初期状態では、メールは深夜に一日一回送られ、それには失敗したスクリプトのそれぞれの箇所についての情報が書かれている。送られてくる時間は変更可能である。送られてくるアカウントや、頻度も同様に変更できる。失敗したらすぐに送られてくるように設定することもできる。

初期状態の変更をするには:

  1. スクリプトエディタを開始する
  2. リソース>現在のスクリプトのトリガーのダイアログボックスから、Notificationsのリンクをクリック
  3. ドロップダウンリストから、メールアカウント、頻度、時間を選択
  4. OKをクリック

もしスクリプトをテストテストしている最中なら、すぐにエラーメッセージを見たいだろうけど、どうすればいいのだろう。それには、try-catchブロックでスクリプトを囲めばいい。下はエラーを捕まえてメールでエラーメッセージを送ることに特化したコードだ。


function myFunction(){
     
try {
         
// script code here
     
}
   
catch (e) {
         
MailApp.sendEmail("youremail@example.com", "Error report", e.message);
     
}
}