如何在discord.py中使用扩展/插件

1 投票
1 回答
46 浏览
提问于 2025-04-14 15:51

这是我用来启动机器人的代码

# bot.py
import discord
from discord import app_commands
from discord.ext import commands, tasks
from itertools import cycle
import humanize
import random

bot = commands.Bot(command_prefix="?", intents=discord.Intents.all())

bot_status = cycle(["Wow.", "Isn't. This.", "Cool?"])


@tasks.loop(seconds=10)
async def change_status():
    await bot.change_presence(activity=discord.Game(next(bot_status)))


@bot.event
async def on_ready():
    try:
        await bot.tree.sync()

        print(f'Synced')
    except Exception as e:
        print(e)
    print("Ready")
    change_status.start()


def calculate_result(number):
    if "M" in number.upper():
        power = number.upper()
        tp = int(power.replace("M", ""))
        calc = 20000 + tp * 10
        return humanize.intword(calc)
    elif "B" in number.upper():
        power = number.upper()
        tp = int(power.replace("B", ""))
        calc = 60000 + tp * 60
        return humanize.intword(calc)
    elif "T" in number.upper():
        power = number.upper()
        tp = int(power.replace("T", ""))
        calc = 140000 + tp * 600
        return humanize.intword(calc)
    else:
        return None


def number_conversion(durability):
    if "K" in durability.upper():
        power = durability.upper()
        dura = int(power.replace("K", ""))
        return dura * 1000
    elif "M" in durability.upper():
        power = durability.upper()
        dura = int(power.replace("M", ""))
        return dura * 1000000
    elif "B" in durability.upper():
        power = durability.upper()
        dura = int(power.replace("B", ""))
        return dura * 1000000000
    elif "T" in durability.upper():
        power = durability.upper()
        dura = int(power.replace("T", ""))
        return dura * 1000000000000
    else:
        return None


@bot.tree.command(name='sync', description='Owner only')
async def sync(interaction: discord.Interaction):
    await bot.tree.sync()
    await interaction.response.send_message('Command tree synced.')


@bot.command()
async def update_commands(ctx):
    await bot.update_commands()


@bot.tree.command(name="hitcost")
@app_commands.describe(dura="The durability power of the person you wish to put a hit on")
async def calculate_command(interaction: discord.Interaction, dura: str):
    result = calculate_result(dura)
    if result is not None:
        embed = discord.Embed(color=00000, title="Hit Cost")
        embed.add_field(name=f"Cost for {dura.upper()}", value=f"{result}")
        await interaction.response.send_message(embed=embed)
    else:
        await interaction.response.send_message("Invalid Power Level. Please use M, B, or T.", ephemeral=True)


bot.run("TOKEN")

现在我尝试把命令和命令功能放到另一个.py文件里(命名为commands.py),我使用了cogs和扩展(我都试过,因为我不知道哪个更适合我想做的事情)。这样我就可以运行bot.py,同时把命令的部分移到command.py(我不直接运行这个文件),它仍然可以正常工作。但是无论我怎么尝试,它都不行(可能是因为我不能使用cogs/扩展)。有没有人能给我一个示例代码,让我明白怎么做?非常感谢!

1 个回答

1

Cogs 是一种很方便的方式来组织你机器人的命令和其他功能。Cogs 是从 commands.Cog 这个类派生出来的,这个类在命令扩展中可以找到。通常,Cogs 会放在单独的文件里,并作为扩展加载。

discord.py 的一个基本 Cog 示例

cog_example_ext.py

from discord import app_commands
from discord.ext import commands

# all cogs inherit from this base class
class ExampleCog(commands.Cog):
    def __init__(self, bot):
        self.bot = bot # adding a bot attribute for easier access

    # adding a command to the cog
    @commands.command(name="ping")
    async def pingcmd(self, ctx):
        """the best command in existence"""
        await ctx.send(ctx.author.mention)
    
    # adding a slash command to the cog (make sure to sync this!)
    @app_commands.command(name="ping")
    async def slash_pingcmd(self, interaction):
        """the second best command in existence"""
        await interaction.response.send_message(interaction.user.mention)

    # adding an event listener to the cog
    @commands.Cog.listener()
    async def on_message(self, message):
        if message.guild and message.guild.me.guild_permissions.ban_members:
            await message.author.ban(reason="no speek") # very good reason

    # doing something when the cog gets loaded
    async def cog_load(self):
        print(f"{self.__class__.__name__} loaded!")

    # doing something when the cog gets unloaded
    async def cog_unload(self):
        print(f"{self.__class__.__name__} unloaded!")

# usually you’d use cogs in extensions
# you would then define a global async function named 'setup', and it would take 'bot' as its only parameter
async def setup(bot):
    # finally, adding the cog to the bot
    await bot.add_cog(ExampleCog(bot=bot))

main.py

import discord
from discord.ext import commands

TOKEN = "your token"

class ExampleBot(commands.Bot):
    def __init__(self):
        # initialize our bot instance, make sure to pass your intents!
        # for this example, we'll just have everything enabled
        super().__init__(
            command_prefix="!",
            intents=discord.Intents.all()
        )
    
    # the method to override in order to run whatever you need before your bot starts
    async def setup_hook(self):
        await self.load_extension("cog_example_ext")

ExampleBot().run(TOKEN)

参考资料:

撰写回答