0
1

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 でCog・Extensionを使ってみよう!

Posted at

はじめに

こんにちは、@nano_sudoです。
discord.pyでBotを作るとき、コードが長くなってしまうことがあります。
そんなときに便利なのが、Cog・Extensionです。
今回はdiscord.pyのCog・Extensionの使い方を説明します。

前提知識

  • pythonの基礎的な文法(関数やクラスなど)

Cogとは

Botを機能ごとに分けることができる機能です。
以下はdiscord.py公式ドキュメントの説明です。

Bot開発においてコマンドやリスナー、いくつかの状態を一つのクラスにまとめてしまいたい場合があるでしょう。コグはそれを実現したものです。(discord.pyドキュメント)

Cog・Extensionを使うメリット

  • 機能のグループ化
    Cogを使用することで、Botの機能をグループに分けることができる。
    (例:音楽コマンドや管理コマンドなど)
  • 再利用性の向上
    Cogをコピーすれば、他のボットに同様の機能を簡単に実装することができる。
  • 柔軟性
    Extensionを利用するとCogの有効化や無効化を簡単に行えるので、必要に応じてBotの動作を変更することができる。
  • 開発の快適性
    Extensionにはホットリロード機能がついているので、開発がより快適にできるようになる。

Cogの最小構成

コマンドは従来のcommands.command()ではなく、app_commands.command()を使います。
app_commandsでは、discordクライアントにコマンドの候補を表示することができます。

Cogを分ける基準

機能ごとに分けるのがおすすめです。
例:音楽コマンド、管理コマンドなど

ファイル構成

.
├── main.py
└── cogs
    └── hello.py
cogs/hello.py
from discord.ext import commands
from discord import app_commands

# commands.Cogを継承する
class MyCog(commands.Cog):
    def __init__(self, bot)
        self.bot = bot
    
    # イベントリスナー(ボットが起動したときやメッセージを受信したとき等)
    @commands.Cog.listener()
    async def on_ready(self):
        print("Cog ready!")
	
    # コマンドデコレーター(descriptionで説明が書ける)
    @app_commands.command(name="hello")
    async def hello(self,interaction:discord.Interaction)
        await interaction.response.send_message("hello!")

コードの解説

Cogの定義

class Hello(commands.Cog):

commands.Cogを継承することで、Cogを定義することができます。

コンストラクター

def __init__(self,bot)
    self.bot = bot

コンストラクターには必ずbot引数を入れてください。

イベントリスナー

@commands.Cog.listener()
async def on_ready(self):
    print("Cog ready!")

@commands.Cog.listener()デコレーターをつけることで、イベントリスナーを定義することができます。
ほかにも、on_messageon_member_joinなどのイベントリスナーがあります。

コマンドデコレーター

@app_commands.command(name="hello")
async def hello(self,interaction:discord.Interaction)
    await interaction.response.send_message("hello!")

@app_commands.command()デコレーターをつけることで、コマンドを定義することができます。
description引数でコマンドの説明を書くことができます。
name引数と関数名が一致していないと、エラーが発生するので注意です。

Cogの有効化

main.py
from discord.ext import commands
from cogs.hello import MyCog


# Botの定義
class MyBot(commands.Bot):
    def __init__(self):
        super().__init__(
            command_prefix="!",
            intents=discord.Intents.all()
        )

    async def setup_hook(self) -> None:
        guild_ids = [123456789012345678] # すぐに同期したいサーバーのIDを入れる
        await self.tree.sync(guild=None)
        for g in guild_ids:
            try:
                await self.tree.sync(guild=g)
            except discord.errors.Forbidden:
                # やりすぎるとForbiddenになるので、一応例外処理を入れておく
                print(f"サーバーID:{g}に登録できませんでした。")

bot = MyBot()

if __name__ == "__main__":
    # Cogを有効化
    bot.add_cog(MyCog(bot))
    # Botを起動
    bot.run("token")

コマンドを使うには、Bot().tree.sync()で一度同期する必要があります。
グローバルにコマンドを同期するには、guild=Noneにします。
私はいつも、setup_hookで同期していますが、ほかに良い方法があればぜひ教えてください!
bot.add_cog()でCogを使ってCogを有効化することができます。

ExtensionからCogを有効化

Extension経由で読み込むと、ホットリロードや有効化・無効化が簡単にできるので、おすすめ

extensionを使用して読み込む場合は、Cogにsetup関数を定義してください。

cogs/hello.py
# 以下をファイルの最後に追加
async def setup(bot):
    await bot.add_cog(MyCog(bot))

main.pyのif __name__ == "__main__"以下をこのように変更してください。

main.py
# 以下をおきかえる
if __name__ == "__main__":
    # Extensionを有効化
    await bot.load_extension("cogs.hello")
    # Botを起動
    bot.run("token")

まとめ

いかがでしたか?
今回はdiscord.pyのCog・Extensionの使い方を説明しました。
discord.pyを使ってBotを作るときは、ぜひCog・Extensionを使ってみてください!
質問やご意見・ご指摘などあれば、Twitterかコメント欄にお願いします!

Zennにも投稿しています!

0
1
0

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
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?