嫁「○○時○○分の○分後って何時何分？」

## はじめに
嫁「明日お料理教室だなあ〜、またバスの時間調べないと・・・」

嫁「えーっと・・・開始時間が**12時30分**だから行きのバスは**12時**でいいけど」

嫁「帰りのバスは、授業が**145分**だから12時30分の145分後は・・・」

嫁「ねえ、**12時30分の145分後って何時何分？**」


っていうやりとりをいつも嫁としているので嫁の~~質問に答えるのがめんどくさい~~ために
簡単に質問に答えてくれるツールを作りたいと思いました！

## 成果物
簡単に答えてくれる（気軽に聞ける）＆そこまで工数かけたくないということで今回は**LINE bot**を作ってみることにしました。

## 参考にした記事
今回は以下を参考にMessage APIとGAS（Google Apps Script）を使ったLINE bot作成を行ってみました。
[【LINE BOT】Messaging APIとGASでLINE BOTを作ってみた](https://qiita.com/gaosan/items/6ff75663b58ab133ef97)
[Google Apps Scriptでスプレッドシート内を検索して行番号を返す関数（高速版）](https://tonari-it.com/gas-spreadsheet-find/)

## ソースコード
```コード.gs
//アクセストークン 
var ACCESS_TOKEN = [アクセストークン];
//シートID 
var SPREADSHEET_ID = [シートID];

/*-------------------------------------------
メッセージが送付された際に、実行される関数
-------------------------------------------*/
function doPost(e){
  var replyToken = JSON.parse(e.postData.contents).events[0].replyToken; 
  var userMessage = JSON.parse(e.postData.contents).events[0].message.text;
  var userID = JSON.parse(e.postData.contents).events[0].source.userId;
  var retMessage = '「はじめる」で何分後か聞くことができるよ！';
  
  //対象のスプレッドシートを取得して更新する
  var targetSs = SpreadsheetApp.openById(SPREADSHEET_ID);
  var targetSht = targetSs.getSheetByName('シート1');
  var lastRow = targetSht.getLastRow();
  
  //ユーザーIDを検索
  var targetRow = findRow(targetSht, userID, 1);
  
  //「はじめる」の場合
  if(userMessage === 'はじめる') {
    if(targetRow === 0) {
      //ユーザーIDが見つからない場合
      //ユーザーIDをA列に保持
      targetSht.getRange('A' + (lastRow + 1)).setValue(userID);
    } else {
      //ユーザーIDが見つかった場合
      //B列の時間をクリア
      targetSht.getRange('B' + targetRow).clear();
    }
    //次の質問
    retMessage = '何時何分から？';
  } else {
    if(targetRow !== 0) {
      //ユーザーIDが見つかった場合
      var time = targetSht.getRange('B' + targetRow).getValue();
      if (time) {
        //時間入力済みの場合
        //○分後時間を進めた値を入れる変数に一旦進める前の時間を格納
        var date = time;
        //正しい時間を入力していたかどうか？
        if (Number.isInteger(Number(userMessage.split("分")[0]))) {
          //正しい時間を入力していた場合
          //○分後時間を進める
          date.setMinutes(date.getMinutes()+Number(userMessage.split("分")[0]));
          var bHour = Utilities.formatDate(targetSht.getRange('B' + targetRow).getValue(), 'Asia/Tokyo', 'H');
          var bMinute = Utilities.formatDate(targetSht.getRange('B' + targetRow).getValue(), 'Asia/Tokyo', 'm');
          var etime = Number(userMessage.split("分")[0]);
          var aHour = Utilities.formatDate(date, 'Asia/Tokyo', 'H');
          var aMinute = Utilities.formatDate(date, 'Asia/Tokyo', 'm');
          //〇〇時〇〇分の○分後は何時何分の答え
          retMessage = bHour + '時' + bMinute + '分の' + etime + '分後は…' + '\n' + '\n' + '≪ ' + aHour + '時' + aMinute + '分 ≫' + '\n' + '\n' + 'です！';
        } else {
          //正しい時間をしていない場合
          retMessage = '「〇〇分」または「〇〇分後」の形で送ろう！';
        }
      } else {
        //時間未入力の場合
        //「時」のチェック
        var hourOK = false;
        var hour = userMessage.split("時")[0];
        if (Number.isInteger(Number(hour)) && Number(hour) > -1 && Number(hour) <25){
          hourOK = true;
        }
        //「分」のチェック
        var minuteOK = false;
        var retString = userMessage.split("時");
        if (retString.length > 1) {
          var minute = userMessage.split("時")[1].split("分")[0];
          if (Number.isInteger(Number(minute)) && Number(minute) > -1 && Number(minute) <60){
            minuteOK = true;
          }
        }
        //正しい時間を入力していたかどうか？
        if (hourOK && minuteOK) {
          //正しい時間を入力していた場合
          //時間をB列に保持
          targetSht.getRange('B' + targetRow).setValue(Utilities.formatDate(new Date(2020,1,1,hour,minute), 'Asia/Tokyo', 'HH:mm'));
          //次の質問
          retMessage = '何分後？';
        } else {
          //正しい時間を入力していない場合
          retMessage = '「〇〇時〇〇分」の形で正しい時間を送ろう！';
        }
      }
    }
  }
  
  var url = 'https://api.line.me/v2/bot/message/reply'; 
  var headers = { 
    'Content-Type': 'application/json; charset=UTF-8' ,
    'Authorization': 'Bearer ' +ACCESS_TOKEN 
  };
    
  //メッセージ送信内容
  var payload = JSON.stringify({
    'replyToken': replyToken ,
    'messages': [{   
      'type': 'text' ,
      'text': retMessage
    }] 
  } ) 
    
  var options = { 
    'headers' : headers ,
    'method' : 'post' ,
    'payload' : payload }; 
    
  // メッセージを送信
  UrlFetchApp.fetch(url ,options)
}

/*-------------------------------------------
対象行検索処理
-------------------------------------------*/
function findRow(sheet,val,col){

　//受け取ったシートのデータを二次元配列に取得
  var dat = sheet.getDataRange().getValues();

　//対象行を検索
  for(var i=1;i<dat.length;i++){
    if(dat[i][col-1] === val){
      return i+1;
    }
  }
  return 0;
}
```

## 仕組み
以下のようにA列にユーザーID、B列に時間を保持し、何分後か入力されたら保持していた時間＋○分後した値を返すようなロジックにしています。
※「はじめる」と入力したら時間リセット
![スクリーンショット 2020-10-11 16.30.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/181865/1379a22a-d2c6-9583-dcdd-c1b4ce2fd13d.png)



## 完成イメージ
![IMG_5EF97650F5AB-1.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/181865/af821fc0-47ab-fb04-abd6-cbeadfc23330.jpeg)

## まとめ
GASに関してはJavaScriptの知識が必要となってきますが、Message APIとGASの連携で簡単にLINE botを作成することができました。

LINEはよく使う身近なツールなのでそれを使ってちょっとした悩みもすぐに解決できればとても良いですよね。

これを機にいろいろな便利botを作ってみたいと思います！


### 何分後何時何分？
![964xhxqp.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/181865/0611667d-d4db-a461-5f4b-69002cc8a307.png)