【GAS】トリガーをまとめてみた

GASを使用した際にトリガーを使う機会があったので調べてみました。
# トリガーの設定方法
トリガーには手動で設定する方法と、トリガーが自動で設定される関数名を用いる方法の2つのパターンがあります。
### その1.トリガーを手動で設定する

1. AppsScriptの左側にあるメニューからトリガーを選択


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3875975/3ef64580-7523-c394-2244-80f868809a05.png)
2. 右下にあるトリガーを追加ボタンをクリック

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3875975/f6af9753-3580-010c-929f-d6913dfbe7ed.png)
3. 実行したい関数とイベントの種類を選択し、保存する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3875975/e3e9399b-f57e-c398-4722-69b31e24a54c.png)

:::note warn
**onInstall・doGet・doPost**は手動でのトリガー設定はできません。
:::
### その2.トリガー付き関数名で設定する
関数名を以下のようにすることで、自動でトリガーを設定することができます。
|イベント|関数名|
|--|--|
| 起動時|onOpen|
| 編集時|onEdit|
| インストール時|onInstall|
| GETリクエスト送信時|doGet|
| POSTリクエスト送信時|doPost|

:::note warn
**フォーム送信時**は関数名でのトリガー設定はできません。
:::


# トリガーの概要と使用例
使用頻度の高そうなトリガーについて使用例とともに説明していきます。

## 起動時
スプレッドシートが開かれたときに実行するトリガーです。

以下のように設定してください。
* 手動で設定する場合：イベントの種類で**起動時**を選択
* 関数名で設定する場合：関数名を**onOpen**に設定

### 使用例
 * スプレッドシートが開かれたときにUIを追加
```Javascript:main.gs
function onOpen() {
  var ui = SpreadsheetApp.getUi();
  ui.createMenu('メニュー名').addItem('メニューアイテム', '設定したい関数').addToUi();
}
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3875975/56fc87f5-8f58-58e8-e775-374689bef91d.png)

こちらの例では、スプレッドシートが開かれたときにUIを表示するようトリガーを設定しておくことで、カスタムメニューを追加しています。

## 編集時
スプレッドシートのセルの値が変更されたときに実行するトリガーです。

以下のように設定してください。
* 手動で設定する場合：イベントの種類で**編集時**を選択
* 関数名で設定する場合：関数名を**onEdit**に設定
:::note info
**編集時と変更時の違い**
手動でトリガーを設定する際に、変更時という項目があります。
編集時ではセルの値を変更したときのみトリガーが発動します。
対して、変更時ではセルの値の変更に加えて、行や列の追加/削除・書式の変更などでもトリガーが発動します。
:::
### 使用例
* 特定のセルに記入があった場合に、他のセルに自動的に値を挿入
```javascript:main.gs
function onEdit(e) {
  var sheet = e.source.getActiveSheet();
  var range = e.range;

  if (range.getColumn() === 2 && range.getRow() > 1) { 
    var currentDate = new Date();
    var formattedDate = Utilities.formatDate(currentDate, Session.getScriptTimeZone(), 'yyyy/MM/dd');

    sheet.getRange(range.getRow(), 1).setValue(formattedDate);
  }
}
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3875975/49bc14eb-7ec5-95a4-d2c0-2b9af90a6440.png)

こちらの例では、B列に作業内容が記入されたとき、A列に記入した日付が挿入されます。

## フォーム送信時
フォームが送信されたときに実行するトリガーです。

以下のように設定してください。
* イベントの種類で**フォーム送信時**を選択

### 使用例
* フォーム入力者にメールを送信する

GoogleFormを作成し、**スプレッドシートで表示**より表示されたスプレッドシートからGASエディタを開き、関数を記入してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3875975/72ace5d7-010e-2ef9-edd6-4bcc3e61b1e9.png)
```javascript:main.gs
function onFormSubmit(e) {
  var email = e.values[1]; //[0]にはデフォルトでタイムスタンプが記入される

  var subject = "フォームの送信について";
  var message = "ご回答いただきありがとうございました。ご返答をしばらくお待ちください。";
  
  MailApp.sendEmail(email, subject, message);
}
```

こちらの例ではフォームを送信すると、記入したメールアドレスにメールが送信されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3875975/86c5534f-fadb-a03a-2d0c-f8853226531a.png)


## インストール時
アドオンが初めてインストールされたときに実行するトリガーです。
（つまり、初回実行時に１回だけ実行されます。）

以下のように設定してください。
* 関数名を**onInstall**に設定

### 使用例
* あらかじめ何かを記入したいとき
```javascript:main.gs
function onInstall(e) {
  createTable();
}

function createTable() {
  var properties = PropertiesService.getScriptProperties();
  var tableCreated = properties.getProperty('tableCreated');

  if (!tableCreated) {
    var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
    
    sheet.appendRow(['hello']);
    
    properties.setProperty('tableCreated', 'false');
  }
}
```


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3875975/135607d6-c250-da90-f50a-012c3ac1938d.png)

こちらの例ではスクリプトをはじめて実行したときにhelloと挿入するようになっています。


## GETリクエスト送信時
GETリクエストを送信することでスクリプトを実行するトリガーです。

以下のように設定してください。
* 関数名を**doGet**に設定


### 使用例
* スプレッドシートの内容をHTML形式で公開
（こちらの[サイト](https://www2.kobe-u.ac.jp/~tnishida/programming/GAS-02.html)を参考にしています。）

```Javascript:main.gs
function doGet() {
  let sheet = SpreadsheetApp.getActive().getActiveSheet();
  let values = sheet.getDataRange().getValues();
  let template = HtmlService.createTemplateFromFile("htmlFileName");
    template.links = values;
  return template.evaluate();
}
```
なお、HTMLファイルはファイル横のプラスマークからHTMLを選択することで作成できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3875975/1441bb28-e3ab-ef71-a268-dce7ef2b603e.png)

WebアプリケーションとしてデプロイしたURLにGETリクエストを送ると、doGetが実行され、スプレッドシートの内容をHTML形式で公開します。

## POSTリクエスト送信時
POSTリクエストを送信することでスクリプトを実行するトリガーです。

以下のように設定してください。
* 関数名を**doPost**に設定

### doPost使用例
* HTML上のフォームの回答結果をスプレッドシートで記録
```html:choice.html
<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
　</head>
 <h1>好きなアイスは？</h1>
    <form>
      <label>
        <input class="accented" type="radio" name="choice" value="イチゴ" checked> イチゴ
      </label>
      <label>
        <input class="accented" type="radio" name="choice" value="バニラ"> バニラ
      </label>
      <label>
        <input class="accented" type="radio" name="choice" value="チョコ"> チョコ
      </label>
    </form>
    <button class="btn" type="button" onclick="submitVote()">送信</button>

    <script>
    function submitVote() {
        const choice = document.querySelector('input[name="choice"]:checked');
        
        google.script.run.withSuccessHandler(function(result) {
          alert("投票ありがとう");
        }).doPost(choice.value);
      }
    </script>
  </body>
</html>
```
```Javascript:main.gs
function doPost(choice){
  var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('answer');
  sheet.appendRow([new Date(),choice]);
}
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3875975/76ad2712-8aa0-cc69-a143-ac5b4e537f3d.png)
こちらの例では、フォームが送信し、POSTリクエストが送信されるとスクリプトが起動し、スプレッドシートに回答が反映されます。