Contents
Discord Bot スラッシュコマンド実装の概要
Discord Botスラッシュコマンドは、ユーザーが/commandという形式で直接コマンドを送信できる機能です。この仕組みにより、Botの操作性と開発者の制御精度が向上します。特にdiscord.py v2.xでは、WebSocket型Bot向けにapp_commandsモジュールが導入され、同期型のスラッシュコマンド実装が可能になりました。本記事では、この最新バージョンを対象とした実装手順とコード例を解説します。
開発環境構築準備
Python環境とdiscord.pyのセットアップは、スラッシュコマンド開発の第一歩です。ここでは、必要なツールのインストール方法をステップバイステップで紹介します。
Pythonインストール手順
- 公式サイト(https://www.python.org/)から最新版Pythonをダウンロード
- インストーラー起動時に「Add to PATH」にチェックを入れ、環境変数を設定
- コマンドプロンプトで
python --versionを実行し、インストール確認
注意:WindowsユーザーはPython 3.10以上、macOS/Linuxユーザーはシステム標準のPythonと競合しないように仮想環境を使用することを推奨します。
discord.pyのv2.x導入方法
|
1 2 |
pip install -U discord.py |
その後バージョン確認を行うには以下を実行:
|
1 2 3 4 |
import discord print(discord.__version__) # 出力例: 2.5.0 |
重要:discord.py v1.xは2023年9月に公式サポート終了。v2.x以降を使用する必要があります。
Discord開発者ポータルでのBot登録フロー
スラッシュコマンドを使用するには、Discordアプリケーションを作成してBotトークンを取得することが前提です。
アプリケーション作成手順
- https://discord.com/developers/applications を開く
- 「New Application」→アプリ名(例: MySlashBot)を入力して作成
- 左サイドバーの「Bot」タブを選択 → 「Add Bot」をクリック
- ボットトークンは「Token」セクションで確認可能。この値を安全に保存
Botトークンの取得方法
アプリケーション作成後、以下の手順でBotをサーバーに導入できます:
- 「OAuth2」タブ → 「Scopes」で
botを選択 - 「Permissions」で必要な権限(例:
Send Messages)を追加 - 生成されたURLをDiscordサーバーの「Add Bot」ページで使用
補足: スラッシュコマンドは、Botが所属するGuild限定またはグローバルに登録可能です。Guild限定の場合、
guild_idsパラメータで指定します。
app_commandsモジュールの基本構造
discord.py v2.xでは、app_commandsモジュールを使用してスラッシュコマンドを定義します。以下が基本的な構文です。
Commandクラスの定義方法
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
import discord from discord import app_commands class MyBot(discord.Client): def __init__(self, *, intents: discord.Intents): super().__init__(intents=intents) self.tree = app_commands.CommandTree(self) async def on_ready(self): print(f"Logged in as {self.user} (ID: {self.user.id})") await self.tree.sync() bot = MyBot(intents=discord.Intents.default()) |
ポイント:
app_commands.CommandTreeを初期化し、sync()メソッドでコマンドを同期します。
Interaction処理の流れ
スラッシュコマンドが実行された際には、on_app_command_completionイベントが発生します。以下に例を示します:
|
1 2 3 4 |
@bot.tree.command(name="hello", description="Hello World!") async def hello(interaction: discord.Interaction): await interaction.response.send_message("こんにちは!") |
| ステップ | 内容 |
|---|---|
| 1 | @bot.tree.commandでコマンドを登録 |
| 2 | interactionオブジェクトでユーザー情報を取得 |
| 3 | response.send_message()で結果を返す |
スラッシュコマンドの登録・実行処理
スラッシュコマンドは、Botが所属するサーバーまたはグローバルに登録できます。以下に両方の方法を紹介します。
Guild限定コマンド登録
Guildごとに異なるコマンドを設定したい場合、guild_idsパラメータを使用します:
|
1 2 3 4 |
@bot.tree.command(guild=discord.Object(id=1234567890)) async def guild_only(interaction: discord.Interaction): await interaction.response.send_message("このサーバー限定のコマンドです") |
グローバルコマンドの同期方法
グローバルにコマンドを公開するには、sync()メソッドで全Guildに反映させます:
|
1 2 |
await bot.tree.sync(guild=None) |
注意: 本番環境では定期的に同期処理を行うとよいです。
on_readyイベント内で実行するのが一般的です。
Autocomplete機能の実装方法
スラッシュコマンドでユーザーが入力途中を補完する機能も可能です。以下に実装手順を紹介します。
選択肢生成関数の作成
|
1 2 3 4 5 6 7 |
@app_commands.autocomplete("option") async def autocomplete_option(interaction: discord.Interaction, current: str): return [ app_commands.Choice(name="選択肢1", value="value1"), app_commands.Choice(name="選択肢2", value="value2"), ] |
パラメータ検索ロジック
Autocompleteは、currentパラメータでユーザー入力の文字列を取得し、該当する選択肢をフィルタリングします:
|
1 2 3 4 5 |
@bot.tree.command(name="search") @app_commands.autocomplete("query", autocomplete_function) async def search(interaction: discord.Interaction, query: str): await interaction.response.send_message(f"検索キーワード: {query}") |
補足: Autocompleteは最大25件の選択肢を返せます。動的なデータベース参照も可能です。
|
1 2 3 4 5 6 7 |
def autocomplete_function(interaction: discord.Interaction, current: str): # 例: データベースから取得するロジック return [ app_commands.Choice(name="value1", value="value1"), app_commands.Choice(name="value2", value="value2"), ] |
Cloud Runなど本番環境への適用ポイント
クラウド環境でスラッシュコマンドを運用する際には、以下のような注意点があります:
環境変数管理
- Botトークンを明文でコードに記載しない
os.environ["BOT_TOKEN"]を使用して安全に取得
例:
|
1 2 3 |
import os bot = MyBot(token=os.environ.get("DISCORD_BOT_TOKEN")) |
WebSocket接続の最適化
Cloud Runでは、WebSocket接続が自動的に終了される場合があります。以下を設定することで改善できます:
websocketsライブラリを使用して接続を明示的に維持- 長時間アイドル時に送信するPingパケットを実装
具体的な例:
|
1 2 3 4 5 6 7 8 9 |
import websockets import asyncio async def keep_alive(): async with websockets.connect("wss://gateway.discord.gg/?v=9&encoding=json") as websocket: while True: await websocket.send('{"op": 1, "d": {"token": "BOT_TOKEN", "properties": {}}}') await asyncio.sleep(60) # 60秒ごとにPing送信 |
- Cloud Run設定:
SERVICE_ACCOUNTにcloud-run-defaultを使用- マイクロサービスのライフサイクル管理でリセット処理を実装
ポイント: パフォーマンスチューニングでは、コマンドの処理時間を極力短くすることが重要です。
GitHubサンプルコードによる動作確認
本記事で紹介したコード例を実際に動かすには、GitHubリポジトリからクローンしてローカルで実行します。
レポジトリのクローン手順
- https://github.com/discord-py/examples を開く
- 「Code」→「Download ZIP」でプロジェクトをダウンロード
注意: GitHubリポジトリのURLは実際のリンクに置き換えてください。
ローカルでの実行方法
- Python環境が整っていることを確認
-
以下のコマンドで依存ライブラリをインストール:
bash
pip install -r requirements.txt -
config.pyにBotトークンを記入し、以下を実行:
bash
python main.py
トラブルシューティング: エラーが発生した場合は、Discordデベロッパータグでログ確認。
discord.utils.get()を使用してユーザーIDを特定する方法も試してください。
|
1 2 3 4 5 6 |
import discord # ユーザーIDからメンバーを取得する例 member = discord.utils.get(guild.members, id=1234567890) print(member.name) # 出力: ユーザー名 |
補足情報
-
Cloud RunとWebSocketの注意点:
- アプリケーションが終了するたびに接続を再確立する必要があるため、定期的なPing送信が必須
- サービスアカウントに
cloud-run-invokerロールを割り当てる
-
Autocompleteの最適化:
- 検索キーワードに応じた動的フィルタリング実装
- 最大25件まで返却可能(Discord API制限)
-
セキュリティ対策:
- Botトークンは
secretsまたは環境変数で管理 - ローカル開発時は
dotenvライブラリを使用して.envファイルから読み込むことで安全化
- Botトークンは