文系でも分かる、GASによる授業通知のLINE bot の作成 その② 〜GASとスプレッドシートの連携、日付のフォーマット〜

<a href="https://qiita.com/Ko001/items/9a6f9ec967f6e16171bb">文系でも分かる、GASによる授業通知のLINE bot の作成 その①</a>の続きです。


1. <a href="https://qiita.com/Ko001/items/9a6f9ec967f6e16171bb">文系でも分かる、GASによる授業通知のLINE bot の作成 その① 〜GASを使ったLINE botの作成〜</a>
2. 文系でも分かる、GASによる授業通知のLINE bot の作成 その② 〜GASとスプレッドシートの連携、日付のフォーマット〜　←今回
3. <a href="https://qiita.com/Ko001/items/c2b1367a6c935acbdfa0">文系でも分かる、GASによる授業通知のLINE bot の作成 その③</a>
4. <a href="https://qiita.com/Ko001/items/d35a74e3be452198b8f2">文系でも分かる、GASによる授業通知のLINE bot の作成 その④　〜setTriggerを使って、指定の時間にプッシュ通知を送る〜</a> 

#この記事でわかること
* GASとスプレッドシートの連携・情報の取得方法
* 日付のフォーマットの仕方
* 連想配列について

#今回やること
* GASとスプレッドシートの連携
* 要件②「月曜4限」などと入力するとその時間の授業の情報を返してくれる機能の追加
<br>a. 授業情報を取得する関数の作成
<br>b. 曜日と時間がメッセージで送られてきた時に、その情報を返すコードを ```function doPost(e)``` に追加

![Screen Shot 2020-11-19 at 17.37.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/772803/49d73454-9c5a-3071-5be6-5b82f0fbd3e7.png)

#GASとスプレッドシートの連携の詳しい解説
この記事がわかりやすいです。
https://tonari-it.com/gas-spreadsheet-get-sheet/

#授業情報を取得する関数の作成
まずは実際のコードから

```GAS:Code.gs
//★★スプレッドシートID★★
var ss = SpreadsheetApp.openById("スプレッドシートIDを入れてください");
//★★シート名★★
var sheet = ss.getSheetByName("シート名を入れてください");

function doPost(e){
//中身省略
}

//パラメータで授業名が入っているセルの行番号と列番号を取得
function getClassInfo(rowNum, dateColumn){
　//授業名を取得
  var className = sheet.getRange(rowNum, dateColumn).getValue();
　//授業の曜日
  var classDay = sheet.getRange(1, dateColumn).getValue();
　//何時間目か
  var classNum = sheet.getRange(rowNum, 1).getValue();
  //始業時間
  var startTime = Utilities.formatDate( sheet.getRange(rowNum + 1, 1).getValue(), 'Asia/Tokyo', 'HH:mm');
　//終業時間
  var endTime = Utilities.formatDate( sheet.getRange(rowNum + 3, 1).getValue(), 'Asia/Tokyo', 'HH:mm');
　//授業のzoomID
  var zoomID = sheet.getRange(rowNum + 1, dateColumn).getValue();
  //zoomのパスワード
  var zoomPass = sheet.getRange(rowNum + 2, dateColumn).getValue();
　全ての情報を連想配列に入れる
  var classInfos = {className: className, classDay: classDay, classNum: classNum, startTime: startTime, endTime: endTime, zoomID: zoomID, zoomPass: zoomPass};
  return classInfos;
}
```

授業名が書かれているセルを基準に、他の情報も取得しています。例えば、ZoomIDが書いてあるのは授業名の一列下だから、 ```(rowNum + 1, dateColumn)``` の位置など。

また、時間の取得に関しては、スプレッドシートで「18:00」などと時間だけしていると、日付が勝手に1899年12月30日となり、取得される情報も日付を含んだ状態になるので、```Utilities.formatDate(日時、タイムゾーン、フォーマット)```で「18:00」とだけ表示されるようにしています。

そして全ての情報を連想配列（後述）に入れ、 ```return classInfos`` で戻り値として指定することで、 ```function doPost(e)```の中でも classInfos　の情報が使えるようにしています。

# 曜日と時間がメッセージで送られてきた時に、その情報を返すコードを ```function doPost(e)``` に追加
完成したコードはこちら

```GAS:Code.gs
function doPost(e) {
  var event = JSON.parse(e.postData.contents).events[0];
  var returnMessage = "曜日と時限（半角：1〜7)を指定してね！\n次の授業が知りたいときは、「次」と入力してね！";
  if(event.source.userId == user_id){
    //返信するためのトークン取得
    var reply_token= event.replyToken;
    if (typeof reply_token === 'undefined') {
      return;
    }
    //以下今回追加したコード
　　//テキストメッセージの内容を取得
    var message = event.message.text;
    for(let i=3; i<=7; i ++) {
      var dateColumn = i;
　　　　//スプレッドシートに書いてある曜日を使って順番に日曜日から土曜日まで検索していく
      var day = sheet.getRange(1, i).getValue();
　　　　//ラインメッセージが曜日を含んでいた時
      if(message.includes(day)){
        for(let j=2; j<=26; j += 4) {
　　　　　　//1限から7限まで順番に検索
          var classNumRow = j;
　　　　　　//時限（1限とか）の数字を取得
          var classNum = sheet.getRange(j, 1).getValue();
　　　　　　//メッセージがその時限の数字を含んでいて、その曜日・時限の授業名がある場合
          if(message.includes(classNum) && sheet.getRange(classNumRow, dateColumn).getValue()){
　　　　　　　// function getClassInfo を起動
            var classInfos = getClassInfo(classNumRow, dateColumn);
　　　　　　　//ラインに返信するメッセージを設定
            var returnMessage = classInfos.classDay + "曜" + classInfos.classNum + "限 (" + classInfos.startTime + "-" + classInfos.endTime + 
              ")\n授業名：" + classInfos.className + 
                "\nZoomID: " + classInfos.zoomID + 
                  "\nPass: " + classInfos.zoomPass;
            reply(reply_token, returnMessage);
　　　　　　　　//指定した曜日の時限に授業がない場合
          } else if(message.includes(classNum) && !sheet.getRange(classNumRow, dateColumn).getValue()) {
            var returnMessage = "授業はありません。"

            reply(reply_token, returnMessage);
          }
        }
      }
    }
  }
}
```

ざっくり説明をすると、for 文を使って、スプレッドシートのセルにある曜日を取得してその曜日がメッセージに含まれているか判別する⇨存在する場合もう一つfor 文を使って、スプレッドシートから授業時限の数字を取得して、それがメッセージに含まれているか判別するという感じです。
for 文の数字と取得するセルの位置を見比べて、どう動いているのか理解してみてください。

###連想配列について
```function getClassInfo``` で取得した授業の情報を ```function doPods(e)``` で使いたいのですが、そのために、使いたい情報を一つにまとめて、 ```return``` で送っています。
情報を一つにまとめるために連想配列を使っていて、 ```classInfos.className``` のように```変数名.key名``` で呼び出すことができます。

ここまでできたら更新して、授業の検索ができるか試してみましょう。

次の記事↓
3. <a href="https://qiita.com/Ko001/items/c2b1367a6c935acbdfa0">文系でも分かる、GASによる授業通知のLINE bot の作成 その③</a>