👏

【個人開発】Notion のメモ内容をランダムに表示するアプリ「RandoMemory」を公開した

2022/11/07に公開

こんにちは、こぷらと申します。
個人開発で取り組んでいる Web アプリ RandoMemory を公開しました。
RandoMemory は Notion に記録したドキュメントをランダムに表示するアプリです。
このアプリの宣伝がてら、開発で取り組んだ内容について紹介します。

https://randomemory.vercel.app/

本記事のトピックは以下の通りです。

  • RandoMemory の紹介
  • Firebase + Next.js で手軽にアプリ開発
  • Notion API の活用方法
  • 個人開発アプリ公開までに行ったこと

技術的な詳しい説明やテクニックなどは紹介しませんのであしからず。
代わりに以下のような方を想定して記事を書きました。

  • これから個人開発を始めたい
  • 他人が開発している様子を知りたい
  • Notion API を利用したアプリ例を知りたい

RandoMemory 概要

The top view of RandoMemory before login

RandoMemory はドキュメント管理ツール Notion に保存されたドキュメントをランダムに表示するアプリケーションです。
Notion アカウントで RondoMemory にログインすることで、ログインしたアカウントの Workspace 内にあるドキュメントからランダムに表示します。

ログイン時にどのページを表示するか選択できるため、機密情報も Notion で管理しているという方も安心して利用できます。[1]
また、Notion 上から表示したいページをいつでも追加・削除することも可能です。

開発の動機

手書きのノートや手帳をパラパラとめくる体験が好きです。
思い出に浸ったり、当時考えてたことからアイデアが生まれたり。
忘れてたことから思わぬ発見、いわゆるセレンディピティが好きでした。

最近は何でも電子化してしまい、手書きで記録を残すことも減りました。
非常に便利で手書きの文化に戻る気はしませんが、なんとなく過去の記録を振り返るような機会も減ってしまいました。
昔のノートをパラパラとめくる体験をしたいと考えて開発したのが「RandoMemory」です。

私は Notion に思いついたことや面白かった記事を適当に記録しています。
そして貯めた記録をランダムに掘り起こすことで、ノートをパラパラめくる体験を擬似体験しようと思いました。
Notion から情報を探すのではなく、過去の記録を無作為に掘り出していく、そんな体験ができるアプリを目指しています。

システム構成

使用した技術、サービスは以下のとおりです。

Architecture of RandoMemory

フロントエンド周りは React のフレームワーク Next.js を利用。
Hosting 先には Vercel を選定し、Github に Push するだけでデプロイできるようにします。
また Backend の大部分は Firebase にまかせて、できるだけ楽に開発する環境を整えました。

Firebase + Next.js で手軽にアプリ開発

個人開発は楽してなんぼです。
あらゆる機能を 0 から開発したい気持ちをぐっとこらえて、優秀なエコシステムに乗っかってサクッと作りましょう。
Firebase + Next.js による開発はそんな考えにピッタリの選択肢です。
あらゆる場所で散々言われつくされてますが、改めてそのメリットを紹介します。

お手軽にユーザー認証が実装できる Firebase Authentication

個人的に Firebase を使う一番の理由が Firebase Authentication です。
アプリケーションに必須なユーザー認証機能は、自分で作ろうとすると非常に大変です。
ユーザー認証が必要なアプリでは、大体以下のようなフローの作り込みが必要です。

  1. ユーザー登録 or ログイン
  2. トークンの発行
  3. API アクセス前にトークンの検証

Firebase Authentication を利用すれば、 SDK の API を利用するだけで上記フローが実現できます。

Next.js で複雑な設定をせずに SPA 開発

React で SPA を作る際の有力候補は cra(create-react-app) かと思います。
cra を下げるつもりは一切ありませんが、個人開発をするのであれば Next.js のほうが良いかと思っています。
Next.js は SSR/SSG 用のフレームワークですが、 SPA っぽいアプリ開発も問題なくできます。
その上であえて Next.js を使う理由は以下の3つです。

  • cra 同様に複雑な設定をせずに開発が可能
  • cra より簡単に設定の拡張が可能
  • 簡易的な API サーバー(後述)がすぐに構築可能

Next.js の API Route 機能で API サーバー開発も楽をする

ユーザー認証が必要になると、オープンには扱えないセキュアな情報も増えてきます。
そのためにバックエンドサーバーを立てるべきですが、できるだけ楽をしたいのが個人開発。
Next.js の API Route 機能を使えば、簡単に API サーバーを立てることができます。

注意点として、Next.js の API Route はあくまで簡易的な API サーバーです。
例えば、同じエンドポイントに対して Get/Post メソッドを使い分ける場合は、API 側できっちり条件分岐を書く必要があります。

pages/api/user.ts
import type { NextApiRequest, NextApiResponse } from 'next';

export default (req: NextApiRequest, res: NextApiResponse) => {
  if (req.method === "GET"){
    // get process
  } else if (req.method === "POST"){
    // post process
  } else {
    res.status( )
  }
  res.status(200).json({ name: 'John Doe' });
};

他にもクエリやボディの扱いやエラーハンドリングなど、使い勝手は専門の Web API フレームワークには劣る印象です。
そのため、開発の立ち上げは Next.js で簡単に API を作り、スケーリングしたら別のフレームワークに移行するのが良いでしょう。

Notion API を活用した Web アプリケーション開発

Notion API を利用することで workspace 内のデータを取得できます。
細かく説明しませんが、以下の手順で利用することができます。

  1. インテグレーション管理画面へアクセス
  2. "+ New Integration" をクリック
  3. 名前や権限を設定し作成
  4. 作成したインテグレーションの Token を利用して API を実行する

