🌟

LINE Botで起床時間を記録できるアプリを作った話

2023/07/10に公開

はじめに

起床時間を自ら記録すれば早起きできるようになるのでは!?

と思い起床時間を記録できるLINE Botを作りました。
https://twitter.com/_hid3/status/1677298232077205511?s=20

アプリの紹介

おはもに-生活改善LINE Bot-
https://lin.ee/wqGf3WK

アカウントとともだちになります。

下部メニューの「起きた時間を記録」をタップします。

すると、起きた時間を教えてください、と返答が戻ってきます。
「日時を選択する」で起きた時間を入力します。

起きた時間が記録でき、直近1週間の記録が返ってきます。

どうしてiOSやAndroidのアプリではないのか?

自分の開発経験がないので。

ちなみに、
LINE Botのメリットとしては、使う側の導入の簡単さがあるかなと思います。
インストール不要でアカウントを友達に追加するだけで利用することができるので。

技術スタック

  • GCP
    • Cloud Run, Cloud SQLなど
  • NestJS, TypeScript
  • LINE
    • Messaging API

日時選択メッセージを返す

リッチメニューの「起きた時間を記録」をタップすると、日時選択メッセージを返すようにしています。
使う人の自由入力だとデータ保存時のフォーマットなどが大変なので、LINのMessaging APIに用意されてるテンプレートメッセージ日時選択アクションを利用しています。

以下の感じで、LINEのメッセージを受けった時にメッセージの種類によって分岐させています。
テンプレートメッセージでアクションとして日時選択アクションを指定してメッセージを返答しています。

 if (event.type === "message") {
      const messageEvent = event as MessageEvent;
      const message = messageEvent.message;
      if (message.type === "text") {
        const text = message.text;
        if (text === "記録") {
          await this.linebotClient.replyMessage(messageEvent.replyToken, {
            type: "template",
            altText: "起きた時間を教えてください",
            template: {
              type: "buttons",
              text: "起きた時間を教えてください",
              actions: [
                {
                  type: "datetimepicker",
                  label: "日時を選択する",
                  mode: "datetime",
                  data: this.gotUpActionData,
                },
              ],
            },
          });
        }
      }
    }

SDKは公式のSDKがあるので使っています。
https://github.com/line/line-bot-sdk-nodejs
TypeScriptの型にも対応しているので便利です。

時間をタイムゾーンを意識してフォーマットする

素のTypeScriptでフォーマットをしているとタイムゾーン周りで間違えやすそうだなと思ったのでライブラリを使うことにしました。
date-fns-tzを使いました。
そこまで深い選定理由はなく、ポピュラーでシンプルそうだったので。

上記のLINEの日時選択アクションで日時を選択すると
2023-07-06T21:05
のようなフォーマットの文字列で、日本時間で送信されてきます。

DBに保存する時は一応UTCでも保存したく、date-fns-tztoDate()を利用しています。

const datetimeInJST = "2023-07-06T21:05";
const gotUpAt = toDate(datetimeInJST, { timeZone: "Asia/Tokyo" });

これで実行環境のタイムゾーンに関わらずUTCのDateにできます。

動作を試してみたものの結果も貼っておきます。

// datetimeInJST 2023-07-06T21:20
    
// console.log("toDate1", toDate(datetimeInJST, { timeZone: "Asia/Tokyo" }));
// console.log("toDate2", toDate(datetimeInJST, { timeZone: "UTC" }));
// console.log("toDate3", toDate(datetimeInJST));
    
// 実行環境タイムゾーン日本
// toDate1 2023-07-06T12:20:00.000Z
// toDate2 2023-07-06T21:20:00.000Z
// toDate3 2023-07-06T12:20:00.000Z

// 実行環境タイムゾーンUTC
// toDate1 2023-07-06T12:20:00.000Z
// toDate2 2023-07-06T21:20:00.000Z
// toDate3 2023-07-06T21:20:00.000Z

起床時間を記録した後に直近1週間の記録を07/07(Fri) 08:12というフォーマットで日本時間で返すようにしています。
DBから取得したUTCのDateをformatInTimeZone()を使って変換しています。

formatInTimeZone(gotUpAt, "Asia/Tokyo", "MM/dd(E) HH:mm")

これで実行環境のタイムゾーンによらずに、UTCのDateを日本時間の指定の文字列に変換できます。

GitHubリポジトリ

https://github.com/hid3h/ohamoni
一応公開しています。
なにか気になるところがあったら覗いてみてください。

おわりに

ここまで読んでくださりありがとうございます!
この記事が少しでも参考になればいいねを押してもらえればありがたいです!

またアプリも、気になれば使っていただければ幸いです。
バグや要望などもあればZennでのコメントでもTwitterでのリプでもお待ちしています。
おはもに-生活改善LINE Bot-
https://lin.ee/wqGf3WK

Discussion