五月病防止のための監視アプリ
開発期間: 2023-05-08 ~ 05-13 おおよそ 30h
開発者: kurihara yuya
おおよそ 7 分ほどで読めます
この web アプリは、アプリ開発者の僕自身が 5 月病にかからないために開発されました。
"朝活の開始時間","スマホのスクリーンタイム", "食事" というこれら 3 点において毎日アプリで記録をとり、アプリを用いて公開します。
管理された記録は、本アプリで閲覧できるだけでなく、毎日僕自身の twitter にその要約が自動投稿されます。
項目 | 使用技術 |
---|---|
Frontend | Next.js (TypeScript) |
Backend & DB | Notion |
Backend と Frontend の繋ぎ込み | Notion API |
管理画面・データ入力画面 | Notion (Web & iOS アプリ) |
ツイート | twitter API v2 |
ツイート実行・notionAPI の実行 | Next.js の API |
自動投稿の定期実行 | AWS Lambda (Python) & Amazon EventBridge |
インフラ | Vercel |
開発環境 | Docker |
サブトピック
- 個人的な目的
- 副次効果として対外的に期待しているもの
個人的な目的として、規則正しい生活を実現し、目標を達成するための時間的リソースを多く確保することがこのアプリの一番の目的です。
ここ最近、努力するための時間は確保できているものの、肌感覚で投下できるはずの時間の 80%ぐらいしか使えていないできてないという実感がありました。
原因として具体的には、
-
スマホいじりすぎ
-
朝起きてから布団でダラダラする
-
(あまり関係ないですが)筋トレしてるのに、少食すぎること というものがありました。
やはり人に見られた方がサボりにくいので、これらの指標をいずれかの形で記録し、対外的に公開することにしました。
また、単純なテキストデータを公開するだけでは、自分自身による虚偽のデータの入力ができてしまいます。したがって、画像を用いて虚偽のデータの入力かどうかを検証することも機能に盛り込みました。
具体的には、朝活の開始時刻のデータを入力するのと同時に、それを証明するための時刻と場所が記載されているレシートなどの写真を求めることです。
このようにして、自分がサボる可能性を徹底的に排除しています。
このアプリの開発にあたって、twitter に自動投稿をしていくことになります。その際に少し工夫することで、下記の副次的な効果を期待できると感じました。
- エンジニアの知り合いを増やす
- インターンシップや案件のチャンスを得る
- 法政大学や他の大学のエンジニアとの繋がりを広げる
したがって、このような属性の方々が僕の自動投稿のツイートをきっかけに僕にリーチできるようにツイートを工夫しました。
具体的には
- #エンジニアと繋がりたい というハッシュタグを投稿に含める
- 自動投稿をしているツイートだけだと不明瞭なので、"開発しました!"というメッセージと共に github のリンクをつける
- "法政" "プログラミング" という Twitter 検索に引っかかるような文言を追加する
- 文字数が足りないので、自動投稿のツイート対してコメントするツイートも自動で行い、自動投稿されたツイートを説明しつつ、載せたい情報を載せておく
技術選定においては、以下の要点を重視しました
- 金銭的低コスト、無料が望ましい
- 開発工数の削減(4-5 日ぐらいで終わらせたかった)
Notion & Notion API
前提として、今回のような単純なビジネスロジックのアプリの場合、そこまで重要ではないのにも関わらず避けられない重めに工数が発生するのは主に 2 点であると想定しました。
- クラウドインフラの構築
- バックエンド API の実装とその繋ぎ込み
したがって、この部分をノーコード化することを検討しました。
notion 以外の他の選択肢として firebase が存在しました。
しかし notion を採用する場合、下記 2 点のメリットがありました
- データ入力のインターフェース(管理画面)までノーコードで使用できる
- notionAPI のパッケージ notionHQ が存在するため、TypeScript で型セーフにフロント開発ができる
したがって、notion と notion API でのバックエンドと管理画面の構築を決定しました。
これにより、バックエンドの開発およびメンテナンスコストが大幅に低減されました。また、Notion を使用することで管理画面のインターフェースをノーコード化し、Notion の iOS アプリ と Web の二つのプラットフォームからデータの入力を可能にしました。
Next.js(TypeScript), Vercel
バックエンドに notion を採用したデメリットとして、表示速度のパフォーマンスの問題がありました。 したがって、強力なキャッシュ機能が必要でした。また、工数削減の観点からキャッシュサーバーを構築する工数も削減する必要がありました。 以上の理由で、Next.js(TypeScript), Vercelに決定しました。 理由としては、Next.js の ISR 機能で静的配信ができる、かつ Vercel で高速にデプロイ& CI/CD を構築できるというものです。 これにより notionAPI のパフォーマンス問題も解消されました。ビルドが遅いという問題は改善していませんが、UX には影響していません。
余談ですが、notionAPI を用いてのデータ表示までには以下のフローがありました。
- notion では 3 つのテーブルでデータを正規化している
- 処理には Next.js の API 機能を使用し、notion API で 3 つのテーブルに情報を取りにいき、join していた。
- それらのデータを加工してレスポンス
10 件の一覧表示の場合におおよそ 4 秒ぐらいかかっていました。
サブトピック
- notion でのデータバリデーションとデータベース構成
- 責務の分離と再利用: Next.js の API の使用
3 つのテーブルを使用しており、logProperty テーブルを relation 先として持つ二つのテーブルが存在します。
(表作成は chatGPT くんにお願いしました w)
logProperty:
カラム名 | 型 |
---|---|
uuid | formula: string |
title | title |
date | date |
morningImage | files: s3Url |
myFitnessPal | files: s3Url |
todayCalorie | number |
screenTime | files: s3Url |
todayScreenTime | number |
morningActivityTime | date |
published | formula: boolean |
tweetUrl | url: string |
MorningActivity:
カラム名 | 型 |
---|---|
morningActivityEstimatedTime | date |
morningActivityLastEdited | last_edited_time: string |
morningTargetPlace | title |
Log | relation |
MonthlyRecord:
カラム名 | 型 |
---|---|
monthlyScreenTime | number |
monthlyCalorie | number |
Log | relation |
notionAPI の叩き方としては下記のステップになっています
- logProperty テーブルのデータを取得
- log の id を使って二つのテーブルに検索をかけてデータを取得
- Next.js の API 内部で扱いやすい形に擬似 join し、加工して返却
工夫した点として、logProperty テーブルの**published カラム(formula: boolean 型)**があります。 これは下記条件が満たされた場合のみ true になります
- 投稿に必要なカラムがすべて満たされた
- filledAtr カラムがユーザーによって明示的に true にされている
フロントエンドでは、published カラムが true のログのみを一覧表示させています。 したがって、一般公開されるタイミングをユーザーが明示的に決定することができます。
Next.js アプリの中で、データの表示とデータの取得と加工、そしてツイートの実行を完全に分離し、後の二つに関しては Next.js の API として切り出しました。 これを行うことで、Lambda からでも vercel のエンドポイントにリクエストをすることで、データの取得とツイートが行えるようになりました。
header の authorization にトークンを乗せることで、フロントエンド APP もしくは lambda からしか API は使用できないようにしています。
わずかな時間の中で高速に開発できたのはよかった。技術選定として notion を採用することで圧倒的に工数を削減することができた。
また、こんな感じで twitter に毎日自分の様子を投稿し続けるのは少し恥ずかしい。 けれど自分を貫こうと思う。このアプリを通して長期的に淡々と努力して、自分のたてた目標を達成できるようにしたい。
直近としては以下のようなことに取り組む予定です:
- 今のインターン先で担当させていただいているプロジェクトで納期に間に合わせる
- 大規模な開発の短・中期インターンに受かる(夏以降)
- コーディングテストの対策
- インフラに terraform を用いたポートフォリオの作成
- コンピュータサイエンスの学習
- 技術面接の準備
今回作ったアプリを用いて、コツコツ努力してこれらの目標を達成します!!!
お読みいたいだきありがとうございました!!