見出し画像

【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通知をしてみましょう。

この記事が気に入ったらサポートをしてみませんか?