限界の瞬間
Twitter(現在のX)に約10年いました。昔は便利でした — フォローしている人たちのキュレーションされたフィードが、時系列順に並んでいた。10分だけ開いて、追いついて、閉じる。それで済みました。
2024年のどこかで、それが当てはまらなくなりました。「おすすめ」タブがデフォルトになり、プロモーション投稿が増殖し、エンゲージメント目当ての投稿が支配的になりました。3人の友達の様子を見るためにXを開き、40分後、本来見たかったものを何も読まずに閉じる、ということが起きていました。
明らかな対策を試しました — フォロー中タブに切り替え、ワードをミュート、リスト作成。それぞれ少しずつ役に立ちました。しかし「おすすめ」アルゴリズムは勝手にリセットされ、右サイドバーは関心のないトレンドを表示し続け、広告はすり抜けてきました。ノイズをまとめて消せる場所はありませんでした。
最初のバージョン:JavaScript 200行
ある週末に小さなChrome拡張を書きました。3つのことをしていました:
- 「Promoted」とマークされた投稿を非表示
- 右サイドバーを非表示
- タイムラインを「フォロー中」に強制
それだけです。約200行、UIなし、拡張アイコンから切り替えるだけ。Xに住んでいる友達数人にソースコードを共有しました。彼らは機能を要求し始めました。
「フォロー解除せずにアカウントをミュートできる?」 もちろん。
「キーワードでフィルタリングできる?」 はい。
「長いスレッドをAIで要約できる?」 うーん。それは本当の機能ですね。
スクリプトから製品へ
AI要約のリクエストが、これが趣味のスクリプトでなくなった瞬間でした。AIをきちんとやるには次が必要でした:
- バックエンド(Chrome拡張からAPIキーを送るのはセキュリティ的に最悪)
- 認証(誰がAIを呼び出してよいかを把握するため)
- レート制限(1人のユーザーがGemini予算を使い切らないように)
- 決済(ヘビーユーザーが無制限の要約のために支払えるように)
いずれも当初の「週末拡張」プランにはありませんでした。でも考えました: 1機能のためにそれだけ作るなら、ちゃんと作って拡張機能の他の部分でも使えるようにしよう — デバイス間でのフィルター同期、設定のクラウド保存、など。
趣味のプロジェクトが本格的なSaaSに変わりました。振り返ると: v1にしてはおそらく過剰でした。でも結局残した部分(認証、同期、決済)は製品を本当に良くしているので、後悔はしていません。
技術スタック
似たような小さなSaaSを作りたい人のために、うまくいったもの:
- バックエンド: Node + Express + tRPC + Drizzle、Railwayでホスティング。月約5ドル。
- データベース: MySQL(同じくRailway)。
- フロントエンド(サイト): 素のHTML/CSS/JS、フレームワークなし。Cloudflare Workers。無料。
- ドメイン: Cloudflare Registrar。年約10ドル。
- メール: SendGrid無料枠(1日100通、小さなアプリには十分)。
- 決済: Stripe Checkout + Customer Portal。
- AI: Google Gemini(無料枠でかなりの量をカバーしてからアップグレードが必要)。
全体の月額コスト: 10ドル未満。拡張機能はChrome Web Storeに(開発者登録料5ドルの一回払い)。
驚いたこと
認証は見た目より難しい。 メール+パスワードに、検証、リセット、セッション、JWT、ログインのレート制限 — 長いチェックリストです。これだけの作業量と知っていたら、ゼロから作りませんでした。可能ならライブラリかサービスを使ってください。
Stripeは見た目より簡単。 2つのtRPCエンドポイント(チェックアウト+カスタマーポータル)、1つのウェブフック、それで終わり。難しいのは銀行口座の認証であって、統合ではありません。
Chrome Web Storeのレビューは予測できない。 最初の申請は使われていない権限で却下されました。2回目は数日で承認されました。アップデートのたびに再レビューがあります — 反映には1〜7日待つ覚悟をしてください。
次に向けて
拡張機能は公開済み、サイトも稼働中、決済はエンドツーエンドで動きます。次の約3か月は配信の仕事です: ブログ記事(これを読んでいます)、Product Huntローンチ、Reddit、IndieHackers。
気になるX/Twitterのフィードがあるなら、ぜひ試してほしいです。無料枠で多くの人が必要なものはカバーします。フィードバックがあれば、メールアドレスはフッターにあります — 全部読んでいます。