Nuitaを支える技術

 この記事はKMC Advent Calendarの8日目の記事です。7日目の記事は id:kaptambns さんの「GIUを支える技術」でした。Webプログラミングの知識がない状態から作ったサービスとして、特に自分もWebプログラミングをするようになってから全力でリスペクトしています*1。「この方は部員の中でも屈指の人生経験の持ち主ですので、記事の内容が楽しみです」と紹介され(そんなことはない)、何を書こうかずっと迷っていましたが、v-dataGod Illust Uploaderに続いてウェブサービスつながりということで自分のWebサービスであるNuitaについて書こうと思います(責任を押し付けていくスタイル)。

www.dnek.app kaptambns.hatenadiary.jp adventar.org

注意

 本記事の主題は成人向けのウェブサービス開発です。技術的な側面について述べるため、性的な描写は可能な限り控えましたが、苦手な方は注意してください。

本題

 射精報告に特化したSNSであるNuitaを開発・運営しています。これ以上サービスの内容について言及するのは不適切な気がするので、あとはぜひユーザー登録して確認していただけると嬉しいです。 nuita.net

 確か最初に出したのは今年の6月くらいで、半年間色々な要素を付け足しながらやってきたのですが、2019年12月6日時点でユーザー数は208、3898回のヌイート*2、1313のオカズが共有されています。Web開発はこれが初めての経験なので、ときどきコーディングのミスで登録ページが500を返したりデータベースをサーバーごと吹っ飛ばしたりしていますが、優しいユーザーの方々やアドバイスをくださる先輩方のおかげで何とか形になりつつあります。

構成

 Nuitaは次のような構成で開発されています。

  • フロントエンド: 素のJS + TypeScript
  • バックエンド: Ruby on Rails
  • データベース: MySQL

 ……前日の記事に乗っかって構成を書き出してみたのですが、ほぼほぼRails チュートリアルをなぞっているだけなので言うことがありません。

 1点だけ、データベースは初期環境のまま開発環境ではSQLite、本番ではMySQLと使い分けていたのですが、データベースの役割とかがなんとなく分かってきたあたりでMySQLに統一しました。タイトルやメタ情報に絵文字が入っているリンクは投稿できないという不具合がずっと存在していて、開発環境だと再現できないのでめちゃくちゃ困っていたのですが、MySQLではデフォルトのcharset utf8では絵文字が扱えないというのが原因でした。結局本番環境のMySQLを直接触ってutf8mb4への変更作業をしなければならず、RailsSQLの知識必要なんじゃん!!!みたいな気持ちで泣きそうになっていた気がします。もちろん、直接触るよりは遥かに楽をしているのですが……。

 RailsチュートリアルはHeroku上にデプロイしていますが、NuitaはConoHa上のレンタルサーバーを借りて動かしています。デプロイできるまでに覚えなきゃいけないことが多いし、Qiita*3とか参考にしても必ずどこかで詰まるので、ここが一番大変だった記憶があります。Slack上に他の部員に助けを求めまくったり、エラーメッセージで検索しまくったりしましたが、何度も解決策が見えないまま気力を全消費してSteamを開いていました。

歴史

 現在、KMCのSlackチャンネル #nuita ではたくさんの方がアドバイスを残してくださったり、ウェブサービスとは全く無関係な成人向け記事をシェアしたりしています。仕様を具体的に書くのを避け続けていたせいで、Githubではissueの報告を除いてほぼkypの個人開発状態だったのですが、つい最近は形が定まってきたのもあって他の部員からもPRが来るようになりました*4。PR・issueはつい先日100個を越え*5、コミット数は517、失った時間の重みで手が震えてきます。これまで半年間の振り返りとして、Nuitaの歩みをごく簡単に、なるべく具体的な描写には深入りしないように簡潔に記します。

2019年4月頃(サービス公開当初)

f:id:kypa:20191208184339p:plain
2019年4月29日のNuita。何もSSとか撮ってなかったので、以降も画像は開発環境のものです
 見て分かる通り、当時はユーザーのアイコン表示もなく、ただ「ボタンを押すと投稿が流れる」という極限まで切り詰められたサイトでしたが、主題のキャッチーさとKMC部員のフットワークの軽さもあって、サービス開始直後から数十人のユーザーを集めることができました。その次の次の日に、ConoHaの操作を間違えてデータを全削除しました。悲しかったです。

 荒らし目的の排除のために、「前のヌイートから3分以上の間を置かないと投稿できない」というコードを急遽書いたのですが、このために新規登録したユーザーが永久につぶやけなくなる問題がありました。

5月

