Bots do Discord escritos em discord.py muitas vezes se tornam difíceis de manter quando todos os comandos, eventos e tarefas em segundo plano estão em um único arquivo. A arquitetura de cogs resolve isso permitindo dividir seu bot em classes modulares, cada uma lidando com um conjunto específico de funcionalidades. Este artigo explica como projetar um bot usando cogs, carregá-los dinamicamente e manter seu código organizado. Ao final, você será capaz de criar um cog, registrá-lo no bot e usar padrões comuns como tratamento de erros e loops de tarefas dentro de cogs.
Principais Conclusões: Construindo um Bot do Discord com Cogs no discord.py
- Classe Cog e decorador @commands.command: Encapsula comandos e eventos relacionados em uma única classe Python para código modular.
- bot.add_cog() e bot.load_extension(): Registra uma classe cog ou carrega um cog de um arquivo separado durante a inicialização do bot.
- Função setup() em cada arquivo de cog: Necessária para adicionar o cog ao bot quando a extensão é carregada.
O Que São Cogs e Por Que Usá-los no discord.py
Um cog é uma classe Python que agrupa comandos, eventos e listeners relacionados. Em vez de escrever @bot.command() no nível superior do seu arquivo principal, você define o mesmo decorador dentro de uma classe que herda de commands.Cog. O bot então carrega o cog, e todos os seus comandos ficam disponíveis. Essa estrutura reflete a forma como o próprio Discord organiza funcionalidades em módulos como moderação, música ou utilidades.
O principal benefício é a separação de responsabilidades. Um cog de moderação lida com comandos de banir, expulsar e silenciar. Um cog de música lida com comandos de tocar, pular e fila. Se um cog quebrar, o resto do bot ainda funciona. Cogs também facilitam que vários desenvolvedores trabalhem no mesmo bot sem editar o mesmo arquivo.
Pré-requisitos para Usar Cogs
Antes de começar, certifique-se de ter Python 3.8 ou superior e a versão mais recente da biblioteca discord.py instalada. Use pip install discord.py para instalá-la. Você também precisa de um token de bot do Discord obtido no Portal do Desenvolvedor do Discord. Presume-se familiaridade básica com classes Python e decoradores.
Passos para Construir um Bot com Arquitetura de Cogs
Os passos a seguir guiam você na criação de um bot baseado em cogs. O exemplo usa dois arquivos: bot.py (o lançador principal) e cogs/moderation.py (um arquivo de cog). Você pode adicionar mais arquivos de cog para outras funcionalidades.
Passo 1: Criar o Arquivo Lançador do Bot
- Crie uma pasta de projeto
Crie uma pasta chamadameu-bot. Dentro, crie um arquivo chamadobot.pye uma subpasta chamadacogs. - Importe discord e commands
Abrabot.pye adicione as seguintes importações:import discord
from discord.ext import commands - Defina a instância do bot
Adicionebot = commands.Bot(command_prefix='!', intents=discord.Intents.all()). Isso cria um bot que responde ao prefixo!e usa todas as intenções. - Carregue cogs ao ficar pronto
Adicione um eventoon_readyque carrega todos os arquivos de cog da pastacogs:@bot.event
async def on_ready():
await bot.load_extension('cogs.moderation')
print('Bot está pronto') - Execute o bot
Adicionebot.run('SEU_TOKEN_DO_BOT')no final. SubstituaSEU_TOKEN_DO_BOTpelo seu token real.
Passo 2: Escrever um Arquivo de Cog
- Crie o arquivo de cog
Dentro da pastacogs, crie um arquivo chamadomoderation.py. - Importe e defina a classe do cog
Escreva o seguinte código:import discord
from discord.ext import commandsclass Moderation(commands.Cog):
def __init__(self, bot):
self.bot = bot@commands.command()
async def kick(self, ctx, member: discord.Member, , reason=None):
await member.kick(reason=reason)
await ctx.send(f'{member} foi expulso.')def setup(bot):
bot.add_cog(Moderation(bot)) - Entenda a função setup
A funçãosetup()é obrigatória. Quandobot.load_extension()é executado, o discord.py procura uma função chamadasetupe a chama com a instância do bot. Dentro, você cria uma instância do cog e a adiciona ao bot.
Passo 3: Carregar o Cog Dinamicamente
- Use load_extension com notação de ponto
Embot.py, a linhaawait bot.load_extension('cogs.moderation')instrui o bot a carregarcogs/moderation.py. O ponto substitui a barra da pasta. - Adicione mais cogs
Para cada novo arquivo de cog, adicione outra linhaawait bot.load_extension('cogs.NOME')dentro deon_ready. Alternativamente, use um loop para carregar todos os arquivos da pasta. - Recarregue cogs sem reiniciar
Useawait bot.reload_extension('cogs.moderation')para recarregar um cog após editá-lo. Isso evita reiniciar o bot durante o desenvolvimento.
Passo 4: Adicionar Listeners de Eventos Dentro de um Cog
- Use @commands.Cog.listener()
Dentro da classe do cog, decore um método com@commands.Cog.listener()para ouvir eventos. Exemplo:@commands.Cog.listener()
async def on_message(self, message):
if 'palavraofensiva' in message.content:
await message.delete() - O nome do evento é derivado do nome do método
O nome do método deve corresponder ao nome do evento do Discord, comoon_message,on_member_joinouon_reaction_add. O decorador listener o vincula automaticamente.
Passo 5: Usar Grupos e Tratamento de Erros em Cogs
- Crie um grupo de comandos
Use@commands.group()para agrupar subcomandos. Exemplo:@commands.group()
async def config(self, ctx):
if ctx.invoked_subcommand is None:
await ctx.send('Comando de configuração inválido.')@config.command()
async def prefix(self, ctx, new_prefix):
# lógica para alterar prefixo
await ctx.send(f'Prefixo alterado para {new_prefix}') - Adicione um manipulador de erros global para o cog
Sobrescrevacog_command_errordentro da classe do cog:async def cog_command_error(self, ctx, error):
if isinstance(error, commands.MissingPermissions):
await ctx.send('Você não tem permissão para usar este comando.')
Isso captura erros apenas para comandos naquele cog.
Erros Comuns ao Usar Cogs
Esquecer a Função setup()
Se você definir uma classe cog mas omitir a função setup(), o bot levantará um erro ExtensionFailed. Todo arquivo de cog deve ter uma função setup(bot) no nível superior que chame bot.add_cog().
Carregar o Mesmo Cog Duas Vezes
Chamar load_extension para um cog já carregado levanta um erro. Verifique se o cog já está carregado antes de recarregar, ou use reload_extension que descarrega e carrega em um único passo.
Usar @bot.command em Vez de @commands.command Dentro de Cogs
Dentro de uma classe cog, você deve usar @commands.command(), não @bot.command(). A variável bot não está no escopo dentro da classe. O decorador commands funciona com o contexto do cog.
Não Configurar Intenções para Eventos
Se o seu cog ouve eventos como on_message ou on_member_join, o bot deve ter as intenções correspondentes ativadas. Em bot.py, use intents=discord.Intents.all() ou ative intenções específicas. Também ative-as no Portal do Desenvolvedor do Discord em Bot > Privileged Gateway Intents.
Arquivo Único vs Arquitetura de Cogs: Principais Diferenças
| Item | Bot de Arquivo Único | Arquitetura de Cogs |
|---|---|---|
| Organização do código | Todos os comandos e eventos em um arquivo | Comandos divididos em vários arquivos de cog por funcionalidade |
| Manutenibilidade | Difícil de escalar além de 10-20 comandos | Fácil de gerenciar centenas de comandos |
| Isolamento de erros | Um comando ruim pode derrubar o bot inteiro | Erros em um cog não afetam outros cogs |
| Recarregamento | Requer reinicialização completa do bot | Pode recarregar cogs individualmente com reload_extension() |
| Colaboração em equipe | Conflitos de merge comuns | Cada desenvolvedor trabalha em arquivos de cog separados |
Com cogs, você pode agora construir um bot do Discord modular que é mais fácil de manter e estender. Comece convertendo seus comandos existentes em um único cog, depois adicione mais cogs para novas funcionalidades. Para uso avançado, explore loops discord.ext.tasks dentro de cogs para executar tarefas em segundo plano, como limpeza periódica de mensagens ou atualizações de status.