Note:
The below was written for the older 0.16 version, which did not have good documentation of cogs. The new 1.0 version has good documentation, and has completely changed the structure of cogs. If you're using a modern version of discord.py, you should consult the official documentation.
Introduction
Every cog has two parts: a class and a setup
function. Almost all setup
functions look the same:
def setup(bot):
bot.add_cog(Cog(bot))
where Cog
is the cog class.
The cog class contains all of our commands and events as methods.
Main Changes
There are four main transformations that you need to do to change your bot to a cog:
Replace bot.command
with commands.command
(commands
being from discord.ext import commands
)
Change the signatures of your functions to include self
at the beginning, as all of your commands and events are now methods of the cog class
Change all references to bot
to refer to self.bot
instead
Remove all bot.event
decorators. Event listeners from your cog are registered on name alone
There are also some gotchas:
Remove await bot.process_commands(message)
from any on_message
events in your cog. For any message this should only be awaited once. The default on_message
does already does this for you.
Registering an event through a cog does not remove other callbacks related to that event, from your main file or other cogs. That means that your bot could respond to a on_member_join
event multiple times for example, if you have behaviour for that event defined in multiple places.
Example
Let's say you have the following discord.py bot, bot.py
in the directory src
:
from discord.ext import commands
bot = commands.Bot(command_prefix='!')
@bot.command(pass_context=True)
@commands.has_role("Mod")
async def acommand(ctx, argument):
await bot.say("Stuff")
@bot.event
async def on_message(message):
print(message.content)
await bot.process_commands(message)
bot.run("token")
You then factor that functionality out into a cog src/cogs/maincog.py
from discord.ext import commands
class MainCog:
def __init__(self, bot):
self.bot = bot
@commands.command(pass_context=True)
@commands.has_role("Mod")
async def acommand(self, ctx, argument):
await self.bot.say("Stuff")
async def on_message(self, message):
print(message.content)
def setup(bot):
bot.add_cog(MainCog(bot))
And your bot.py
file would look like
from discord.ext import commands
bot = commands.Bot(command_prefix='!')
bot.load_extension("cogs.maincog")
bot.run("token")
Note that to load the extension at cogs/maincog.py
, we use load_extension("cogs.maincog")
.
Other features
Cogs also allow you to define some special methods. Most of these are available only in discord.py-rewrite and are documented here.
__global_check
, formerly __check
, runs before every command and must return True
for that command to proceed.
__local_check
runs only before commands from this cog.
__global_check_once
I believe that this is similar to __global_check
except that it only checks once in the case of subcommands. I haven't used this much.
__unload
You can live refresh your bot by unloading the extension, then reloading it, allowing you to update your cogs without taking your bot offline. This method is called when you unload the extension, or when your bot stop running, in case you need to do cleanup.
__before_invoke
and __after_invoke
are run before and after every command from this cog, respectively.
__error
is an error handler for commands from this cog.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…