【LINE bot】GASで家計簿作った

GASでLINEのbotを作れると知ったので、GASやjavascに触ってみたくて作った。

#やったこと
- LINEビジネスアカウントを作成、LINEアカウントを開設
- GASでグーグルスプレッドシートと連携

開設方法、接続方法は下記サイトをそのまま参考にしました。
参考：[LINE BOTの作り方とは？Messaging APIを利用した作成法3選｜Udemy メディア](https://udemy.benesse.co.jp/development/app/line-bot-making.html "LINE BOTの作り方とは？Messaging APIを利用した作成法3選｜Udemy メディア") 


#アカウントの画面

|![IMG_9204.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689250/f420c08f-e95c-7896-8bb9-833191f511ee.jpeg)
|:--:|

※アカウントを削除後に送信したメッセージには、既読がついていない
※メッセージの送受信・スプレッドシート上の情報取得、編集が出来ることを確認したあとに削除したので、表示されるメッセージ等は後述するコードと異なる

|![IMG_9106.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689250/ab137229-42ce-c822-c7d8-e7b1f537c468.jpeg)
|:--:|

|![IMG_9113.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689250/b6e044f8-651d-44e1-69bb-fc8c1a65b401.jpeg)
|:--:|

※一度友だち登録した端末からはビジネスアカウント退会後にもトーク履歴などが表示されるが、他の人のスマホからは確認できない。

|![IMG_9107.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689250/65df2bcd-8a70-ceb9-5198-3039ab210106.jpeg)
|:--:|

※画面下部に開発者の名前が表示されている


#実装した機能
・一週間の予算を設定できる
・数字を入力すると、一週間の予算から減算される。利用料金と残高が表示される。
・月曜日になると、利用料金がリセットされる
・予算外利用料金を入力できる。入力された予算は、合算されていく。
・月始まりの1日になると、予算外利用料金がリセットされる

開設した公式アカウントの公開範囲を設定できなかったので、万が一、自分以外のLINEユーザーが使用して何かしらのデータを受け取ってしまうのが怖かったので、現在は削除しています。
(自分が切実にほしい機能だったので、ほかに何かいい方法ないかなあ。。。)
(GASの別の遊び方も考えたい)


#スプレッドシートはこんな感じ。

|![スクリーンショット 2021-07-13 175436.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689250/2b1f29f7-4bcf-96d1-f7c1-34f708975380.png)
|:--:|
※「利用履歴」「予算外履歴」はそれぞれ「利用料金合計」「予算外料金合計」の間違い。


#書いたコードはこれ。
深夜に思い立って開発してから退会まで四時間ほどで、一部機能(指定日時の動作)はLINEアプリ上で動作確認をしていません。
スプレッドシートで確認しています。なので、下記コードでLINEアプリ上でそのまま動くか分からない。（スプレッドシートで確認していたときのコードをLINE API用に修正しています。）


```js
function doPost(e) {
   var replyToken= JSON.parse(e.postData.contents).events[0].replyToken;
   if (typeof replyToken === 'undefined') {
     return;
  }

  var url = '(https://api.line.me/v2/bot/message/reply)';
  var channelToken = '（ラインのトークン）';

  var input = JSON.parse(e.postData.contents).events[0].message;
  var message = 'こんにちは。\n使用方法を確認したい場合は、「help」コマンドを入力してください。';

  
  var sheetAc = SpreadsheetApp.getActive();
  var sheet = sheetAc.getSheetByName("シート1");

  /* 週間・月間にリセット */
  let date = new Date();
  let localDate1 = date.toDateString();
  // 一日(1)の場合、利用料金をリセット
  if (date.getDate() == 1) {
    let localDate2_s = sheet.getRange(5,3).getValue();
    let localDate2 = new Date(localDate2_s).toDateString();
    if(localDate1 != localDate2) {
      sheet.getRange(5,1).setValue(0);
      sheet.getRange(5,3).setValue(localDate1);
    }
  }
  // 月曜日（1）の場合、予算外合計値をリセット
  if (date.getDay() == 1) {
    let localDate2_s = sheet.getRange(6,3).getValue();
    let localDate2 = new Date(localDate2_s).toDateString();
    if(localDate1 != localDate2) {
      sheet.getRange(6,1).setValue(0);
      sheet.getRange(6,3).setValue(localDate1);
    }
  }

  if(input.type == 'text') {
    /* 小文字大文字の区別無のフラグ */
    let regexp1 = new RegExp(/^set/, 'i');
    let regexp2 = new RegExp(/^ot/, 'i');
    let regexp3 = new RegExp(/^[0-9]+$/);

    if(input.text.match('ありがとう')) {
      message = 'どういたしまして';

    } else if(input.text.match('help')) {
      message = "【help】 コマンドの説明\n" +
      "【now】　利用状況を表示します。\n" +
      "【set金額】 一週間の予算を、半角英数で設定します。一か月でリセットされます。\n" +
      "【半角数字】　半角数字のみを入力すると、一週間予算から減算されます。\n" +
      "【ot予算外金額】　予算外の合算合計値を表示します。一か月でリセットされます。";

     } else if(input.text.match('now')) {
      var total = sheet.getRange(1,2).getValue();
      var limit = sheet.getRange(2,2).getValue();
      var sum1 = sheet.getRange(5,1).getValue();
      var sum2 = sheet.getRange(6, 1).getValue();
      message = '一週間予算：' + total + '円\n' +
                '残高：' + limit + '円\n' +
                '利用料金：' + sum1 + '円\n' +
                '予算外合計：' + sum2 + '円';

    } else if(regexp1.test(input.text)) {
      /* 【set金額】 一週間の予算を、半角英数で設定します。一か月でリセットされます。 */
      /* 行番号と列番号指定してセルに書き出し */
      var sum = parseInt(input.text.slice(3), 10);
      sheet.getRange(1,2).setValue(sum);
      sum = sheet.getRange(1,2).getValue();
      message = '一週間予算を' + sum + '円に設定しました。';

     } else if(regexp2.test(input.text)) {
      /* 【ot予算外金額】　予算外の合算合計値を表示します。一か月でリセットされます。 */
      var price = parseInt(input.text.slice(2), 10);
      var sum = sheet.getRange(6,1).getValue();
      sheet.getRange(6,1).setValue(price + sum);
      sum += price;
      message = '利用料金：' + price + '円\n'+
                '予算外合計：' + sum + '円';

    } else if(regexp3.test(input.text)) {
      /* 【【半角数字】　半角数字のみを入力すると、一週間予算から減算されます。 */
      // 「過去の利用料金総合計」を取得
      var sum1 = sheet.getRange(5,1).getValue();

      
      var price = input.text; // 「利用料金」をメッセージから取得
      sheet.getRange(5,1).setValue(sum1 + price); // 「過去の利用料金総合計」と「利用料金（メッセージ）」の合計を、スプレッドシートに入力
      var sum2 = sheet.getRange(2,2).getValue(); // ↑の操作で更新された「予算残高」を取得（スプレッドシート上の関数で、「一週間予算」マイナス「利用料金総合計」が入力されているセル）
      message = '利用料金：' + price + '円\n'+
                '予算残高：' + sum2 + '円';
    }
  }

  var messages = [{
    'type': 'text',
    'text': message,
  }];

  UrlFetchApp.fetch(url, {
    'headers': {
      'Content-Type': 'application/json; charset=UTF-8',
      'Authorization': 'Bearer ' + channelToken,
    },
    'method': 'post',
    'payload': JSON.stringify({
      'replyToken': replyToken,
      'messages': messages,
    }),
  });
  return ContentService.createTextOutput(JSON.stringify({'content': 'post ok'})).setMimeType(ContentService.MimeType.JSON);
}
```


コードも記事も汚いので恥ずかしい。varをletにする気力も無かった。
みなさんすごい。