[GAS] Google スプレッドシートで独自メニューボタンからメール送信
Google Apps Script (GAS) で、スプレッドシートのメニューのところにカスタムボタンを作って、ボタンを押すとメールを送信するサンプルコード。
Google スプレッドシートには、スプレッドシートを変更したらメールで通知する機能があるが、特定のメールアドレスを設定できない上、通知のタイミングが「変更が入ったとき」となる。入力が完了した(タイポとかのチェック含め)タイミングで、特定のメールアドレスに通知したいので、 GAS を使って通知機能を作る。
作るもの
こんなスプレッドシートで、メニューのところにボタンがある。

ボタンを押すと、最終行に入力されたデータを記載したメールが送信される。
件名:通知があります。 本文: リクエストがきました。 3 △△△ 2019/03/03 00:00:00 リクエスト3 2019/03/1 00:30:05
スクリプト
function onOpen() {
  var ui = SpreadsheetApp.getUi();
  var menu = ui.createMenu('通知する');
  menu.addItem('通知', 'send_request');
  menu.addToUi();
}
function send_request() {
  var emailAddress = ['test@abc.com'];
  // 件名
  var subject = '通知があります。';
  // メール本文
  var body = 'リクエストがきました。\n\n';
  var sheet = SpreadsheetApp.getActiveSheet();
  var cVal = sheet.getRange('C:C').getValues();
  var lastRow = cVal.filter(String).length;
  // Range は、行番号,列番号,行数,列数 の順で指定
  var data = sheet.getRange(lastRow,1,1,4).getValues();
  data.forEach(function(val){
    body += val[0]+'  '+val[1]+'  '+Utilities.formatDate(val[3], 'America/Vancouver', 'yyyy/MM/dd HH:mm:ss')+'\n'+val[2]+'\n\n';
  });
  //現在日時を取得
  var now = new Date();
  body += Utilities.formatDate(now, 'America/Vancouver', 'yyyy/MM/dd HH:mm:ss');
  GmailApp.sendEmail(emailAddress, subject, body);
}独自メニューボタンの設置
onOpen() の中が、独自メニューボタンを作る部分。
onOpen() は元から用意されているメソッドで、スプレッドシートを開くと同時に呼び出され、実行される。シンプルトリガー( SimpleTrigger )と呼ばれているやつ。
Ui クラスを使って、メニューを追加している。 menu.addItem('××', 'hoge'); の部分は複数書くことができ、ボタンを増やすことができる。
onOpen() が使えないとき
onOpen() のようなシンプルトリガーは記述するだけで動くが、これを使うと最低レベルの権限でスクリプトが実行される。
そのためか、一部の関数が権限の問題で使えないことがあったり、 「〜する権限がありません」 エラーが出現する。
このような場合は、プロジェクト固有のトリガー( InstallableTrigger )を使う。
- 起動時に呼び出す関数名を「 onOpen 」以外に変更。ここでは「 open 」にした。 
- スクリプトエディター上部にある時計みたいなマークをクリック。  - GAS trigger setting button 
- 「トリガーを追加」をクリック。  - GAS trigger page 
- 「実行する関数の選択」で呼び出したい関数を、「イベントの種類を選択」で「起動時」を選んで「保存」。  - GAS trigger setting 
プロジェクトのトリガーを設定しても、これまでずっと動いていたのに、突然トリガーが動かなくなって、メニューボタンが表示されなくなることがある。
こうなると、新しいスプレッドシートで作り直さないとトリガーが効かない。作り直し以外の方法ないかな。。。
メールを送信する
send_request() が、メール送信部分。
GmailApp.sendEmail() でメールを送信する。
メール本文には、シートに追加された「リクエスト」のみ記載するため、 sheet.getRange('C:C').getValues(); で「リクエスト」が書かれる C のセルの値をすべて取得し、 cVal.filter(String).length; で、C セルに値のある最終行番号を取得して、範囲( Range )で使用する。
filter(String) が値のあるセルのみ取得してくれる。
セルに入力された日付データは、 yyyy-MM-dd って入力されていても、文字列( Tue Feb 14 2016 00:00:00 GMT+0900 (JST) こんなん)で出力されるので、 Utilities.formatDate() を使ってフォーマットする。