f:id:kypa:20191208185345p:plain
2019年5月6日のNuita
 アイコンを設定できるようになった*6ほか、投稿に100文字以内のコメントが付けられるようになりました。当初は単に行為の感想を答えてくれればいいなあくらいのつもりで書いたのですが、いざ実装してみるとユーザーがオカズのURLを投稿するようになりました。そのため、急遽テキスト中のURLがリンクとして表示されるようにしました。この頃から「一発ネタのSNS」ではなく「普通に使えるSNS」へと進化した気がします。

 このほか、5月にはRailsデフォルトの数字URL(/users/45とか)をやめて/users/rAnd0ma1PhanvmEr1c/みたいにしたり、HTTPS化したり、twitterアカウントにヌイートを自動投稿できるようにしたりしました。

6月

 いいね機能を実装しました。ここはAjaxを使わないとさすがに見た目が悪いので、慣れないJavascriptをようやく触り始めました。また、id:k-maztani にお願いして、最高にイケてるロゴを作ってもらいました。

f:id:kypa:20191208191923p:plain
これもリブランディングが必要……?
 余談ですが、これぐらいまでmetaタグでviewportの設定をし忘れていたので、せっかくのBootstrapなのにスマホでも横幅1000px以上の画面が縮小表示されていました。

7月

f:id:kypa:20191208195444p:plain
2019年7月20日のNuita。リンクを入れるとカードとして展開される

 URLを入れるとリンク先のタイトルや(手に入る場合には)画像、説明文が表示されるようになりました。基本的にはtwitterと同じくサイト側で用意されたメタデータを利用していますが、…….。

8月

f:id:kypa:20191208195718p:plain
2019年8月20日のNuita

 ユーザーのプロフィールに、Github形式で最近のヌイート傾向が表示されるようになりました。言い忘れていましたが、Nuitaにはフォロー・フォロワーという概念があり、フォローしなければリンク以外のコメントは見られません。また、相互フォローの関係だといいねの内容や詳細なプロフィールが見られるようになります。

 また、特定のコンテンツに対する検閲機能が追加されました。

9月

 これまでに投稿された全てのコンテンツからランダムに1つ表示する機能が追加されました。更新ボタンを押していくだけで新しいコンテンツに出会うことができます。

 いいね、フォロー、ランダム表示など、動的に書き換えなければいけない部分が素のJavaScriptで扱うにはあまりにつらい量になってきたので、TypeScriptを導入しました。IDEで補完が効くので知識が薄い自分にも書きやすいです。フロントエンドはもっとイケてる感じにしたいなあと思いつつ、導入の手間が多くてそれ以上のことはできていません。

11月

 PWAを導入しました。「ホーム画面に追加」するとほとんどネイティブアプリみたいに扱うことができます。徐々にコードの量が増えてきて、1人だと見通しが立たない感じになってきました。

12月

 「Nuita Advent Calendar」をはじめました。継続的に投稿してくれるユーザーの数はやはり少ないので、その対策になったり一度やめたユーザーが戻るきっかけになったらいいなあと思っています。

あとがき

 というわけで、これまでのNuitaの歩みを見てきました。3月くらいにサービスの構想を思いつき、Webに対する知識がHTMLとCSSしかない状態からだいたい9ヶ月くらいでここまで形にすることができました。ほぼサービスとしての体を成していない状態から支えてくださったユーザーの皆さんには感謝の念しかありません。一方で、最初の頃手探りで書いていたコードがまだ動き続けているのはかなりの恐怖体験で、きっと多数のバグが発見されずに埋もれているのだろうと思います。KMCの内外を問わず、開発に貢献していただける方を募集しています。あるいは、バグを発見したりコードレビューしたりしてくださるだけで構いません。力になってください。データベースが大きくなるにつれて最近確実に重くなってます。誰か助けて……。あと、新規登録はいつでも受付中です。

nuita.net

次回予告

この記事はKMC Advent Calendarの8日目の記事でした。次回の担当は kmc-id: tkmax777 さんです。このカレンダー初の1回生!どんな内容かとても楽しみです。

KMCM

KMCの入部資格に制限はありません。受験生や社会人でももちろん入部できます。遠方にお住まいの方でも入部できます。Slackでおしゃべりするだけでも大丈夫です。#nuita の様子も見ることができます。興味がある方はメールやDMで入部希望の旨を連絡してください。見学もできます。

kmc.gr.jp

あわせて読みたい

KMCでは今年、他にも二つのアドベントカレンダーを進行中です。

adventar.org

adventar.org

こちらもぜひお読みください!

*1:余談ですが、数年前のアドベントカレンダーでR18な感じのことを取り扱っていたのもリスペクトポイントです

*2:Nuitaにおけるユーザーの投稿の呼称です

*3:主に参考にしたもの; (初心者向け)vpsを契約して、capistrano3でRailsアプリをデプロイするまで [その1 サーバー設定編] - Qiita

*4:僕はマージしてます。GIUは……

*5:記念すべき #100 は部員同士でお見合いをしていたらdependabotに取られました

*6:S3とfog-awsを使っています