逆引き:コマンド・Interaction・UI
prefixからslashへの移行、コマンド引数、権限、cooldown、Interaction応答、Button、Select、Modal、Embedの相談を整理します。
この記事で分かること
- prefix commandのイベント到達確認
- slash commandの登録と反映範囲
- Interaction初回応答とdefer
- help/サブコマンドへの整理
- 引数変換とconverterの失敗を返す
- User/Member/Role/Channelを混同しない
コミュニティの相談ログを匿名化・一般化し、コマンド・Interaction・UI実装の確認点をまとめた逆引きです。
prefix・slashコマンド移行
prefix commandの到達確認
メッセージ入力からコマンド処理までの到達点を確認します。
イベントを見る
prefix commandはメッセージイベント、Message Content Intent、prefix判定、bot自身の除外、handlerへの到達を分けて確認します。Botがオンラインでもmessage contentが空ならコマンド処理に入れません。
コマンド処理へ渡す
discord.pyのcommands.Botでon_messageを自前実装する場合など、コマンド処理へ渡す処理を忘れるとprefix commandが反応しません。例外を握りつぶさず管理ログへ残します。
確認ポイント
- readyログ
- message event到達
- Message Content Intent
- prefix判定
- 例外全文
参考(公式ドキュメント)
- https://docs.discord.com/developers/resources/message
- https://discordpy.readthedocs.io/en/stable/ext/commands/commands.html
slash command登録と反映
slash commandが表示されない、古い内容のまま残る時の確認です。
登録先を見る
slash commandはアプリコマンドとして登録します。guild commandとglobal commandでは反映範囲や反映時間が違います。登録スクリプト、application id、guild id、scopeを分けます。
導入URLを見る
Bot導入時にapplications.commands scopeがない、または対象サーバーに登録していない場合、コードが動いていてもコマンドは表示されません。
確認ポイント
- applications.commands scope
- guild/global登録
- 登録スクリプトの実行
- 古いコマンドの削除
参考(公式ドキュメント)
- https://docs.discord.com/developers/interactions/application-commands
- https://docs.discord.com/developers/topics/oauth2
Interaction応答へ移す
prefixの返信処理をslash commandへ移す時の確認です。
初回応答を決める
Interactionは受信後すぐ初回応答が必要です。重い処理、外部API、DB、画像生成を待つ場合はdeferし、処理後にedit/follow-upします。
公開範囲を決める
権限不足、入力ミス、個人向け結果はephemeralにし、共有したい結果だけ公開にします。prefix時代のmessage.replyをそのまま置き換えないようにします。
確認ポイント
- reply/defer
- edit/follow-up
- ephemeral
- 例外時の応答
参考(公式ドキュメント)
helpとサブコマンド設計
helpや大量コマンドをslash commandの構造へ整理します。
一覧を分ける
helpはコマンド一覧、引数、権限、例、失敗時の案内を分けます。slash commandではサブコマンドや説明文を使い、巨大な単一helpへ寄せすぎないようにします。
古い記事を読み替える
prefix command handlerや古いCommand Handler記事は、Interactionの登録、応答期限、権限設定へ読み替えます。現在の公式情報と利用ライブラリの版を確認します。
確認ポイント
- コマンドを用途別に分ける
- 説明文を短くする
- 権限不足時の返信を用意する
参考(公式ドキュメント)
コマンド引数・権限・cooldown
引数変換とconverter
User、Member、Role、Channel、ID指定がうまくいかない時の確認です。
型を分ける
UserとMember、Role、TextChannel、Thread、Forumなどは扱いが違います。引数変換で失敗した時は、利用者に何を入力すべきか短く返します。
失敗を見せる
変換失敗を例外で終わらせず、入力例、対象サーバー内に存在するか、Botが見えるかを案内します。管理ログには入力型、対象ID、失敗理由を残します。
確認ポイント
- User/Memberを分ける
- Role/Channelを分ける
- 入力例を返す
- 例外全文を記録する
参考(公式ドキュメント)
- https://discordpy.readthedocs.io/en/stable/ext/commands/commands.html
- https://docs.discord.com/developers/resources/channel
DMとチャンネル限定
DMでは動く/動かない、特定チャンネルだけで実行したい時の確認です。
実行場所を分ける
DM、guild text、thread、forum、管理チャンネルでは取得できる情報や権限が違います。guild_id、channel_id、member情報が必要なコマンドはDMで実行できないことがあります。
限定条件を明示する
コマンドを特定チャンネルだけに限定する場合は、対象IDを設定値にし、権限不足や場所違いの返信を用意します。
確認ポイント
- DM可否
- 対象guild/channel
- thread/forum対応
- 場所違いの返信
参考(公式ドキュメント)
- https://docs.discord.com/developers/interactions/application-commands
- https://docs.discord.com/developers/topics/permissions
権限チェックとエラー返信
利用者権限、Bot権限、ロール階層を分けます。
誰の権限か
利用者が実行できるか、Botが実行できるか、対象ロールや対象メンバーに対して操作できるかは別です。Administratorで原因を隠さず、必要権限を分けて確認します。
返信とログを分ける
利用者には短い説明を返し、管理ログには必要権限、現在の権限、対象ID、例外を残します。秘密情報や個人情報は公開ログに出しません。
確認ポイント
- 利用者権限
- Bot権限
- ロール階層
- app_permissions
- 管理ログ
参考(公式ドキュメント)
cooldownと連投対策
連投、重い処理、外部API呼び出しを止めすぎず守る設計です。
単位を決める
cooldownはuser、guild、channel、command、外部API単位などで意味が変わります。全体で止めるのか、一人だけ止めるのかを決めます。
例外と解除を決める
管理者の除外、失敗時にcooldownを消すか、外部API rate limitとの関係、利用者への残り時間表示を決めます。連投対策は荒らし対策だけでなく、Bot自身の安定運用にも関わります。
確認ポイント
- cooldown単位
- 重い処理のdefer
- 残り時間の返信
- 失敗時の扱い
参考(公式ドキュメント)
Interaction応答・defer/follow-up
初回応答期限とdefer
重い処理の前にInteractionへ先に応答します。
最初に到達ログを見る
slash commandやbutton callbackが動かない時は、登録や権限より先にhandler先頭へ到達しているか確認します。到達後に外部API、DB、画像処理を待つなら、初回応答やdeferを先に行います。
重い処理を後ろへ逃がす
検索、スクレイピング、DB集計、画像生成、ファイル処理は応答期限を超えやすい処理です。処理中表示、timeout、失敗時返信、管理ログを分けます。
確認ポイント
- handler先頭ログ
- reply/defer
- timeout
- 処理中表示
参考(公式ドキュメント)
edit/follow-upとephemeral
初回応答後にどこへ何を返すかを分けます。
見える範囲を決める
個人向けの入力ミス、権限不足、認証切れ、管理情報はephemeralへ寄せ、共有したい結果だけ公開します。後から公開/非公開を変えられない場面もあるため、初回応答時点で方針を決めます。
更新先を固定する
defer後のedit、追加のfollow-up、エラー返信、キャンセル時返信を混同すると、二重返信や期限切れが起きます。ライブラリのreply済みフラグやinteraction tokenの期限も確認します。
確認ポイント
- 公開/非公開
- editReply
- followUp
- 二重返信
- 期限
参考(公式ドキュメント)
Interaction失敗時の例外ログ
利用者返信と管理ログを分けます。
例外を握りつぶさない
callback内のtry/catchで例外を消すと、利用者には無反応に見えます。利用者には短く返し、管理ログには例外名、対象コマンド、guild/channel、権限、HTTP statusを残します。
権限と応答を分ける
Bot権限不足、ユーザー権限不足、対象チャンネル不一致、Interaction token期限切れは修正場所が違います。同じ「反応しない」として扱わないようにします。
確認ポイント
- 例外名
- コマンド名
- 権限
- HTTP status
- token期限
参考(公式ドキュメント)
- https://docs.discord.com/developers/interactions/receiving-and-responding
- https://docs.discord.com/developers/topics/permissions
外部API/DB待ちとの分離
外部処理の失敗でInteraction全体を壊さない設計です。
処理を段階化する
入力確認、初回応答、外部API/DB処理、結果整形、返信更新を分けると、どこで止まったかログから見えます。外部処理の失敗はInteraction応答の失敗とは別に扱います。
再試行しすぎない
rate limit、timeout、認証切れ、DB接続切れを同じretryで扱うと悪化します。再試行可否、待機時間、利用者への短い返信、管理ログを決めます。
確認ポイント
- 入力確認
- 初回応答
- 外部処理
- 返信更新
- retry可否
参考(公式ドキュメント)
Button・Select・Modal・Embed
Button/Selectのcustom id
押されたUIを安全に識別します。
custom idを設計する
custom idには機能名、対象ID、短い状態を入れますが、Token、個人情報、長いJSONを入れないようにします。押したuser、対象message、期待する状態をcallback先頭で確認します。
古いUIを無効化する
ページング、投票、ロール選択などは、古いmessageのボタンが押されることがあります。作成時刻、操作できるuser、対象guild/channelを確認します。
確認ポイント
- custom id
- 押したuser
- 対象message
- 古いUI
- 秘密情報を入れない
参考(公式ドキュメント)
Modal入力とvalidation
入力欄の不足や形式違いを利用者へ返します。
入力の責務を分ける
Modalはまとまった入力に向いていますが、長すぎる値、URL、ID、改行、空文字、権限が必要な対象はvalidationが必要です。処理前に利用者へ短く返します。
保存前に確認する
DB保存、Webhook送信、外部API送信の前に、入力値の長さ、形式、公開範囲、再送時の重複を確認します。
確認ポイント
- 必須項目
- 文字数
- URL/ID形式
- 公開範囲
- 重複
参考(公式ドキュメント)
component timeoutと押せる人
UIがいつまで誰に有効かを決めます。
操作できる人を限定する
ページング、確認ボタン、管理操作は、実行者だけが押せるのか、権限を持つ人なら押せるのか、全員が押せるのかを決めます。失敗時はephemeralで短く返します。
期限切れ後を整える
timeout後はボタンを無効化する、再実行を促す、古いmessageを残す/消すなどを決めます。timeoutでcallbackが消えた状態を無反応に見せないようにします。
確認ポイント
- 実行者限定
- 権限確認
- timeout
- disabled表示
- 再実行
参考(公式ドキュメント)
Embed・添付・外部URL表示
表示方式ごとの制限と安全性を確認します。
表示方式を分ける
Embed本文、Embed画像、添付ファイル、attachment://、外部URL、OGP展開は扱いが違います。画像や添付の実物をwebsiteへ直接入れず、読み取った内容を文章化します。
伏せる情報を見る
スクリーンショットやEmbedにはToken、Webhook URL、ユーザー名、サーバー名、外部URLが写り込みます。公開記事では個別URLや画像を載せず、確認手順へ変換します。
確認ポイント
- Embed本文
- 添付ファイル
- attachment://
- 外部URL
- 画像は文章化
参考(公式ドキュメント)
一次情報(公式ドキュメント)
- Discord Developer Documentation: Application Commands
- Discord Developer Documentation: Interactions
- discord.py commands extension documentation
- Discord Developer Documentation: Permissions
- Discord Developer Documentation: Receiving and Responding
- Discord Developer Documentation: Components
- Discord Developer Documentation: Message Resource