
エンジニアとして仕事をしていると、自分が書いたコードによって冷や汗をかく瞬間があります。
本番環境で障害を起こしたとき。
データベースを誤って更新したとき。
ログにAPIキーを出力してしまったとき。
そして何より――
Discord Botが勝手に @everyone を連打したとき。
今回は、私自身が実際に体験した出来事をもとに、Bot開発でありがちな失敗と、その対策について書いてみたいと思います。
笑い話として読んでいただければ幸いですが、技術的には意外と重要な話です。
→事件は「bot-commands」チャンネルで起きた🤭
ある日、私は所属していたDiscordコミュニティの「bot-commands」チャンネルを眺めていました。
すると突然、Botが全員メンションを飛ばしました。
チャンネルは即座にざわつき始めます。
「え?今Botが全員通知飛ばした?」
「これ誰が作ったんだ?」
「Bot開発者は @.everyone 使っちゃダメって知らないのかな」
「じゃあ俺もやってみるか。@everyone」
「おいw」
私は画面を見ながら思いました。
「これは酷いな。」
「作った人、今ごろ焦ってるだろうな。」
「可哀想に。」
そして次の瞬間、私の脳内で重要な情報がロードされました。
そのBotを作ったのは私だった。
→人間は現実逃避能力が高い😤
面白いことに、人間という生き物は都合の悪い事実を認識するまでに数秒かかることがあります。
私はしばらく他人事としてチャットを眺めていました。
しかし徐々に理解が追いついてきます。
「待てよ。」
「このBotのコード知ってるぞ。」
「デプロイしたのも知ってるぞ。」
「Gitのコミット履歴にも見覚えがあるぞ。」
「犯人、俺じゃないか。」
顔が熱くなりました。
まるでCPU温度が100℃近くまで上昇したかのようでした。
→そしてBotは再び暴走した😱
問題はここで終わりませんでした。
私が現実を受け入れ始めたその時。
Botが再び @everyone を実行しました。
再び通知が飛びます。
再び人々が集まります。
そして再びコメントが流れます。
「また動いたぞ」
「バグってるじゃん」
「やばいBotだな」
「ゲーム中だったのに2回目呼び出された」
「このBot好き」
最後のコメントだけ若干意味が分かりませんでしたが、少なくとも好意的なユーザーが存在していたようです。
私はというと、地球上から消滅したい気持ちでいっぱいでした。
→Bot開発でよくある失敗その1:通知設計を軽視する
Discord、Slack、Teamsなどのコミュニケーションプラットフォームでは、「メッセージを送ること」よりも「誰に通知が飛ぶか」の方が重要です。
実際には単なるテキスト送信であっても、@everyone、@here、ロールメンション、ユーザーメンションなどはプラットフォーム側で特別な処理が行われます。
つまり、message.send()という一行の裏側には、数百人〜数万人への強制通知という非常に大きな影響範囲が存在します。
これはシステム設計でいうところの「Blast Radius(障害影響範囲)」の問題です。通知機能は常に危険物として扱うべきです。
→Bot開発でよくある失敗その2:入力値を信用する
私が後から原因を調査したところ、メッセージ生成ロジックの一部に想定外の入力が流入していました。
Bot開発者はしばしば以下のような前提を置きます。ユーザーは変な入力をしない、管理者は常識的に使う、このフィールドにメンションは入らない。
しかし現実世界は違います。現実世界のユーザーは極めて創造的です。開発者が想像した使い方をしません。むしろ想像していなかった使い方しかしません。
その結果、@everyoneという文字列が想定外の経路から入り込み、通知爆撃が発生することがあります。これは典型的なインプットバリデーション不足です。
→Bot開発でよくある失敗その3:権限設計を後回しにする
多くの開発者は機能開発に集中します。私もそうでした。まず動くものを作る。そして後から権限を考える。これは非常によくある流れです。
しかし実際には逆です。Botに与える権限は最小化しなければなりません。
セキュリティ業界では、Principle of Least Privilege(最小権限の原則)という考え方があります。
Botが全員通知を送る必要がないなら、そもそもその権限を持たせるべきではありません。権限が存在する限り、コードはいつかその権限を使います。人間が意図していなくてもです。
→Bot開発でよくある失敗その4:テスト環境が存在しない
開発者あるあるですが、「ちょっとした修正だから大丈夫だろう」と思ったコードほど事故を起こします。本番障害の原因ランキングを作るなら、かなり上位に"たぶん大丈夫"が入ります。
Botも同じです。専用の検証サーバーを用意し、通知機能やイベント処理を十分にテストするべきです。本番環境をテスト環境として利用すると、テスターがコミュニティ参加者全員になります。しかも強制参加です。
→優秀な開発者は失敗しないのか?
答えはNoです。優秀な開発者ほど失敗します。なぜなら、より多くのものを作り、より多くの変更を行うからです。
重要なのは、失敗しないことではなく、同じ失敗を繰り返さないことです。私自身、あの日の出来事は今でも鮮明に覚えています。
Discordの通知音が鳴るたびに、心拍数も一緒に上昇していました。
しかしあの経験のおかげで、現在では通知設計、権限設計、監査ログ、イベント管理について以前より遥かに慎重になりました。
高額な研修よりも、自分が原因で全員通知を飛ばした方が学習効果は高いのかもしれません。できれば二度と受講したくない研修ですが。
→まとめ
Bot開発は単なるプログラミングではありません。イベントドリブンアーキテクチャ、権限管理、入力検証、障害耐性設計など、多くのソフトウェアエンジニアリング要素が詰まっています。
そして時には、開発者自身の精神耐久性も試されます。
もしあなたがBotを開発しているなら、一度確認してみてください。不要なメンションは送信されないか。入力値は適切にサニタイズされているか。権限は最小化されているか。テスト環境で十分に検証しているか。
そして何より、本番環境でBotが突然 @everyone を実行した時に、チャット欄を見ながら「こんなBot作った奴誰だよ」と呟かないようにしてください。
犯人が自分だった時のダメージは想像以上です🤣