カテゴリー: Discordボット開発

Discordボット開発#5ボタン(Button)のインタラクションを実装しよう!

この記事は韓国語の原文から翻訳したものです。

目次8項目

こんにちは!Mojangcamです 😎

前回の#4ではスラッシュコマンドで埋め込みを送信してみましたよね?今回はさらに一歩進んで、メッセージにクリックできるボタン(Button)を付けてみます!ボタンを押すとボットが反応する、本当の意味で「インタラクティブなボット」を作ってみましょう。

完成すると、こんなことができるようになります:

  • ✅ 確認 / ❌ キャンセルボタンでユーザーに選択肢を提示する
  • 🎫 チケット作成やロール付与のようなワンクリック機能
  • ボタンを押した人にだけ見える返信を送る

📌 準備するもの

  • Python 3.8 以上
  • discord.py 2.x (ボタン機能は2.0から対応しています!)
  • ボットトークン + サーバーへのボット招待済み (第1回を参照!)
ターミナル
pip install -U discord.py

バージョンが古い場合は必ずアップデートしてください。バージョンは pip show discord.py で確認できます。

📌 ステップ1 - ボタンの要、Viewを理解する

discord.pyのボタンは単体では使えず、Viewというコンテナに入れてメッセージと一緒に送ります。

  • discord.ui.View → ボタンやドロップダウンなどを入れる箱 📦
  • discord.ui.button デコレーター → View の中にボタンを作り、押されたときに実行する関数を紐づける

まずは構造だけ見てみましょう!

Python
import discord

class MyView(discord.ui.View):
    @discord.ui.button(label="押してみて!", style=discord.ButtonStyle.primary)
    async def my_button(self, interaction: discord.Interaction, button: discord.ui.Button):
        await interaction.response.send_message("ボタンが押されました!")

⚠️ コールバック関数の引数の順番は (self, interaction, button) です。他のライブラリ(pycordなど)のサンプルとは順番が逆なので、混同しやすいので注意してください!

📌 ステップ2 - ボタンのスタイルを知ろう

style= に指定できるボタンの色は5種類です。

スタイル 色 用途の例
ButtonStyle.primary 青 メインの操作
ButtonStyle.secondary グレー 補助的な操作
ButtonStyle.success 緑 確認/承認
ButtonStyle.danger 赤 削除/拒否
ButtonStyle.link リンク型 URLへ移動 (url= が必要、コールバックなし)

📌 ステップ3 - 確認/キャンセルボタンを作る

実践で一番よく使う確認/キャンセルのパターンを作ってみます。

Python
class ConfirmView(discord.ui.View):
    def __init__(self):
        super().__init__(timeout=60)  # 60秒後にボタンを無効化

    @discord.ui.button(label="確認", style=discord.ButtonStyle.success)
    async def confirm(self, interaction: discord.Interaction, button: discord.ui.Button):
        await interaction.response.edit_message(content="✅ 確認しました!", view=None)

    @discord.ui.button(label="キャンセル", style=discord.ButtonStyle.danger)
    async def cancel(self, interaction: discord.Interaction, button: discord.ui.Button):
        await interaction.response.edit_message(content="❌ キャンセルしました。", view=None)

ポイントまとめ 💡

  • timeout=60 : 60秒が経過するとボタンは動作しなくなります (デフォルトは180秒)
  • edit_message(..., view=None) : ボタンを押すと元のメッセージを編集しつつボタンを削除
  • interaction.response は3秒以内に1回だけ応答できます。さらに送信したい場合は interaction.followup.send() を使ってください!

📌 ステップ4 - 全体のコード (コピペOK)

スラッシュコマンドと組み合わせた完成版です。

Python
import discord
from discord.ext import commands

intents = discord.Intents.default()
bot = commands.Bot(command_prefix="/", intents=intents)

class ConfirmView(discord.ui.View):
    def __init__(self):
        super().__init__(timeout=60)

    @discord.ui.button(label="確認", style=discord.ButtonStyle.success)
    async def confirm(self, interaction: discord.Interaction, button: discord.ui.Button):
        await interaction.response.edit_message(content="✅ 確認しました!", view=None)

    @discord.ui.button(label="キャンセル", style=discord.ButtonStyle.danger)
    async def cancel(self, interaction: discord.Interaction, button: discord.ui.Button):
        await interaction.response.edit_message(content="❌ キャンセルしました。", view=None)

@bot.event
async def on_ready():
    await bot.tree.sync()
    print(f"{bot.user} ボットの準備ができました!")

@bot.tree.command(name="확인", description="確認/キャンセルボタンを送信します")
async def confirm_command(interaction: discord.Interaction):
    await interaction.response.send_message("続行しますか?", view=ConfirmView())

bot.run("Token")

📌 結果を確認しよう

ボットを起動してDiscordのチャンネルで /확인 と入力すると、「続行しますか?」というメッセージと一緒に緑の確認ボタンと赤のキャンセルボタンが表示されます!ボタンを押すとメッセージが「✅ 確認しました!」に変わり、ボタンが消えます。

📌 よくあるエラー

1. ボタンを押したら「インタラクションに失敗しました」と表示される

コールバックで3秒以内に応答しなかったときに発生します。処理に時間がかかる場合は、先に await interaction.response.defer() を呼び出してください。

2. TypeError: ... missing 1 required positional argument

