0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

文系でも分かる、GASによる授業通知のLINE bot の作成 その③

Last updated at Posted at 2020-11-19

文系でも分かる、GASによる授業通知のLINE bot の作成 その②の続きです。

  1. 文系でも分かる、GASによる授業通知のLINE bot の作成 その① 〜GASを使ったLINE botの作成〜
  2. 文系でも分かる、GASによる授業通知のLINE bot の作成 その② 〜GASとスプレッドシートの連携、日付のフォーマット〜
  3. 文系でも分かる、GASによる授業通知のLINE bot の作成 その③ ←今回
  4. 文系でも分かる、GASによる授業通知のLINE bot の作成 その④ 〜setTriggerを使って、指定の時間にプッシュ通知を送る〜

#この記事でわかること

  • 日付の取得の仕方
  • スプレッドシートで取得した時間の計算方法

#今回やること

  • 要件③ 「次」と入力すると、1番近い授業の情報を返してくれる機能を追加
    Screen Shot 2020-11-19 at 22.11.03.png

#流れ(要件定義)

  • 「次」を含むメッセージが入力されると、
  • 今の日時を取得して
  • 次の授業の情報を返信する

#次の授業を取得する関数の作成

Code.gs
function findNextClass() {
  //今の日時を取得
  var today = new Date();
 //今の時間を取得
  var hour = today.getHours();
 //今の分を取得
  var minutes = today.getMinutes();
  console.log(today);
  for(let i=0; i <= 6; i++) {
  //今日の曜日から初めて、曜日を一つずつずらしていく
    var day = (today.getDay() + i) % 7;
    var dateColumn = day + 3;
    var array = ['日','月','火','水','木', '金', '土'];
  //何曜日を検索しているかコンソールに表示(デバッグ用)
    console.log("曜日:" + array[day]);
    
    var searchHour = 0;
  //もし、検索する曜日が今の曜日と一致しているなら今の時間から、そうじゃないなら朝6時から検索
    if(day == today.getDay()){searchHour = hour;} else { searchHour = 6;}
  //検索時間が24時になるまで、1時間ずつ足して計算する
    for(var j=0; j < 24-searchHour; j++) {
      console.log(searchHour + "時");
      for(let k=2; k <= 26; k+=4){
        var classNumRow = k;
        var startTimeRow = k + 1;  
        //始業時間が設定されている場合、始業時間を取得
        if(sheet.getRange(startTimeRow, 1).getValue()) {
          var startTime = sheet.getRange(startTimeRow, 1).getValue();
          var startHour = startTime.getHours();
          var startMinutes = startTime.getMinutes();
          console.log("start hour: " + startHour);
          //検索した時、今と検索時間の日付と時間が一致していても、今の分が始業の分を超えている場合は情報を取得しない          
          if(searchHour === startHour && today.getDay() === day && hour === searchHour && minutes > startMinutes){
            console.log("\nalready orver\n");
            //時間が一致し、授業が存在する場合、情報を取得
          } else if(searchHour === startHour && sheet.getRange(classNumRow, dateColumn).getValue()){
            var classInfos = getClassInfo(classNumRow, dateColumn);
            return classInfos;
          }
        }
      }
    //検索時間を1時間足す
      searchHour += 1;
    }
  }  
}

function getClassInfo(){
  //②で作ったもの
}

解説
今の時間に1時間ずつ足していく形で検索していきます。分は無視してXX時YY分のXXが始業時間と一致した時にその授業の情報を返します。
ただし、これだと 今が10:35で始業が同じ曜日の10:30の場合などに授業の情報を取得してしまうので、if(searchHour === startHour && today.getDay() === day && hour === searchHour && minutes > startMinutes) を使っています。
一つ前の記事で書いたように、スプレッドシートに記入した時刻は変な日付が設定されてしまうため、時間と分をバラバラに扱うことで、日付を無視できるようにしています。

function findNextClassfunction doPost(e)で動くようにする

今回までの完成形のコードになります。

Code.gs
var access_token = "自分のアクセストークン"
// 自分のユーザーIDを指定します。LINE Developersの「Your user ID」の部分です。
var user_id = "ユーザーID"

//★★スプレッドシートID★★
var ss = SpreadsheetApp.openById("スプレッドシートID");
//★★シート名★★
var sheet = ss.getSheetByName("シート名");

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) {
          var classNumRow = j;
          var classNum = sheet.getRange(j, 1).getValue();
          if(message.includes(classNum) && sheet.getRange(classNumRow, dateColumn).getValue()){
            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);
          }
        }
      }
    }
    
    if(message.includes("次")){
      var classInfos = findNextClass();
      var returnMessage = classInfos.classDay + "曜" + classInfos.classNum + "限 (" + classInfos.startTime + "-" + classInfos.endTime + 
        ")\n授業名:" + classInfos.className + 
          "\nZoomID: " + classInfos.zoomID + 
            "\nPass: " + classInfos.zoomPass;
      reply(reply_token, returnMessage);
    } else {reply(reply_token, returnMessage);}
  }
}

function reply(reply_token, returnMessage) {
  var reply_url = 'https://api.line.me/v2/bot/message/reply';

  // メッセージを返信 
  UrlFetchApp.fetch(reply_url, {
    'headers': {
      'Content-Type': 'application/json; charset=UTF-8',
      'Authorization': 'Bearer ' + access_token,
    },
    'method': 'post',
    'payload': JSON.stringify({
      'replyToken': reply_token,
      'messages': [{
        'type': 'text',
        'text': returnMessage,
      }],
    }),
  });
  return ContentService.createTextOutput(JSON.stringify({'content': 'post ok'})).setMimeType(ContentService.MimeType.JSON);
}

function findNextClass() {
  var today = new Date();
  var hour = today.getHours();
  var minutes = today.getMinutes();
  console.log(today);
  for(let i=0; i <= 6; i++) {
    var day = (today.getDay() + i) % 7;
    var dateColumn = day + 3;
    var array = ['日','月','火','水','木', '金', '土'];
    console.log("曜日:" + array[day]);
    
    var searchHour = 0;
    if(day == today.getDay()){searchHour = hour;} else { searchHour = 6;}
    for(var j=0; j < 24-searchHour; j++) {
      console.log(searchHour + "時");
      for(let k=2; k <= 26; k+=4){
        var classNumRow = k;
        var startTimeRow = k + 1;  
        //始業時間が設定されている場合、始業時間を取得
        if(sheet.getRange(startTimeRow, 1).getValue()) {
          var startTime = sheet.getRange(startTimeRow, 1).getValue();
          var startHour = startTime.getHours();
          var startMinutes = startTime.getMinutes();
          console.log("start hour: " + startHour);
          //検索した時、今と検索時間の日付と時間が一致していても、今の分が始業の分を超えている場合は情報を取得しない          
          if(searchHour === startHour && today.getDay() === day && hour === searchHour && minutes > startMinutes){
            console.log("\nalready orver\n");
            //時間が一致し、授業が存在する場合、情報を取得
          } else if(searchHour === startHour && sheet.getRange(classNumRow, dateColumn).getValue()){
            var classInfos = getClassInfo(classNumRow, dateColumn);
            return classInfos;
          }
        }
      }
      searchHour += 1;
    }
  }  
}

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');
  var zoomID = sheet.getRange(rowNum + 1, dateColumn).getValue();
  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;
}

ここまでできたら、また更新して、「次」とメッセージを送って正しく動くか確かめてみましょう。

次の記事↓
文系でも分かる、GASによる授業通知のLINE bot の作成 その④ 〜setTriggerを使って、指定の時間にプッシュ通知を送る〜

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?