Discordの地震Botを作った話

Bot
BotDiscordEarthquake Early Warning Plus雑記
この記事は約6分で読めます。
スポンサーリンク

前書き

はじめまして、ゆきねこです。

3年ほど前からDiscord向けの地震Bot「EarthquakeEarlyWarningPlus」を開発、運用していますが、今回はその「EarthquakeEarlyWarningPlus」(以下EEWPBot)の生い立ちとか開発においてのノウハウみたいなものを書いていこうと思います。

そもそもEEWPBotってなに??

端的に言うと、EEWPBotはDiscord上でリアルタイムに地震速報を受け取れるBotです。

(こういうの)

生い立ちとか

開発に至ったきっかけ

(これについては実は詳しく覚えていないのですが)昔とあるコミュニティーに所属しており、そのコミュニティーのメンバーの中に地震で被災した方がいらっしゃったのがきっかけでEEWPBotを作り始めました。

このときは"プログラミング"のプの字も分からない状態で、とても苦労しながら数ヶ月かけて作り上げました。(2018年の3月ぐらい?)

もともとはそのコミュニティー用のプライベートBotとして稼働させていましたが、それだけではもったいないと思い、その年の7月ごろに一般公開を始めました。

(現行バージョンと比べるとめちゃくちゃ簡素)

ホストしていたサーバーが壊れた

一般公開を初めてから1ヶ月後にBotをホストしていたサーバーのHDDが壊れました。
ソースコードも全て吹き飛びました。(冗長化しろって話だけども)

これが割と精神的に来て開発がめちゃくちゃ滞りました

Botを1から作り直した

2020年の4月初旬に、Discordから「Botが100サーバー以上に導入されている場合は認証が必須になったよ」とのメッセージを受け取り、認証手続きを始めたのが再開発のきっかけです。

既に100を超えるサーバーに導入されているのにも関わらず、サービスを停止させているのはおかしいのではないか?と思い、1からソースコードを書き直しました。

その後完成したのがEEWPBotのv2です。

Botを1から作り直した (その2)

再開発から約1年後の2021年4月ごろにまたBotを1から作り直しました。

作り直した経緯としては
・ソースコードが汚すぎてメンテナンスが大変
・もっと最適化できる部分がある
・さらにリッチな画像表現をしたい

これらを踏まえ、様々なところを最適化しつつ作り直しました。
これが現行バージョンのEEWP v3です。

v3では画像での表現にとてもこだわっており、自分自身でもかなりの出来だと思っています(ハイパー自画自賛)

この"画像での表現"にめちゃくちゃ苦労したので、ここから先は実装にあたってのノウハウとかを書いていこうと思います。

開発にあたって

開発に使用した言語

EEWPBotの開発にはJavascriptを使用しています。
Javascript(以下js)ってWeb系の言語だと思われている[*独自研究][*要出典]んですが、Node.jsで割となんでも出来ます。Node.js最高!!

制約がめちゃくちゃ多い

Discordというプラットフォーム上での運用なので、ネイティブなアプリケーション(KiwiMonitorやJQuakeなど)に比べて制約が段違いにありました。具体的な例を上げるとすれば

・高頻度な情報更新が出来ない
・地震検知から通知までのタイムラグがある
・ユーザーごとのカスタマイズがしづらい

...と、すばやく情報を通知することが重要となる地震速報アプリケーションには致命的すぎるものばかりでとても大変でした。

いかに"わかりやすい"情報を届けるか

EEWPBotは(Discord上で)登録してある多数のチャンネルに投稿を投げるという形で地震速報を通知するのですが、APIのRateLimitもあり何度も情報更新をすることが不可能でした。

そこで、投稿一つにつき1枚に限り画像を添付できる*という仕様を利用し、更新をせずとも一目で理解出来るようにしました。

(*:Embed(埋め込みメッセージ)の仕様なので普通に画像を投げようと思えば何枚でも投げられる)

すばやく情報を通知するために

上で書いたように、EEWPBotは地震速報通知の際に画像を添付するという仕様なのですが、この画像を生成する時間がネックとなり、すばやい情報通知が出来なくなってしまいました。

そこで、この画像生成ロジックを切り離すことで、画像を添付しつつもすばやい投稿が出来るようになりました。

具体的には画像生成用にAPIサーバーを立て、Discordに添付する画像のURLを独自APIに指定することで実装しています。

また、DiscordとAPIサーバーの間にはCDNを噛ましてあげることで大量のアクセスを捌いています。Cloudflare、おすすめです。

画像生成方法がダメすぎた

v2まではゴリ押しで実装していました。脳筋なので💪

↑脳筋過ぎンだろ...

実は(v2までは)Bot側のコードに画像生成ロジックを組み込んであり、「地震検知ごとに画像生成→専用のディレクトリに保管」みたいな仕組みになっていました。

でもこれだとソースコードめちゃくちゃ読みづらいしメンテナンスも大変!!しかも必要ない画像まで生成されて全然イケてない!!!!

...ということで、v3からはこの画像生成ロジックを切り離し、本格的にAPI側に移行すると同時に1から作り直しました。

画像生成を支える技術

主にhtmlとcssとjsです。ほぼWebページと変わらない構成

node.jsでの画像生成と言うとnode-canvasあたりが主流だと思うんですが、canvasのみだと出来ることが限られてしまうので、EEWPBotではplaywrightを採用しています。

playwrightについて知らない方にざっくり説明すると、ChromiumやFirefoxなどをヘッドレスモードで動かせるライブラリです。また、GUIを持たないぶん起動が早く、リソースもあまり食わないのがポイントです。

このplaywrightを使用して、ローカルなhtmlファイルを読み込ませてからスクリーンショットを撮ることで画像生成を実装しています。

APIのRateLimitに引っかかる

公開初期は1秒ごとに投稿を更新していたのですが、導入サーバー数が多くなるにつれAPIのRateLimitに引っかかることが増え、最終的には1時間アクセス禁止を食らったりして大変でした。Botだけではなく自分も食らうので...

これについては情報の更新回数を削ったりすることでなんとか凌ぎましたが、今後導入サーバー数が増えていくと今の対策だけではかなり厳しいのではないかと思っています。

一応Discordさん側にもお問い合わせメールを投げたのであとは返信待ちです。返信が来たらこの記事を更新しようと思います。

最後に

ここまで文章を書いたのは久々で疲れました。原稿用紙7枚分ぐらいなんて書いたのいつぶりだろうか...

色々とトラブルがありながらも3年間(実質1年ちょいだけど)運用してこれたことに驚いています。

ここまで続ける事ができたのも、EEWPBotを導入してくださっている皆さんのおかげです。本当にありがとうございます。
また、Patreonで寄付してくださっている方には頭が上がらないほど感謝しています...

これからも更に便利な機能を追加していこうと考えていますので、どうかEEWPBotをよろしくお願いいたします!

コメント

タイトルとURLをコピーしました