【個人開発】読みたい記事をストックするLINE Bot作ってみた

## はじめに

この度「あとで読むゼッタイ君」というLINE Botを個人で開発し、リリースしてみました。
その機能の紹介や技術的な話、感想等をつらつらと書いていきたいと思います。

ちなみに「あとで読むゼッタイ君」は、[こちらのリンク](https://lin.ee/WvHi3bx) or 以下のQRコードから友達追加が可能なので、ぜひ使って頂けると嬉しいです！

![あとで読むゼッタイ君.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526830/49daa827-b910-b19c-392c-eea1ffb375ca.png)


## どんなアプリ？

後で読みたいなーと思ったWebページを管理（登録・閲覧・削除）できるだけの超絶シンプルなLINE Botです。
具体的には、ユーザーが送ったメッセージ内容に応じて、以下の機能が利用できます。

- URLのみを送信すると、後で読みたい記事（WebページのURL）をブックマークとして登録できる
- 「読む」というメッセージを送信すると、ブックマークから（**ランダムで1つ**）閲覧（取得）できる
- 「読んだ」というメッセージを送信すると、ブックマークから削除できる

利用イメージとしては以下になります。

![S__26001423.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526830/5d38055b-f7a4-a40c-dc03-537512ad034c.jpeg)


## なぜ？

久しぶりに何でも良いから何かを自分で作りたくなったからというのが正直な所です笑

気づけば個人で何かを作ってきちんとリリースまでこぎつけたのは、4年ほど前に未経験からエンジニアへの転職を志した時にまで遡ります🙄
良いアイデアが浮かんだつもりになるも、作っていくうちに「これ微妙じゃない？」となってしまったり、ただ単にモチベーションが続かなくなったりと...

## そうは言っても

せっかく時間を使うなら、せめて自分が使いたいものを作りたいなと思い、直近で自分が感じていた「まとまった勉強時間を中々確保できない」という課題に着目しました。

もう少し深掘りすると、勉強は「インプット」と「アウトプット」に分類できると思いますが、今回は隙間時間を有効活用したかったので、短い時間でできそうな「インプット」の方に焦点を当てて、課題を具体的に考えてみました。

### 課題を考える

- 子供が生まれ、家事育児に充てる時間が多くなり、まとまった時間を確保しづらくなった
    - とは言え、短い時間なら手の空くタイミングがある
- 積読記事が溜まりまくっている
- 記事をストックする場所がバラバラ
    - Notion, Qiita, はてなブックマーク等
- 積読記事を読む時に、自分の興味関心がある分野の記事を選定してしまう
- （課題じゃないが）絶対にリリースしたい

### というわけで

- 短い時間にインプットできる
- 積読記事を1箇所に集約できる
- 積読記事からランダムで選定してくれる

上記を実現できるものを開発することに決めました。

また、リリースするにあたり障壁になりそうな自分の苦手分野であるデザインとCSS部分を考慮しなくて良い点、すぐに起動できて、サクッとURLを転送できる点で、LINE(Bot)が最適だと判断しました。

※サクッとURLを転送できる
iPhone/Safariなら数タップでURLを転送可能です
![スクリーンショット 2024-06-11 8.55.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526830/fd3f567c-61e5-af20-a57c-ae0fe1ac4877.png)



→参考:[【iPhone】SafariとLINEを連携してWebページをシェア(共有)する方法](https://www.ipodwave.com/iphone/howto/safari_line_share.html)

ちなみにトーク画面でピン留めしておくと、常にトーク一覧画面の上部に表示され、すぐアクセスできるという点も良いです。隙間時間にパッとLINEを開いて、インプットの時間に充てることができます。

## 技術的な話

### システム構成

作図が下手で恐縮ですが、システム構成は以下の通りです。超シンプルです。

![system-configulation.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526830/853abb6f-a3c8-7a8e-8e39-46b60e0f3c59.png)

ユーザーがメッセージをBot宛に送信すると、LINEプラットフォームよりこちらのAPIサーバーにPOSTリクエスト(Webhook)が送られます。

LINEプラットフォームとは、[LINE Messaging API](https://developers.line.biz/ja/docs/messaging-api/overview/)を利用してやり取りします。

参考：[Messaging APIの仕組み](https://developers.line.biz/ja/docs/messaging-api/overview/#how-messaging-api-works)

### 技術スタック

- APIサーバー(Webhook): Go
- データベース: PostgreSQL
- 開発環境: Docker(Docker Compose)

Goを選定した理由は、学習目的＋今回のような軽量なAPIサーバーを構築するのに適していると思ったからです。

### インフラ選定

個人開発で1番のハードルになるのがインフラ（コスト）かと思います。

安さを1番の目的とし、色々調べた結果以下を選定しました。

- APIサーバー(Webhook): Cloud Run
- データベース: [Neon](https://neon.tech/)
- コンテナイメージ保管: Artifact Registry
- CI/CD: GitHub Actions

Cloud Runで最小インスタンス数を0に設定(コールドスタート)にしたり、Artifact Registryでクリーンアップポリシーを設定して必要以上にイメージを保持しないようにしたり、テーブル設計とSQLを工夫してDB容量がなるべく肥大しないようにしたので、コストはほぼ発生しない見込みです
(まあ多分そんなことしなくても、余程バズるとかない限り、ある程度の間はコスト0で運用できそうな感じでした)

ちなみに上記の中で、最もコストが高くなりがちなのはデータベースで、当初は（無料枠があると思っていた）MySQLベースのサーバレスDBである[PlanetScale](https://planetscale.com/)を考えていたのですが、デプロイ間近に改めて調べるとなんと無料枠が廃止されており、慌てて今回選定したサーバレスPostgresの[Neon](https://neon.tech/)に変更したという背景があります(笑)
何を選定するかをきちんと調査した上で開発を進めるべきだったというのが反省点です。

参考: [【個人開発】無料DBを求めてPlanetScaleからNeonに移行したら快適だった話](https://qiita.com/nuko-suke/items/e940ff8ccde35d09f668)

また、私自身はインフラ周りやCI/CD整備にそこまで知見はなかったのですが、今回一から構築できたことでとても勉強になりました。

インフラコスト周りの調査で参考にしたもの: 
[Cloud Runの料金](https://cloud.google.com/run/pricing?hl=ja#pricing_calculator)
[Neon Pricing](https://neon.tech/pricing)
[Artifact Registryの料金](https://cloud.google.com/artifact-registry/pricing?hl=ja#data-transfer)
[GitHub Actions の課金について](https://docs.github.com/ja/billing/managing-billing-for-github-actions/about-billing-for-github-actions)
[個人開発向け無料 RDB サービスまとめ 2023 年版](https://egashira.dev/blog/free-rdb-services-2023)

### LINE Botの作成がカンタン

LINE Botの作成が想像より簡単でした。
LINEコンソールにLINEアカウントでログインし、プロバイダとチャネルを作成するだけで公式アカウントが自動で生成され、設定画面にあるWebhook URL入力欄に今回開発したAPIサーバーのURLを登録するだけで簡単に動作確認ができます。

今回使用しているのはユーザーのメッセージに対して応答する[リプライメッセージを送信するAPI](https://developers.line.biz/ja/reference/messaging-api/#send-reply-message)のみですが、ドキュメントも整備されており、開発が進めやすかったです。

また、LINE Botで発生する料金は、[LINE公式アカウント料金プラン](https://www.lycbiz.com/jp/service/line-official-account/plan/)に記載されている通り、月あたり200通が無料枠となっております。

ただし、今回開発したLINE Botが利用する、ユーザーが送信したメッセージに対するリプライ(応答)メッセージは、この200通にカウントされません([参考](https://www.lycbiz.com/jp/service/line-official-account/plan/#:~:text=%E3%83%81%E3%83%A3%E3%83%83%E3%83%88%E3%81%AE%E9%80%81%E5%8F%97%E4%BF%A1-,%E3%83%BB%E5%BF%9C%E7%AD%94%E3%83%A1%E3%83%83%E3%82%BB%E3%83%BC%E3%82%B8,-%E3%83%BB%E3%81%82%E3%81%84%E3%81%95%E3%81%A4%E3%83%A1%E3%83%83%E3%82%BB%E3%83%BC%E3%82%B8))

つまり料金かからずに運用が可能となっております。

参考: [ボットを作成する](https://developers.line.biz/ja/docs/messaging-api/building-bot/)

### VSCodeのPortFowardが便利

開発中に実際にBotとの連携の動作検証をしたい場合、LINEプラットフォームからのWebhookを受け付ける必要があるので、自分が開発するAPIサーバーは外部に公開する必要があるのですが、[VSCodeのPortFowarding機能](https://code.visualstudio.com/docs/editor/port-forwarding)がとても便利でした。
ngrok等を使わずに、数クリックでローカルのサーバーを公開できます。


## 感想

やはり自分が課題に感じたことを少しでも解決できると作って良かったなと思います。
やりたいけど中々腰が重かった個人開発ですが、リリースできると業務で感じるものとは別の達成感がありました。

この記事をご覧頂いた方で、個人開発やりたいけどなぁ..という方のモチベーションが少しでも上向いて頂けると嬉しいです（自分も頑張ります）

再掲になりますが、今回紹介した「あとで読むゼッタイ君」は、[こちらのリンク](https://lin.ee/WvHi3bx) or 以下のQRコードから友達追加が可能なので、ぜひ使って頂けると嬉しいです！！！

![あとで読むゼッタイ君](https://storage.googleapis.com/zenn-user-upload/cfd1d2dbfe21-20240607.png)