抽選会の手間を減らすSmartLotteryをリリースしました
自作サービス「SmartLottery」をリリースしました。
はじめに
Rails7とHotwireを使用し、自作サービス SmartLottery をリリースしました。
- リポジトリ
OdenTakashi/SmartLottery: SmartLottery
- サービスURL
目次
自己紹介
こんにちは、odentakashi(@odentakashi)です。
私はフィヨルドブートキャンプでプログラミングの勉強をしており、この度ずっと開発を続けていた
自作サービスをリリースしました。
またこの記事では、自作サービスを作っていく中での苦労や勉強になったことを書いていきます。
SmartLotteryの紹介
SmartLotteryとは
このサービスは 複数人にプレゼントを送る際に発生する手間を解決するための抽選アプリ です。
抽選会を作成するだけで応募フォームを生成し、そのフォームから応募してもらうことによって
抽選・当選メールの送信をこのアプリが自動で行います。
このサービスが解決すること
上述の通りこのサービスは 複数人にプレゼントを送る際に発生する手間を解決するための抽選アプリ です。
もし抽選会を開催するとなった場合、以下のような手順で抽選会を開催することが多いのではないかと思います。
- Googleフォームで応募フォームを作成する
- 作成した応募フォームを希望者に共有し、応募してもらう
- 締め切り時刻になったら手動で抽選を行う
- 抽選結果をもとに当選者にメールを手動で送信
このように列挙してみると手順が多く手間がかかります。
まさにこの手間を解決するのが SmartLottery です。
SmartLotteryを使った場合ですと
- 抽選会を作成する
- 生成された応募フォームを送り応募してもらう
実際に手動で行う作業はこれだけで、この後はアプリ側が抽選・当選メールの送信を行ってくれます。
使い方
抽選会作成者
1. 抽選会を作成する
一つの抽選会に複数の賞品を登録可能です
2. 応募フォームのURLをコピーする
3. URLを共有する
コピーしたURLを抽選会参加希望者に対して共有します。
設定した締め切り日を過ぎますと応募ができなくなるため注意が必要です。
4.当選メールが送信されるまで待つ
締切日の翌日01:00(日本時間)に抽選が開始されます。
また抽選が行われると抽選詳細ページにて当選者が表示されます。
応募希望者
1. 共有されたURLにアクセスする
抽選会作成者から共有されたURLにアクセスを行います。
2. 応募フォームより応募
3. 抽選を待つ
応募しますと以下のような画面が表示されます。
この画面が表示されたら後は、抽選が行われるのを待ちます。
サービスを作ろうと思ったきっかけ
私の所属するフィヨルドブートキャンプでは、プレゼント企画というものがあります。
流れとしては締切日を設け、プレゼントの企画者の方が作成したGoogleフォームを利用し、生徒の方が応募をします。
そして締切日になった際に、企画者の方が Array#sampleを用い抽選を行い当選者にメールを送ると
いうものです。
その中で、この手順を手動で行うのは大変であるという声があったため、その手間を解決するアプリを作成しました。
技術スタック
- Ruby 3.2.2
- Ruby on Rails 7.0.6
- Hotwire
- turbo-rails 1.4.0
- stimulus-rails 1.2.1
- Slim 5.1.1
- Devise 4.9.2
- Rubocop 1.55.1
- Slim-Lint 0.24.0
- RSpec 6.0.3
- Tailwind CSS
- Github Actions
- Fly.io
開発について
開発の流れとしては、初めにエレベータピッチを作成し、ペーパープロトタイプを作成、技術検証、DB&リソース設計、そして実際に作成するというものでした。
この中で自分はアイデア出しの段階でとても苦労してしまいました。
アプリを作る際に大事なのはそのサービスが何かしらの問題を解決できるかという点、既存のサービスでその問題を解決できない点です。
その点を考慮すると自分の出すアイデアは既存のサービスで解決できてしまうものばかりで、
自分が作る必要のないものでした。
アプリを作るというのは実装だけではないということを身をもって感じた瞬間でした。
実装に入ってからは、初めて触るインフラ周り、CIなどなど何もわからないことばかりでした。
しかし慣れてみるととても便利で、「自分はこれしかやらなくていいの?」と思うほどでした。
また実装の中で使用したライブラリなどもとても便利なものがあり、実際にこれを作ってくれている方がいるというありがたみを強く実感しました。
苦労したこと
締め切りを過ぎた後の抽選をどのように行うか
このサービスにおける重要な機能の一つに、抽選会の主催者が設定した締め切りを過ぎた後に抽選を行うというものがあります。
この処理は、締切日の翌日01:00時に定期的に実行されます。
この定期実行を実現するために、cronを使用して、Rakeタスクを実行しています。
最初は、この処理を実行するためにActiveJob+Redis+Sidekiqを検討していましたが、
アドバイスを受けて、このツールは非同期処理のためのものであり、特定の日時に実行することには向いていないと判断しました。
またUNIX系サーバーにおいてはcronを使用するのが一般的ということもアドバイスいただきました。
したがって、非同期処理から定期処理へのアプローチを採用し、締切後に抽選を行うためのRakeタスクを作成しました。
そして、このRakeタスクを毎日01:00に実行するようにcrontabを設定しました。
また、このサービスのインフラで利用しているFly.ioではsupercronicというジョブランナーが推奨されており、このツールを使用して定期的なタスクの実行を管理しています。
ツールの本来の使い方をを考えないで実装を行うと、おそらく歪なものが出来上がってしまうため、
まず何をしたいのかをはっきりさせ、それに合うような適切なツール選定が必要であるということを
実感しました。
メール配信サービスの選定
今回Deviseを使い、登録時、登録情報変更時、パスワード変更時の確認メールの配信に加えて、
当選結果を伝える際にメール配信を行っています。
その際、どのメール配信サービスを使うかという選定に苦労しました。
結果的にはGmailの配信サービスを利用しメールを配信しています。 しかしこの選択は妥協案なのでこれから改善していきたい点の一つとなっています。
当初Gmailの配信サービスを利用することについてkomagataさんから他の配信サービスを検討した方がいいかもしれないとアドバイスをいただきました。
理由としては、
- メール配信がスパムとして扱われてしまい、Gmailアカウント停止の可能性がある
- 本番環境でGmailの配信サービスを使うことはあまりない
といったものです。
その背景にはメール配信自体がスパムの温床となっていることが挙げられます。
そこで別のメール配信サービスを検討しました。検討したメール配信サービスは以下の通りです。
- Mailgun
- Postmark
- SendGrid
今回の受け入れの条件は以下の通りでした。
- 価格が無料もしくは格安であること
- メール配信が問題なく行われること
- 導入が大変過ぎないこと
この点を考慮して検討を進めました。 まずそれぞれの料金体系は以下の通りでした。
Mailgun
- 30日間は月5000通まで無料枠
- 30日間以降はプランに入る必要がある(月35$~)
Postmark
- 独自ドメインのメールアドレスを取る必要がある。
- 月100通までは無料
SendGrid
SendGrid登録の際に、法人向けで個人向けではなかったのですが、ダメ元で申請してみたところ
本サービスは法人向けに提供されており、 任意団体のお客様のお申し込みは受け付けておりません。
というメールが届き、こちらは使用できないと判断しました。
検討をしたところPostmarkが有力となっていたのですが、一点気になるのは「月100通までは無料」
という点でした。
理由としては、実際にこのサービスがどれだけのメールを配信することになるのか、今の段階では予想がつかないためです。
これらの事実に加えて、フィヨルドブートキャンプの卒業生が、Gmailの配信サービスを利用している
こともあり、現段階ではGmailの配信サービスを利用し、配信数の目安がついてから他のサービスに乗り換えるという判断をしました。
ヒアリングの難しさ
フィヨルドブートキャンプ内であったら便利というものを作成したため、細かい仕様については
ヒアリングが必要でした。
しかし事前にヒアリングを行い、内容を理解していたつもりでしたが、実際に実装を進めてみると
仕様についてわからない点が多くありました。
そのため、少し作って確認しながら実装を進めました。
またヒアリングを行う際のコツとして、
- 完璧でなくていいので事前に仕様を自分で考えてみるのが良い
とアドバイスいただきました。
このような経験から、ある程度叩き台を作ってからでないと、ヒアリングで得られる情報量が少ないことを学びました。
やってよかったこと
作業の記録を残す
実装を進めていく中で、記録を残さず作業をし続けていたのですが、
気づいたらどこまで作業したのか、どこで詰まっているのかということがわからず、迷子のような状態になってしまうことがありました。
この状況に陥ってしまうとわからない箇所の特定が難しいため、質問もしにくくなってしまいます。
その解決策として自分の作業の記録を残すということを導入しました。
それは
- 自分が行ったこと
- 行ったことの結果
- 考えたこと
書いていくということなのですが
メリットとして
- わからない箇所がはっきりする
- 質問がしやすくなる
などが挙げられます。
結果的に、わからないことへの恐怖心が格段と減り、とても良い知見であったと思います。
抱え込まず質問、相談する
実装を始めていく中で一番意識していたことが、抱え込まず質問、相談するということです。
実際に詰まってしまう箇所は無数にあったため、自分では解決できないこと、解決はしたが自信が持てない点が多々ありました。
そのような時は抱え込まず、考える時間を決め、その時間を超えたら質問することにしました。
また質問する際に意識していたことは
- 自分なりの答えを持つ
- 情報を省略をしない
ということです。
ただ「わかりません」と相談するのではなく、問題の解像度を上げるために以下のようなフォーマットでわからないを分解していました。
- 質問の背景(どこの処理の話か、何をしようとしたかなど)
- 何を期待するのか
- 結果はどうなったのか
- 何を試したのか
- 自分なりにの考えor仮説
このようなフォーマットに当てはめながら調査をしていると自己解決することが何度もあり、
わからないという状態は問題の解像度が低い状態であるため、解像度を上げることにも役に立ったと思います。
これからもこの方法は役に立つと思うので、身をもって体験ができ、とても勉強になりました。
これからの展望
SmartLotteryのこれから
メール配信サービスの移行
上述した通り現在利用しているGmailの配信サービスでは、アカウントが停止されてしまった場合
メールが送信されなくなってしまうため、様子を見て他の配信サービスに乗り換えたいと思っています。
応募する賞品を選択できるようにする
現在は、抽選会に複数の賞品が設定されている場合、どの賞品に応募するかは選べず
ランダムに抽選される仕様です。
リリースを早めるためにこの仕様にしているのですが、将来的には応募先を選べるようにしたいと考えています。
odentakashiのこれから
OSSに貢献したい
開発を行う中で様々なライブラリを使用しました。
そのライブラリ一つ一つは、画面の向こうのどなたかが苦労して作成してくれているものです。
この開発を通してこの事実を今まで以上に痛感し、同時に自分も小さなことから少しでも貢献したい
という気持ちが強くなりました。
その第一歩として、実際に開発の中で利用したライブラリにPRを送るということもしました。
(typo修正ですが💦)
docs: fixed typo in History.md by OdenTakashi · Pull Request #630 · nathanvda/cocoon
おわりに
月並みな感想ですが、開発は全体的にとても楽しく進めることができました。
進捗が出ない期間などもありましたが
作業の記録を残すようにしたりと、自分なりの工夫をすることに加え
週に一回の自作サービスの進捗会などで
相談をさせていたたくことにより、モチベーションを保つことができました。
また開発の途中で一番辛かったことは、時間をかけて実装したが、振り返ると大した処理ではないと感じてしまう点でした。
このような気持ちを日報に書いたところ、komagataさんから以下のようなお言葉をいただき、とても心が軽くなりました。
ありがとうございます。🙏
元々どんなはたから見たらちょっとしたWebサービスでも作るのはとっても大変なものです。気にしなくていいと思います。 それだけにちゃんとしたサービスを公開している人は外からは見えないほど労力を使っているってことっすね。
リリースまで様々なアドバイスをしてくださったkomagataさん、machidaさん、メンターの皆様、
そして関わってくださった受講生の皆様のおかげで詰まりながらもプログラミングを楽しく学習することができました。ありがとうございます。