2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【discord.py】Button 入門〜削除ボタンを作る〜

Last updated at Posted at 2023-06-19

はじめに

discord.py または Pycord で以下のように bot のレスポンスに押したら消せるボタンを付けます.(スラッシュコマンドでも可)
image.png
説明は少なめでコードを見て雰囲気を掴んでもらうスタイルでいきます.

前提知識

  • 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 国際 ライセンス)の元で公開します.

2
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?