コールバックの引数の順番の問題です!discord.py 2.xは (self, interaction, button) の順番です。(self, button, interaction) と書くとこのエラーが出ます。

3. ボットを再起動すると、以前のメッセージのボタンが押せなくなる

Viewは基本的にメモリ上にしか存在しません。再起動後も動作させるには、timeout=None + custom_id を指定したpersistent viewを作り、bot.add_view() で登録する必要があります。(これは今後の応用編で扱います!)

📌 まとめ

今回はdiscord.pyのViewとボタンでクリックのインタラクションを実装してみました。

  • ボタンはViewに入れて送信
  • スタイルは5種類 (primary/secondary/success/danger/link)
  • 応答は3秒以内に、1回だけ!

次回はドロップダウン(Select Menu)メニューを作ってみる予定です。お楽しみに 🙌

📚 Discordボット開発シリーズ

  1. スラッシュコマンド完全攻略
  2. スラッシュコマンドにオプション(Arguments)を追加する
  3. スラッシュコマンドにサブコマンドを追加する
  4. スラッシュコマンドで埋め込みを送信する
  5. ボタン(Button)のインタラクションを実装する ← 今読んでいる記事!

連載 · 全32回中5回目

Discordボット開発

  1. #1Discordボット開発 - スラッシュコマンド(Slash Command)完全攻略!
  2. #2スラッシュコマンドにオプション(Arguments)を追加しよう!
  3. #3スラッシュコマンドにサブコマンド(Subcommand)を追加しよう!
  4. #4スラッシュコマンドで埋め込み(Embed)を送信しよう!
  5. #5ボタン(Button)のインタラクションを実装しよう!現在の記事
  6. #6ドロップダウン(Select Menu)メニューを実装しよう!
  7. #7モーダル(Modal)で入力を受け取る方法 (Pythonサンプル付き)
  8. #8埋め込み(Embed)を画像・フィールドで飾る (Pythonサンプル付き)
  9. #9AI(Claude・ChatGPT API)と連携する! (Pythonサンプル付き)
  10. #10多言語(i18n)に対応する! (Pythonサンプル付き)
  11. #11FlaskでWebダッシュボードを作る! (Pythonサンプル付き)
  12. #12コマンドのクールダウン(Cooldown)・権限(Permission)を管理しよう! (Pythonサンプル付き)
  13. #13ロール・チャンネルの自動化でサーバーを管理しよう! (Pythonサンプル付き)
  14. #14データを保存しよう!JSON vs SQLite (Pythonサンプル付き)
  15. #15슬래시 명령어 그룹(Group)으로 명령어 정리하기! (파이썬 예제) (韓国語)
  16. #16리마인더·알림 기능 만들기! 봇이 먼저 말 걸게 하기 (파이썬 예제) (韓国語)
  17. #17RAG로 문서 기반 답변봇 만들기! 우리 서버 전용 FAQ 봇 (파이썬 예제) (韓国語)
  18. #18투표(Poll) 기능 만들기! 다수결로 정하는 서버 규칙 (파이썬 예제) (韓国語)
  19. #19Cog로 코드 쪼개기! 1000줄 봇도 안 더러워지는 구조 (파이썬 예제) (韓国語)
  20. #20자동 환영 메시지·온보딩 만들기! 규칙 동의 버튼으로 자동 역할 부여 (파이썬 예제) (韓国語)
  21. #21키워드 자동응답·금지어 필터 만들기! 경고 누적으로 자동 제재까지 (파이썬 예제) (韓国語)
  22. #22슬래시 명령어 자동완성(Autocomplete) 만들기! 금지어를 골라서 추가·삭제 (파이썬 예제) (韓国語)
  23. #23aiosqlite로 비동기 DB 제대로 설계하기! JSON 탈출 (파이썬 예제) (韓国語)
  24. #24채널 난독화(Channel Obfuscation) 대응하기! 11/16부터 안 보이는 채널이 생겨요 (파이썬 예제) (韓国語)
  25. #25봇이 죽지 않게! 에러 핸들링·로깅 체계 잡기 (파이썬 예제) (韓国語)
  26. #26티켓(Ticket) 문의 시스템 만들기! 버튼 하나로 1:1 상담 채널 자동 생성 (파이썬 예제) (韓国語)
  27. #27티켓 담당자 배정·우선순위 만들기! 스태프가 여러 명이어도 안 꼬이게 (파이썬 예제) (韓国語)
  28. #28레벨·경험치(XP) 시스템 만들기! 채팅할수록 레벨업, 랭킹판까지 (파이썬 예제) (韓国語)
  29. #29화폐·상점(Economy) 시스템 만들기! 코인 벌어서 아이템 사기 (파이썬 예제) (韓国語)
  30. #30投票・アンケート(Poll)ボットを作ろう!ネイティブ投票+ボタンでリアルタイム集計まで(Pythonサンプル) 🗳️
  31. #32サーバーログ・監査ログ(Audit Log)チャンネルを作ろう!メッセージの削除・編集・入退室・キックまで自動記録(Pythonサンプル) 🕵️
  32. #33임시 음성방 확장, 파티방 만들기! 방장 위임·강퇴·초대 전용(비공개) 방 + 전용 채팅방 자동 생성 (파이썬 예제) 🎉 (韓国語)
全32回を表示閉じる

著者

Mojangcam

自分でコードを書き、サーバーを動かし、詰まったエラーを解決しながら学んだことを記録する開発・IT実践ブログ