[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 」にした。
スクリプトエディター上部にある時計みたいなマークをクリック。
「トリガーを追加」をクリック。
「実行する関数の選択」で呼び出したい関数を、「イベントの種類を選択」で「起動時」を選んで「保存」。
プロジェクトのトリガーを設定しても、これまでずっと動いていたのに、突然トリガーが動かなくなって、メニューボタンが表示されなくなることがある。
こうなると、新しいスプレッドシートで作り直さないとトリガーが効かない。作り直し以外の方法ないかな。。。
メールを送信する
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()
を使ってフォーマットする。