インテグレーションとは Notion が外部ツールと連携するための Bot のようなものです。
より詳細なセットアップ方法が知りたい方はドキュメントを確認してください。

https://developers.notion.com/

指示に従ってインテグレーションを作ると、最初は Internal (自分のワークスペース専用) なインテグレーションとなります。
今回は Web アプリとして公開するために、Public なインテグレーションを作成しました。
Public インテグレーションでは、OAuth に則って認可したユーザーのワークスペースにもアクセスできるようになります。
詳しくはこちらのドキュメントを御覧ください。

https://developers.notion.com/docs/authorization

Notion の認可情報でユーザー認証を行う

Firebase Authentication では様々な手法での認証方法をサポートしています。
いわゆる 「Google アカウントでログイン」する機能なども、API を利用するだけで実装できます。

RandoMemory では Notion との連携が必要になります。
そのため「Notion でログイン」機能があれば、UX 的に最も優れています。
しかし、Firebase Authentication では Notion との連携をサポートしていません。
そこで、Notion の Authorization と Firebase Authentication のカスタム認証を組み合わせることにしました。

Firebase Authentication のカスタム認証システム

Firebase Authentication では Notion をサポートしていないため、カスタム認証システムを利用しました。
カスタム認証システムを大雑把に説明すると、独自の認証システムの認証情報から Firebase 用の認証情報を作成する方式です。
詳しくは以下のドキュメントを御覧ください。

https://firebase.google.com/docs/auth/web/custom-auth?hl=ja

カスタム認証システムの利用方法はざっくり以下のとおりです。

  1. アプリケーション側で一意のユーザー ID を発行
  2. Firebase Admin でユーザー ID からカスタムトークンの発行
  3. カスタムトークンをクライアントへ返す
  4. カスタムトークンを利用して Authentication へログイン

Firebase 用の認証情報は Firebase Admin SDK で作成するカスタムトークンを利用します。
カスタムトークンを作るためには、ユーザーを一意に識別するための User ID が必要になるので、そこに Notion の認可情報を利用します。

Notion の認可フローの詳細はドキュメントに任せます。

https://developers.notion.com/docs/authorization

認可フローが完了すると、以下の情報が取得できます。

NotionAuthorizationResponse
{
  "access_token": string,
  "bot_id": string,
  "owner": OwnerObject
  "workspace_id": string
}

今回はこの中の Bot ID を利用します。
ドキュメントでは以下のように説明されています。

The bot_id returned along with your token should act as your primary key when storing information.

主キーとして利用できるとのことなので、今回の要件にぴったりです。
念のため複数のアカウントで試してみて、ユーザーごとに異なる ID が返ってくること、認可のたびに同じ ID が返ってくることも確認しました。

ということで、最終的に以下のような形でユーザー認証を実現しました。

Notion の AccessToken と Firebase Authentication を連携させた認証フロー

アプリ公開に向けた準備

不特定多数の人に向けたアプリの公開は初めてなので、備忘録としてやったことをまとめておきます。
こんなこともしたほうがいいなど、アドバイスがあればぜひコメントなどで教えてください。

名前決め

最も苦戦した部分がアプリの命名です。
私のアプリと認識してもらうためにも、名前は重要なファクターだと考えてます。
こだわっていい名前をつけたいと思いつつ、なかなかアイデアが浮かばず何日も悩みました笑。
古代ギリシア語やいろいろな神話の神様を調べたり迷走しましたが、最終的に「RandoMemory」に落ち着きました。

過去の記録(Memory)をランダムに掘り起こす、というアプリのコア機能をそのまま名前にしてみました。
ダジャレっぽくてダサいかなと思いつつ、シンプルでわかりやすいので結構気に入ってます。

Vercel へのデプロイ

Next.js を利用しているのでホスティング先には Vercel を選びました。
Vercel のダッシュボード上で Github と連携させるだけでデプロイできるのは最高に楽ですね。
他のサービスを利用したことがないので具体的にどこが良いとまで説明できませんが、問題が起こるまではこのまま使い続けるつもりです。

プライバシーポリシーと利用規約の準備

Notion のインテグレーションを Public で正式に公開するためには、プライバシーポリシーと利用規約を用意する必要があります。
しかしそんなもの作ったこともなかったので、今回は App Privacy Policy Generator というサービスで作ったものをそのまま利用しました。
利用しているサービス (Analytics など) を指定すると、それに応じた内容のプライバシーポリシーを生成してくれるすぐれものです。
プライバシーポリシーと利用規約どちらも生成してくれるので、とりあえず必要なものはこれで揃います。

PR 文書の作成(この記事)

最後に広告と情報共有も兼ねて、この記事を執筆しました。
せっかく作ったんだから誰かに使ってもらいたい、そう思って有名なプラットフォームで記事を書いてみました。
ただの紹介記事ではあれだと思って、技術的な内容も少し紹介しています。
いずれもっと込み入った内容についても紹介する予定です。
反応があると私が喜ぶので、いいねや SNS でのシェアよろしくお願いします。

おわりに

今回は私が開発した Web アプリ「RandoMemory」を紹介しました。
Notion で過去に溜め込んだ記録をランダムに掘り起こすアプリです。
思い出に浸りたいとき、思いがけない発見を期待しているときに使ってみてください。

今後は Notion だけでなく他のドキュメント管理サービスや Twitter などの SNS にも対応できればと思っています。
使ってみた感想やご意見などあれば、コメントや Twitter で気軽に送ってください。

それでは。

脚注
  1. ページ内のコンテンツ情報はブラウザ上に表示するのみで、DBなどには一切保存しておりません。 ↩︎

GitHubで編集を提案

Discussion