はじめに
discord.py または Pycord で以下のように bot のレスポンスに押したら消せるボタンを付けます.(スラッシュコマンドでも可)
説明は少なめでコードを見て雰囲気を掴んでもらうスタイルでいきます.
前提知識
- Python の基本的な文法(クラスなど)
- 超基本的な Discord bot の作り方(トークンの発行の仕方やインテントなど)
筆者の環境
- MX Linux 21.3
- Python 3.10.9
- discord.py 2.3.0(py-cord 2.4.1 でも動作確認済み)
Discord におけるボタンとは
Button は 2021 年 5 月 26 日に Discord に追加された UI Component で,他には Select Menu や Modal があります.また,スラッシュコマンドと同様に Interaction というオブジェクトでユーザと bot の対話を実現します.ボタンなどの UI Component は callback
メソッドを定義することで,インタラクションを受け取った時(ボタンなら押された時)の処理を記述できます.
一旦 ping コマンド
今回はテキストのコマンドでやります.スラッシュコマンドでも同様にできます.
ベースのコードは discord.py の README から拝借しました.
import discord
from discord.ext import commands
intents = discord.Intents.default()
intents.message_content = True
bot = commands.Bot(command_prefix='>', intents=intents)
@bot.command()
async def ping(ctx):
await ctx.send('pong')
bot.run('token')
誰でも消せる削除ボタン
send
(スラッシュコマンドなら send_message
など)の引数に View というものを与えることができます.
この View に Button などを追加していきます.
import discord
from discord.ext import commands
intents = discord.Intents.default()
intents.message_content = True
bot = commands.Bot(command_prefix='>', intents=intents)
# discord.ui.Button を継承し,callback 関数をオーバーライド
class DeleteButton(discord.ui.Button):
async def callback(self, interaction: discord.Interaction):
await interaction.message.delete()
@bot.command()
async def ping(ctx: commangds.Context):
view = discord.ui.View()
delete_button = DeleteButton(label='Delete', style=discord.ButtonStyle.red)
view.add_item(delete_button) # 作ったボタンを view に追加
await ctx.send('pong', view=view) # view と一緒にメッセージを送信
bot.run('token')
これではじめに貼ったようなボタンができて,押すとメッセージが消えると思います.
コマンドを呼んだ人しか消せないようにする
先程のコードでは誰でもボタンを押せば消せたと思いますが,コマンドを呼んだ人しか消せないようにしたい場合も多いと思います.そこで DeleteButton
を以下のように変更します.
class DeleteButton(discord.ui.Button):
# コンストラクタの引数に user を追加
def __init__(self, user: discord.User, style=discord.ButtonStyle.red, label='Delete', **kwargs):
self.user_id = user.id # クラス変数にユーザ ID を保存
super().__init__(style=style, label=label, **kwargs)
async def callback(self, interaction: discord.Interaction):
# 保存したユーザとボタンを押したユーザが同じかどうか
if self.user_id == interaction.user.id:
await interaction.message.delete()
さらに DeleteButton
のインスタンスを作る時,
DeleteButton(ctx.author)
のようにユーザを渡します.完成形のコードがこちら.
import discord
from discord.ext import commands
intents = discord.Intents.default()
intents.message_content = True
bot = commands.Bot(command_prefix='>', intents=intents)
# discord.ui.Button を継承
class DeleteButton(discord.ui.Button):
# コンストラクタの引数に user を追加
def __init__(self, user: discord.User, style=discord.ButtonStyle.red, label='Delete', **kwargs):
self.user_id = user.id # クラス変数にユーザ ID を保存
super().__init__(style=style, label=label, **kwargs)
async def callback(self, interaction: discord.Interaction):
# 保存したユーザとボタンを押したユーザが同じかどうか
if self.user_id == interaction.user.id:
await interaction.message.delete()
@bot.command()
async def ping(ctx: commands.Context):
view = discord.ui.View()
delete_button = DeleteButton(ctx.author) # コマンドを呼んだユーザを渡す
view.add_item(delete_button) # 作ったボタンを view に追加
await ctx.send('pong', view=view) # view と一緒にメッセージを送信
bot.run('token')
これでコマンドを呼んだ人しか消せないボタンが作れました.
参考文献
この記事のライセンス
この記事はCC BY 4.0(クリエイティブ・コモンズ 表示 4.0 国際 ライセンス)の元で公開します.