前置き
本記事ではdiscord.py 2.0を使います。
まだダウンロードしてない場合は
$ python -m pip install -U discord
でインストールしてください
1.commands.Botには...?
discord.pyV2.0にはSlashCommandを使うためのapp_commands
が入ってます。
discord.Client
は別の記事でも言いましたがtree = app_commands.CommandTree
を定義する必要がありました。ですがcommands.Bot
にはapp_commands
が入ったdiscord.Client
を継承してるので定義は必要ないです。
2.実際に試してみる
import discord
from discord import app_commands
from discord.ext import commands
INITAL_EXTENSIONS = [
"cogs.help",
"cogs.verify",
# いろいろ入れます
]
class DiscordBot(commands.Bot):
def __init__(self, intents: discord.Intents, help_command=None, command_prefix: str):
super().__init__(
intents=intents,
help_command=help_command,
command_prefix=command_prefix
)
async def setup_hook(self):
self.tree.copy_global_to(guild=discord.Object(id=ここにサーバーID))
await self.tree.sync(guild=discord.Object(id=ここにサーバーID))
return await super().setup_hook()
intents = discord.Intents.all()
bot = DiscordBot(intents=intents, command_prefix="!")
@bot.event
async def on_ready():
print("Logged!")
if __name__ == "__main__":
async def boot():
for cogs in INITAL_EXTENSTIONS:
await bot.load_extenstion(cogs)
asyncio.run(boot())
bot.run("TOKEN_HERE")
ちなみにファイル構成は↓のような感じです
/
├ cogs
│ ├ help.py
│ └ verify.py
└ main.py
各cogs内のpythonファイルは以下のような感じです。
import discord
from discord.ext import commands
from discord import app_commands
class HogeCog(commands.Cog):
def __init__(self, bot: commands.Bot):
super().__init__()
self.bot = bot
@commands.Cog.listener()
async def on_ready(self):
print("[Cogs] HogeCog is ready.")
@app_commands.command(name="hoge", description="hogehoge")
async def hoge(self, interaction: discord.Interaction):
await interaction.response.send_message("こんにちは世界")
async def setup(bot: commands.Bot): # この関数が超重要
await bot.add_cog(HogeCog(bot))
はい。
最後の関数setup
はめちゃめちゃ大切です。これがないとmain.py
が読み込んでくれません。
注意点として、HogeCogはcommands.Cogを継承しているクラスなので、__init__
メゾットでself
キーワードを定義しているのでhogeメゾットにはもちろんself
を入れてください。
じゃないと引数がずれてエラーが出ます。
3.discord.uiを使ってみる
uiってなんだ。という方は世の中のbotを見てみて下さい。
そのbotたちには例えばボタンdiscord.ui.Button
やそれを格納するビューdiscord.ui.View
、あとは文字入力ウィンドウであるモーダルdiscord.ui.Modal
があると思います。
それをどのようにcog内で展開するか説明します(というか今回のメインテーマここ...?)
import discord
from discord.ext import commands
from discord import app_commands
class HogeView(discord.ui.View):
def __init__(self, bot: commands.Bot):
super().__init__(
timeout=None
)
self.bot = bot
@discord.ui.button(label="hogebutton", style=discord.ButtonStyle.danger, custom_id="hoge_btn1")
async def callback_hogebutton(self, button: discord.Button, interaction: discord.Interaction):
await button.response.send_message("あなたはボタンを押しました")
class HogeCog(commands.Cog):
def __init__(self, bot: commands.Bot):
super().__init__()
self.bot = bot
@commands.Cog.listener()
async def on_ready(self):
print("[Cogs] HogeCog is ready.")
@app_commands.command(name="hoge", description="hogehoge")
async def hoge(self, interaction: discord.Interaction):
await interaction.response.send_message(view=HogeView(bot=self.bot))
async def setup(bot: commands.Bot):
await bot.add_cog(HogeCog(bot))
こんな感じです。
もちろんclassを分離させるので、self.botを使いたいとき(bot.get_user()
とか?)に使えません。そんなときにはHogeView
の__init__
に引数としてbotを定義しましょう。
もちろんclass内の__init__
に定義したので、self.bot = bot
でself.botを使えるようにしなければいけないです。
import discord.py
from discord.ext import commands
# 略
class HogeModal(discord.ui.Modal)
def __init__(self, bot: commands.Bot):
super().__init__(title="タイトル")
self.text = discord.TextInput(label="何か入力してみよう...", style=discord.TextStyle.short, min_value=1, max_value=40, required=True)
self.add_item(self.text)
def on_submit(self, interaction: discord.Interaction):
value = self.text.value
await interaction.response.send_message("あなたの入力した文字はこれですね?¥n{}".format(value))
#略
@app_commands.command(name="hoge_modal", description="HogeModal")
async def hoge_modal(self, interaction: discord.Interaction):
await interaction.response.send_modal(HogeModal(self.bot))
こんな感じです。
注意点としては、send_message
ではなくsend_modal
でModalを継承したクラスを送信することです。
また、ModalはModalで直接送信できません。要するにModalを継承したクラス内のon_submit
メゾット内ではsend_modal()
で新たなModalは送信できない事です。これは一つdiscord.ui.View
を挟んだりしてModalを送ればいけます。
4.終わりに
cogsとSlashCommandを一緒に動かすといった日本語の文献が少なかった(GitHubには英語版の詳細な文献がありますが...)ので備考録(兼みなさんのために)的に書いてみました。
よかったらフォロー・いいねください。モチベーションが高まります。