海外サッカーの試合を通知するLINE Bot「SoccerBell」を個人開発した話
head_image

はじめに

本サイトの管理者はサッカー観戦が好きで、特に海外リーグで日本人選手が所属するチームの試合を中心に応援しています。

ただ、日本との時差の関係で、深夜や早朝に試合が行われることも多く、気が付いたら試合が終わっていたり、
うっかり見逃してしまうことが少なくありませんでした。

「試合がある日に、通知してくれるアプリがあればいいのに...」
そう思ったことがきっかけで、SoccerBell(サカベル)という LINE 上での試合通知サービスを作ってみました。

最初は個人的に使うレベルの簡単なものを Google Apps Script で作っていたのですが、
同じ悩みを持っている人は他にも多いと思い、今回プロダクトとして公開する形に至りました。

LINE Bot という選択

SoccerBell は試合情報を LINE で通知する、いわゆる LINE Bot という形で提供しています。
なぜ LINE Bot なのかという点についても、ここで少し触れておきたいと思います。

とはいえ、特別な理由があったというよりも、自分が欲しいと思って作るに至ったアプリなので、
「自分がどう受け取りたいか」という点を考えた結果が LINE だった、というのが正直なところです。

通知は欲しいけれど、スタンドアロンのアプリをわざわざダウンロードするほどでもない。
そんな距離感のサービスにはLINE Bot くらいがちょうどよいと思いました。

結果として、SoccerBell はアプリではなく、必要なときにだけ情報を届ける LINE Bot という形にしています。

SoccerBell について(サービス概要)

機能や使い方については、以下のページにまとめているので、
興味のある方はそちらをご覧いただければと思います。

SoccerBell|サービス概要

システム構成イメージ

SoccerBell は、ざっくり言うとバッチ処理を中心にしたシンプルな構成になっています。
説明
定期的に外部のサッカーデータ API を叩いて試合情報を取得し、そのデータをいったんデータベースに保存します。
保存した情報をもとに通知対象を判定し、LINE Messaging API を通じてユーザーに通知を送る、という流れです。

また、ユーザーからメッセージが送られてきた場合も、
基本的にはデータベースに保存している情報を参照して応答する形で完結するようにしています。

一部の有料プラン向けの機能については、決済サービスとして Stripe を利用しています。

設計について少しだけ

SoccerBell は、世の中にあるシステムの中では、そこまで複雑な構成や難しい仕様を持ったものではないと思います。
ただ、比較的シンプルな仕組みのシステムであっても、実際に形にしようとすると、
設計や運用を含めて考えるポイントはそれなりに出てくるものです。

そういった点をどう割り切るか、どこまで考えるか、というのもシステム開発の一部なわけで、
SoccerBell でもそのあたりは意識しながら設計しました。

ここでは、実際に作る過程で意識したポイントをいくつか紹介します。

通知処理を「判定」と「送信」に分けた構成

画像5

SoccerBell では、通知まわりの処理を「通知する対象を判定するバッチ」と
「実際に通知を送信するバッチ」に分けています。

やっていることだけを見ると、まとめて1つのバッチで処理してしまうこともできますが、
役割としては性質が違うため、あえて分けています。

通知判定バッチは、
「どのユーザーに、どの試合を通知するか」を決めるところまでが責務で、
通知送信バッチは、
その結果をもとに実際に LINE に通知を投げる、という役割です。

そのためバッチを分けることで、通知条件の変更やロジックの調整は判定側だけを触ればよく、
送信方法の変更(例えば通知手段を増やす、失敗時のリトライを入れるなど)は送信側だけで完結させることができます。

処理を分けることで構成は少し増えますが、あとから仕様が増えたときに考えることが減るので、
結果的には楽になるかなと思っています。

APIリクエスト数とデータ量を抑えるための考え方

画像3

外部 API を使う以上、リクエスト数の制限はもちろん気にする必要がありますが、
それと同時に「どこまでデータを持つか」も割と大事なポイントだと思っています。

SoccerBell では、試合情報の取得自体はリーグ単位でまとめて行っていますが、
データベースに保存する試合情報は、各チームにつき直近2試合分だけに絞っています。

通知サービスとして必要なのは、基本的に「次の試合」と、多くてもその次くらいまでなので、
それより先の試合を大量に持っておく必要はあまりありません。

また、先の試合日程は延期や時間変更が入ることも普通にありますし、
全試合を保存してしまうと、どこを更新するか、古いデータをいつ消すか、といったことを
毎回考えないといけなくなります。

そのあたりの運用をできるだけシンプルにしたかったので、
直近分だけを毎日取り直して上書きする、という形にしています。

結果として、APIの呼び出し回数だけでなく、
データ量や運用まわりの考慮も最小限で済む構成になっています。

シーズン切り替わりを意識した運用設計

画像2

サッカーはシーズンごとにチーム構成が変わるので、
チーム情報のメンテナンスも運用で毎回更新するとなると、意外と面倒になりがちです。

SoccerBell では、リーグに所属するチーム情報を定期的に取得するバッチを用意して、
昇格や降格によるチーム構成の変化を自動的に反映できるようにしました。

シーズンが切り替わるたびに手動で直す前提にしてしまうと、
アンテナを張り続けていないといけなくなるため、できるだけ「何もしなくても回る」形を目指しました。

全体を通して意識していたのは、

「作るとき」よりも「作ったあと」をできるだけ楽にする、という点です。

個人開発とはいえ、実際に運用し始めると、ちょっとした仕様追加や修正が入ることは普通にありますし、
そのたびに大きく作り直すのは中々しんどいので、今回紹介したポイント以外にも、
外部 API を1つに固定しないために複数の外部 API を持てる前提のテーブル設計にしていたり、
あとから機能を足すときに影響範囲を広げにくい構成になるよう、細かいところではいろいろ割り切りつつ設計しています。

最初から完璧を目指すというより、「あとから手を入れやすい形」を意識しておくことが、
結果的に一番ラクだなと感じています。

おわりに

この記事では、「こんな機能があったらいいな」と思って作ったアプリを、
せっかくなら他の人にも使ってもらえたらと思い公開することにした、という流れの中で、
SoccerBell がどんな作りになっているのかをざっくり紹介してきました。

システム自体はそこまで複雑なものではありませんが、
何か一つでも参考になる部分があれば嬉しいな、という気持ちで書いています。

画像4

最後に少しだけ、AI について触れておきます。
今回の SoccerBell の開発では、設計の壁打ちからコーディング、画像生成まで、
かなりの部分で AI を使って進めていました。
そのおかげもあって、開発スピードや生産性は本当に大きく変わったと感じています。

現時点では、AI がいるからといって誰でも簡単にシステム開発ができる、
というところまではまだ来ていないかな、というのが正直な感覚です。
ただ、それもそう遠くない将来に変わっていきそうだな、という気もしています。

そうなってくると、「何を作るか」というアイデアの部分が、
これまで以上に大事になってくるのかもしれませんね。
自分としては、これからもプロダクトをどんどん作っていきたいなと思っています。

以上です!


ABOUT

エンジニア2人が気が向いたときに作ったものや、書いたものを置いているサイトです。

このブログについて
CATEGORY
TOP