カテゴリー: Discordボット開発
Discordボット開発#6ドロップダウン(Select Menu)メニューを実装しよう!
この記事は韓国語の原文から翻訳したものです。
目次8項目
こんにちは!Mojangcamです 😎
前回の#5ではボタン(Button)でボットとやり取りする方法を紹介しましたよね?今回はさらに一歩進んで、ドロップダウンメニュー(Select Menu) を作ってみます!
ボタンは選択肢が2〜3個のときには便利ですが、選択肢が5個以上になると画面がボタンで埋め尽くされてしまいます。そんなときにドロップダウンメニューを使えば、最大25個の選択肢を1つのメニューにすっきりまとめられます。ロール選択、アンケート、ゲームサーバーの選択メニューなど、本当によく使われています!

📌 準備するもの
- Python 3.8 以上
- discord.py 2.x (Select Menuは2.0から対応しています!)
- ボットトークン + サーバーへのボット招待済み (シリーズ第1回を参照!)
pip install -U discord.pyバージョンは pip show discord.py で確認できます。2.x以上ならOK!1.xでは動作しません。
📌 ステップ1 - Select(ドロップダウン)クラスを作る
ドロップダウンの要は discord.ui.Select クラスです。このクラスを継承して、選択肢(SelectOption)と選択されたときの動作(callback)を定義します。
import discord
from discord.ext import commands
class GameSelect(discord.ui.Select):
def __init__(self):
options = [
discord.SelectOption(label="マインクラフト", value="minecraft", description="ブロックで作る世界", emoji="⛏️"),
discord.SelectOption(label="ARK サバイバル", value="ark", description="恐竜と一緒にサバイバル!", emoji="🦖"),
discord.SelectOption(label="VALORANT", value="valorant", description="5対5のタクティカルFPS", emoji="🔫"),
]
super().__init__(
placeholder="好きなゲームを選んでください!",
min_values=1,
max_values=1,
options=options,
)
async def callback(self, interaction: discord.Interaction):
await interaction.response.send_message(
f"🎮 {interaction.user.mention}さんが **{self.values[0]}** を選択しました!"
)1つずつ見ていきましょう 💡
SelectOption: ドロップダウンに表示される選択肢の1つ1つです。labelは画面に表示される名前、valueはコードで受け取る値、descriptionはグレーの説明文、emojiは先頭に付く絵文字です。placeholder: 何も選択していないときに表示される案内文です。min_values/max_values: 最小・最大の選択数です。max_values=3にすると複数選択メニューになります!(最大25)callback: ユーザーが選択を終えると実行される関数です。選択された値はself.valuesリストに入ります。
📌 ステップ2 - Viewに入れる
ボタン編で学んだように、すべてのUIコンポーネントはViewというコンテナに入れて送る必要があります。
class GameSelectView(discord.ui.View):
def __init__(self):
super().__init__(timeout=60) # 60秒後に無効化
self.add_item(GameSelect())ちなみに、ドロップダウン1つはViewの1行(row)を丸ごと使います。Viewは最大5行なので、1つのViewに入れられるドロップダウンは最大5個までです。
📌 ステップ3 - スラッシュコマンドで送信する
intents = discord.Intents.default()
bot = commands.Bot(command_prefix="!", intents=intents)
@bot.event
async def on_ready():
await bot.tree.sync()
print(f"✅ {bot.user} ボットの準備ができました!")
@bot.tree.command(name="게임선택", description="好きなゲームを選んでみてください!")
async def game_select(interaction: discord.Interaction):
await interaction.response.send_message("下から選んでください! 👇", view=GameSelectView())
bot.run("Token")📌 全体のコード (コピペOK)
# discord.py 2.x / Python 3.8+
import discord
from discord.ext import commands
class GameSelect(discord.ui.Select):
def __init__(self):
options = [
discord.SelectOption(label="マインクラフト", value="マインクラフト", description="ブロックで作る世界", emoji="⛏️"),
discord.SelectOption(label="ARK サバイバル", value="ARK サバイバル", description="恐竜と一緒にサバイバル!", emoji="🦖"),
discord.SelectOption(label="VALORANT", value="VALORANT", description="5対5のタクティカルFPS", emoji="🔫"),
]
super().__init__(placeholder="好きなゲームを選んでください!", min_values=1, max_values=1, options=options)
async def callback(self, interaction: discord.Interaction):
await interaction.response.send_message(
f"🎮 {interaction.user.mention}さんが **{self.values[0]}** を選択しました!"
)
class GameSelectView(discord.ui.View):
def __init__(self):
super().__init__(timeout=60)
self.add_item(GameSelect())
intents = discord.Intents.default()
bot = commands.Bot(command_prefix="!", intents=intents)
@bot.event
async def on_ready():
await bot.tree.sync()
print(f"✅ {bot.user} ボットの準備ができました!")
@bot.tree.command(name="게임선택", description="好きなゲームを選んでみてください!")
async def game_select(interaction: discord.Interaction):
await interaction.response.send_message("下から選んでください! 👇", view=GameSelectView())
bot.run("Token")📌 実行結果
/게임선택 と入力すると、ボットがドロップダウン付きのメッセージを送信します。メニューからゲームを選ぶと「🎮 ○○さんが マインクラフト を選択しました!」という返信が届きます。
💡 ボーナス: ユーザー・ロール・チャンネルを選ぶ専用のドロップダウンもあります!discord.ui.UserSelect、discord.ui.RoleSelect、discord.ui.ChannelSelect を使えば、選択肢を自分で作らなくてもサーバーのユーザー/ロール/チャンネル一覧が自動で表示されます。機会があれば今後詳しく取り上げますね!
📌 よくあるエラー
1. This interaction failed (インタラクションに失敗しました)
callbackの中で3秒以内に応答しないと発生します。処理に時間がかかる場合は、先に await interaction.response.defer() を呼び出してから interaction.followup.send() で返信すればOKです。
2. ドロップダウンがグレーになって無効化される
View(timeout=60) の時間が過ぎると、コンポーネントが期限切れになります。ずっと動作させたいメニューなら timeout=None に設定してください。(ボットの再起動後も維持するにはpersistent view + custom_id の指定が必要ですが、これは応用編で扱います!)
3. TypeError: __init__() got an unexpected keyword argument 'options'
discord.ui.Select ではなく UserSelect のような専用セレクトに options を渡すと出るエラーです。選択肢を自分で定義するときは、必ず基本の discord.ui.Select を使ってください。
📌 まとめ
今回はドロップダウン(Select Menu)で最大25個の選択肢をすっきりまとめる方法を紹介しました。ボタン → ドロップダウンまで来たので、次回はモーダル(Modal)でユーザーから直接テキスト入力を受け取る方法を扱います!お楽しみに 🙌
📚 Discordボット開発シリーズ
- スラッシュコマンド完全攻略
- スラッシュコマンドにオプション(Arguments)を追加する
- スラッシュコマンドにサブコマンドを追加する
- スラッシュコマンドで埋め込みを送信する
- ボタン(Button)のインタラクションを実装する
- ドロップダウン(Select Menu)メニューを実装する ← 今読んでいる記事!
連載 · 全32回中6回目
Discordボット開発
- #1Discordボット開発 - スラッシュコマンド(Slash Command)完全攻略!
- #2スラッシュコマンドにオプション(Arguments)を追加しよう!
- #3スラッシュコマンドにサブコマンド(Subcommand)を追加しよう!
- #4スラッシュコマンドで埋め込み(Embed)を送信しよう!
- #5ボタン(Button)のインタラクションを実装しよう!
- #6ドロップダウン(Select Menu)メニューを実装しよう!現在の記事
- #7モーダル(Modal)で入力を受け取る方法 (Pythonサンプル付き)
- #8埋め込み(Embed)を画像・フィールドで飾る (Pythonサンプル付き)
- #9AI(Claude・ChatGPT API)と連携する! (Pythonサンプル付き)
- #10多言語(i18n)に対応する! (Pythonサンプル付き)
- #11FlaskでWebダッシュボードを作る! (Pythonサンプル付き)
- #12コマンドのクールダウン(Cooldown)・権限(Permission)を管理しよう! (Pythonサンプル付き)
- #13ロール・チャンネルの自動化でサーバーを管理しよう! (Pythonサンプル付き)
- #14データを保存しよう!JSON vs SQLite (Pythonサンプル付き)
- #15슬래시 명령어 그룹(Group)으로 명령어 정리하기! (파이썬 예제) (韓国語)
- #16리마인더·알림 기능 만들기! 봇이 먼저 말 걸게 하기 (파이썬 예제) (韓国語)
- #17RAG로 문서 기반 답변봇 만들기! 우리 서버 전용 FAQ 봇 (파이썬 예제) (韓国語)
- #18투표(Poll) 기능 만들기! 다수결로 정하는 서버 규칙 (파이썬 예제) (韓国語)
- #19Cog로 코드 쪼개기! 1000줄 봇도 안 더러워지는 구조 (파이썬 예제) (韓国語)
- #20자동 환영 메시지·온보딩 만들기! 규칙 동의 버튼으로 자동 역할 부여 (파이썬 예제) (韓国語)
- #21키워드 자동응답·금지어 필터 만들기! 경고 누적으로 자동 제재까지 (파이썬 예제) (韓国語)
- #22슬래시 명령어 자동완성(Autocomplete) 만들기! 금지어를 골라서 추가·삭제 (파이썬 예제) (韓国語)
- #23aiosqlite로 비동기 DB 제대로 설계하기! JSON 탈출 (파이썬 예제) (韓国語)
- #24채널 난독화(Channel Obfuscation) 대응하기! 11/16부터 안 보이는 채널이 생겨요 (파이썬 예제) (韓国語)
- #25봇이 죽지 않게! 에러 핸들링·로깅 체계 잡기 (파이썬 예제) (韓国語)
- #26티켓(Ticket) 문의 시스템 만들기! 버튼 하나로 1:1 상담 채널 자동 생성 (파이썬 예제) (韓国語)
- #27티켓 담당자 배정·우선순위 만들기! 스태프가 여러 명이어도 안 꼬이게 (파이썬 예제) (韓国語)
- #28레벨·경험치(XP) 시스템 만들기! 채팅할수록 레벨업, 랭킹판까지 (파이썬 예제) (韓国語)
- #29화폐·상점(Economy) 시스템 만들기! 코인 벌어서 아이템 사기 (파이썬 예제) (韓国語)
- #30投票・アンケート(Poll)ボットを作ろう!ネイティブ投票+ボタンでリアルタイム集計まで(Pythonサンプル) 🗳️
- #32サーバーログ・監査ログ(Audit Log)チャンネルを作ろう!メッセージの削除・編集・入退室・キックまで自動記録(Pythonサンプル) 🕵️
- #33임시 음성방 확장, 파티방 만들기! 방장 위임·강퇴·초대 전용(비공개) 방 + 전용 채팅방 자동 생성 (파이썬 예제) 🎉 (韓国語)
