【GAS活用術⑤-2】その日にGoogleフォームから登録された内容をLINEでまとめて通知・通知文カスタマイズ編
Google Apps Script (GAS)を、もっと身近に、日々の暮らしに。
【GAS活用術⑤-1】では、前日にGoogleフォームから登録された件数をLINEで通知する方法をご紹介しました。
1日あたりの登録件数が多い場合や、登録件数だけ知りたい場合などには、有用かと思います。
今回は、前回の【GAS活用術⑤-1】のスクリプトを少しだけ変えて、その日に登録された内容をまとめてLINE通知する方法をご紹介していきます。
例えば、私が作成した読み聞かせの記録を登録するシステムでは、読み聞かせ当日の夕方に、その日に登録された記録をまとめて数十人が所属するLINEグループに通知するようにしています。
「今日、誰がどんな本を読んだのか」をまとめてLINEグループに送るのは、いい活動報告になりますし、せっかく登録してもらった記録の共有にもなります。
登録件数がある程度限られ、緊急性の高くないデータを、LINEグループに送るのであれば、この「その日に登録された内容をまとめてLINE通知する方法」がオススメです。
コード解説
前回の【GAS活用術⑤-1】同様、蓄積された回答データを保持する、スプレッドシート側にGASを設定していきます。
では、さっそくスクリプトを見ていきます。今回は、先にコード解説をしていきたいと思います。
function notifyDailyRegs(){
//指定のシート上のデータがある範囲の表示値を表形式(正しくは二次元配列)ですべて取得
let sheet = SpreadsheetApp.getActiveSpreadsheet().getSheets()[0]; //一番左のシートを取得
const table = sheet.getDataRange().getDisplayValues().slice(1); //ヘッダー行を除く
//今日の日付を取得
const date = new Date(); //現在時刻を取得
//date.setDate(date.getDate() -1); //日付を変更( 昨日なら-1、一昨日なら-2)
const today = Utilities.formatDate(date, 'JST', 'yyyy/MM/dd'); //日付書式を設定
//「A列の値の0文字目から10文字分(yyyy/MM/dd)が今日の日付と同じもの」を条件にフィルターをかける
const regs = table.filter(row => row[0].slice(0,10) == today);
//配列regsの行数が0より大きいならメッセージを生成してLINEで通知する
if(regs.length > 0){
//msgHeaderとmsgLinesにわけてメッセージを生成
const msgHeader = "\n本日、" + today + "に以下の記録が登録されました"
let msgLines = ''; //msgLinesの初期化
for(let i = 0; i < regs.length ; i++) { //配列regsの行数だけ繰り返し
msgLines += "\n" + regs[i][1] + ": "
+ regs[i][2] + ": "
+ regs[i][3] + ": "
+ regs[i][4] + ": "
+ regs[i][5] + ": "
+ regs[i][6] ;
}
console.log(msgHeader + msgLines);
const token = "★トークンをここに設定★"; //トークンを設定
//sendLine(msgHeader + msgLines, token); //sendLine関数でmsgHeaderとmsgLinesを通知
}else{
console.log("本日、" + today + "の登録はありませんでした");
}
}
※sendLine関数は【GAS活用術⑤-1】と同じなので、割愛しています。
notifyDailyRegs関数の前半は、前回【GAS活用術⑤-1】のNotifyCount関数と間違い探しのレベルでほぼ同じです。前回は「前日にGoogleフォームから登録された件数」でしたが、今回は「その日(当日)に登録された内容をまとめて」なので、前日か当日かという条件の違いだけです。
filterメソッドを使用しているところまでは同じですね。さて、違うのは次からです。
まず、if文で当日に登録された件数(regs.length)が0かどうかを確認しています。0でない場合(登録されたデータがある場合)のみ、通知文を生成してLINE通知しています。
通知文は、msgHeaderとmsgLinesに分けて生成しています。なぜ分けているのか、それぞれがどのような情報を表示するのかは、具体例を見た方がわかりやすいので、さっそくmsgLinesの方からみていきましょう。
msgLinesが生成されているのは以下のコードの部分です。簡単にいうと、二次元配列:regsを一行ずつ読んで、メッセージをmsgLinesにどんどん追加しています。
for(let i = 0; i < regs.length ; i++) { //配列regsの行数だけ繰り返し
msgLines += "\n" + regs[i][1] + ": "
+ regs[i][2] + ": "
+ regs[i][3] + ": "
+ regs[i][4] + ": "
+ regs[i][5] + ": "
+ regs[i][6] ;
}
「msgLines +=」の「+=」は、msgLinesにすでに入っている値に消さずに、さらに右辺の値を追加する、ということなので、一行ずつ読んで生成したメッセージをmsgLinesにどんどん追加していく、ということです。
以前、【GAS活用術④-2】の「通知文は人それぞれ スクリプトも人それぞれ」で通知文(newRegMsg2)をカスタマイズする方法をご紹介しました。今回は前回と違い、二次元配列ですが、処理としては一行ずつなので、この通知文をカスタイズする方法はほぼ一緒です。
違う点を改めて以下に整理します。
一次元配列ではなく、二次元配列:regsを一行ずつ行数分だけ処理する(for(let i = 0; i < regs.length ; i++)の部分)
「msgLines +=」の「+=」で、どんどん追加していく
二次元配列なので、regs[i][3]の形式で、行のインデックス番号はiとする
(このiは0から始まり、一行処理したら+1ずつ増えていく)
この時点では、大体どんなことをやっているか、イメージだけつけばOKです。
スクリプトのコピー・修正・動作確認
それでは、上記のスクリプトをコピーして、スプレッドシートのメニューバーから、拡張機能 > Apps Script を選択し起動したスクリプトエディタに貼りつけます。
msgHeaderとmsgLinesの部分は、お使いのスプレッドシートにあわせて、修正していく必要があります。【GAS活用術④-2】の「通知文は人それぞれ スクリプトも人それぞれ」でも紹介したように、基本ルールは以下の通りです。
文字は、” ”(ダブルクォーテーション)で囲む
変数(ここではregs[i][1]、regs[i][2]など)と文字は + で連結する
改行は、"\n" で記述する
( )を使う時は、どこで始まりどこで終わるかを意識して、必ず対にする
最後は ; で終わる
そして、msgHeaderでは各明細で共有する情報、msgLinesは各明細の詳細情報を出力するようにします。
まず上記のサンプルのスクリプトを実行して、徐々に変更していくとよいと思います。では、実際にどんな風に通知文をブラシュアップさせていくか、やってみましょう。
まずはmsgHeaderとmsgLinesをサンプルのまま実行してみます。
//msgHeaderとmsgLinesにわけてメッセージを生成
const msgHeader = "\n本日、" + today + "に以下の記録が登録されました"
let msgLines = ''; //msgLinesの初期化
for(let i = 0; i < regs.length ; i++) { //配列regsの行数だけ繰り返し
msgLines += "\n" + regs[i][1] + ": "
+ regs[i][2] + ": "
+ regs[i][3] + ": "
+ regs[i][4] + ": "
+ regs[i][5] + ": "
+ regs[i][6] ;
}
notifyDailyRegs関数のmsgHeaderとmsgLinesのところを記述したら、①保存して、②notifyDailyRegsを実行する関数として選択していることを確認して、③実行します。
実行ログを確認します。ちなみに今回は、登録件数が0の時は、以下のようなログを出力するようにしています。
テストの時は、今日の登録されたデータがない場合も多いと思うので、下記のように日付を変更するコードをコメントアウトして、何日か前のデータを、今日のデータとして抽出するようにするとよいでしょう。
ちゃんと対象データが抽出されたログをみてみます。
データは表示されていますが、まず、日付「2023/11/01」とタイプ「朝の本読み」が何度も出てきているのが気になります。日付「2023/11/01」のregs[i][1]は割愛し、タイプ「朝の本読み」はmsgHeaderの方へもっていくことにします。
regs[i][2]がタイプにあたりますが、[i]は繰り返しのfor文の中でしか使えないので、msgHeaderでは行インデックス番号0(1行目)のタイプを表示するようにregs[0][2]として書き換えます。
//msgHeaderとmsgLinesにわけてメッセージを生成
const msgHeader = "\n本日、" + today + "に" + regs[0][2] + "の記録が登録されました"
let msgLines = ''; //msgLinesの初期化
for(let i = 0; i < regs.length ; i++) { //配列regsの行数だけ繰り返し
msgLines += "\n" + regs[i][3] + ": "
+ regs[i][4] + ": "
+ regs[i][5] + ": "
+ regs[i][6] ;
}
また、①保存、②notifyDailyRegsを確認、③実行後、ログ確認します。
少しすっきりしましたね。次に、年(regs[i][3])と組(regs[i][4])の間の": "は不要なのでとり、人の名前の後には、"さん"をつけることにします。
また、本の名前2(regs[i][7])と本の名前3(regs[i][8])も表示されるようにして、読んだ本が複数ある場合は、" / "を間にいれ、本の名前全体は「」で囲んでみます。
//msgHeaderとmsgLinesにわけてメッセージを生成
const msgHeader = "\n本日、" + today + "に" + regs[0][2] + "の記録が登録されました"
let msgLines = ''; //msgLinesの初期化
for(let i = 0; i < regs.length ; i++) { //配列regsの行数だけ繰り返し
msgLines += "\n" + regs[i][3] + regs[i][4] + ": "
+ regs[i][5] + "さん「"
+ regs[i][6] + " / "
+ regs[i][7] + " / "
+ regs[i][8] + "」";
}
だいぶよくなってきました。ここからは応用編です。本の名前2と本の名前3が登録されていないときは、" / "が出ないように、【GAS活用術④-2】の「論理積演算子(&&)にもチャレンジ」で紹介した、論理積演算子(&&)を活用してみます。
//msgHeaderとmsgLinesにわけてメッセージを生成
const msgHeader = "\n本日、" + today + "に" + regs[0][2] + "の記録が登録されました"
let msgLines = ''; //msgLinesの初期化
for(let i = 0; i < regs.length ; i++) { //配列regsの行数だけ繰り返し
msgLines += "\n" + regs[i][3] + regs[i][4] + ": "
+ regs[i][5] + "さん「"
+ regs[i][6]
+ ( regs[i][7] && " / " + regs[i][7] )
+ ( regs[i][8] && " / " + regs[i][8] ) + "」";
}
複数、本の名前が登録されている時は、" / "で区切られ、一冊だけの時は" / "なしで表示されるようになりました。今度は、学童の本読みのデータを表示してみます。
学童の本読みの場合は、年と組にデータが入らないことになっているので、": "だけ表示されています。これをまた論理積演算子(&&)をつかって、書き換えてみます。
//msgHeaderとmsgLinesにわけてメッセージを生成
const msgHeader = "\n本日、" + today + "、" + regs[0][2] + "の記録が登録されました"
let msgLines = ''; //msgLinesの初期化
for(let i = 0; i < regs.length ; i++) { //配列regsの行数だけ繰り返し
msgLines += "\n" + (regs[i][3] && ( regs[i][3] + regs[i][4] + ": "))
+ regs[i][5] + "さん「"
+ regs[i][6]
+ ( regs[i][7] && " / " + regs[i][7] )
+ ( regs[i][8] && " / " + regs[i][8] ) + "」";
}
いい感じになってきました。
このように、notifyDailyRegs関数の修正・保存・実行・ログ確認を繰り返し、徐々に通知文の精度を高めていきましょう。
納得する通知文ができたらLINE通知するように変更
これでいいかな、と思う通知文が出来上がったら、LINE通知してみましょう。【GAS活用術⑤-1】同様、送り先のトークンを設定して、sendLine関数をコールする部分の、先頭の // を消すだけです。
その後、スクリプトを保存して、再度、notifyDailyRegs関数を実行します。
実行ログとLINE通知ではまたちょっと雰囲気が変わりますよね。必要に応じて、再度スクリプトを修正してみてもよいでしょう。
なお、今回は登録件数が0の時は、「登録はありませんでした」というログは出力しますが、LINE通知はしないようにスクリプトを記述しています。この辺りも好みに応じて修正してみてください。
テストが終了したら、日付変更のコードを再度コメントアウトするため、先頭に // をつけて、保存しておきましょう。
トリガーを設定する
最後は、notifyDailyRegs関数を毎日自動的に実行されるようにトリガーを設定します。スクリプトエディタの画面左端のメニューバーで「トリガー」を選択します。
既に【GAS活用術⑤-1】でNotifyCount関数に対して設定したものがあれば、それを編集しましょう。もちろん、新規にトリガーを設定してもいいです。
「実行する関数の選択」でnotifyDailyRegs、「イベントのソースを選択」で時間主導型、「時間ベースのトリガーのタイプ」で日付ベースのタイマーを選択し、「時刻」でどの時間帯に実行するのかを選択します。
トリガーを保存すれば、毎日、同じ時間帯に、その日に登録された内容がコンパクトに1つの通知になって、LINE通知されます。
これでGoogleフォームとLINE通知で、以下の4つのパターンをみたことになります。
【GAS活用術④-1】Googleフォームから送信されたら内容をLINEで通知・ほぼコピペ編
【GAS活用術④-2】Googleフォームから送信されたら内容をLINEで通知・通知文カスタマイズ編
【GAS活用術⑤-1】前日にGoogleフォームから登録された件数をLINEで通知
【GAS活用術⑤-2】その日にGoogleフォームから登録された内容をLINEでまとめて通知 (→今回はこれでした)
どのタイミングでどんな内容の通知を送りたいのか、よく考えた上で、Googleフォームから送信されたデータを元にLINE通知をしてみましょう。