-
Notifications
You must be signed in to change notification settings - Fork 0
Adding and Editing Commands
Before continuing, you should have at least some knowledge of python, as adding commands does require writing code.
You may also want to have a look at the discord.py documentation
gBot has been coded to make adding new features relatively easy. New commands/features (cogs) go into .py files in the cogs folder. While not strictly necessary, it is recommended you have only 1 command per file, as this lets the help command that comes with gBot list the commands properly.
Here's an example cog file:
## Initialization
import discord
from common import config, log, embedMessage, category
from discord.ext import commands
## Class setup
class exampleCommand(commands.Cog):
def __init__(self, bot):
self.bot = bot
## Help stuff
self.hidden = False
self.category = category.getCategory(self.__module__)
self.description = "Adds numbers together but is overly finnicky about it."
self.usage = f"""
{config.cfg['options']['prefix']}exampleCommand <first number> <second number>
"""
## Config stuff
self.firstNumber = config.cfg['settings']['exampleCommand']['firstNumber']
self.favNumber = config.cfg['settings']['exampleCommand']['favNumber']
self.listenFor = config.cfg['settings']['exampleCommand']['listenFor']
self.replyWith = config.cfg['settings']['exampleCommand']['replyWith']
## Command defining
@commands.command(aliases=['add','badd'])
@commands.has_guild_permissions(embed_links=True, attach_files=True)
async def exampleCommand(self, ctx, arg1: int, arg2: int):
if arg1 == 9 and arg2 == 10:
embed = embedMessage.embed(
title = 'whas nahn plus tehn?',
description = 'twenny wan',
color = embedMessage.defaultColor
)
await ctx.send(embed=embed)
return
if arg1 != self.firstNumber:
embed = embedMessage.embed(
title = 'ERROR',
description = f'Sorry, the first number must be {self.firstNumber}!',
color = embedMessage.errorColor
)
await ctx.send(embed=embed)
return
ans = arg1 + arg2
if ans == self.favNumber:
embed = embedMessage.embed(
title = 'WOW!',
description = f'The answer is {self.favNumber}, my favorite number!',
color = discord.Color.from_rgb(255, 215, 0)
)
await ctx.send(embed=embed)
return
embed = embedMessage.embed(
title = 'SUCCESS',
description = f'The answer is {ans}.',
color = embedMessage.defaultColor
)
await ctx.send(embed=embed)
## Listener defining
@commands.Cog.listener()
async def on_message(self, msg):
if msg.guild.me.id != msg.author.id and msg.content.startswith(self.listenFor):
await msg.reply(self.replyWith)
## Allow use of cog class by main bot instance
def setup(bot):
bot.add_cog(exampleCommand(bot))
...a bit of a wall of text, so let's break it down piece by piece
## Initialization
import discord
from common import config, log, embedMessage, category
from discord.ext import commands
Starting off easy, this is where you should put your imports. In this case, we are importing discord.py and its command module, which lets us interface with the Discord API easily, and makes command creation much simpler. We are also importing some things from the common folder:
-
config: Allows us to accessconfig.yamlfor easy user customization. -
log: You should always have this, makes logging work. -
embedMessage: Helps make embeds easier to use. -
category: Lets the command be categorized based on its parent folder
## Class setup
class exampleCommand(commands.Cog):
def __init__(self, bot):
self.bot = bot
This defines what the class is called, which should be kept the same as the command name unless you don't want this command to show up in help. It lets us refer to the bot later in the file as self.bot.
## Help stuff
self.hidden = False
self.category = category.getCategory(self.__module__)
self.description = "Adds numbers together but is overly finnicky about it."
self.usage = f"""
{config.cfg['options']['prefix']}exampleCommand <first number> <second number>
"""
This section is where you should put things that the help command will use to display the command in the help menu. The options here are:
-
self.hidden: If true, this command will NOT show up in help. -
self.category: If you want your command to be put into a category, you need this. The stuff after the=automatically sets the category to the subfolder the file is in, orMiscif it is not in one. -
self.description: A short description that appears with the commands name in help. -
self.usage: The usage and syntax of the command. Shows up when you dohelp <command>.
## Config stuff
self.firstNumber = config.cfg['settings']['exampleCommand']['firstNumber']
self.favNumber = config.cfg['settings']['exampleCommand']['favNumber']
self.listenFor = config.cfg['settings']['exampleCommand']['listenFor']
self.replyWith = config.cfg['settings']['exampleCommand']['replyWith']
This section is just putting config settings (from config.yaml) into variables, for easy access later.
## Command defining
@commands.command(aliases=['add','badd'])
@commands.has_guild_permissions(embed_links=True, attach_files=True)
async def exampleCommand(self, ctx, arg1: int, arg2: int):
This part simply defines some stuff about the command.
-
@commands.command(aliases=['add','badd']): This means that this is a command, and not something like a listener. Here you can also define what aliases can be used to do the same action (in this case,addandbadd), though it isn't required. -
@commands.has_guild_permissions: This is a decorator that checks if the user running the command has the permissions needed to use the command. List of valid permissions here. -
async def exampleCommand: This is where you put the word used to invoke the function, in this case that would bebadd. -
(self, ctx, arg1: int, arg2: int): This is defining the commands input arguments, if any.-
self: Required, must be first. By being in a class, the command is automatically given the class as the first argument. -
ctx: Required, must be second. It means context, and allows easy referring to attributes of the message containing the command. -
arg1: int: The first argument given by the user will be stored in the variablearg1as an integer.arg2is exactly the same.
-
if arg1 == 9 and arg2 == 10:
embed = embedMessage.embed(
title = 'whas nahn plus tehn?',
description = 'twenny wan',
color = embedMessage.defaultColor
)
await ctx.send(embed=embed)
return
This if statement checks to see if arg1 is 9, and arg2 is 10. If both are, it outputs an embed containing a special message. Embed parameters are:
-
title: The text shown at the top of the embed. -
description: The text in the embed, shown before thebodytext. -
sections: A list of different sections to be in the embed, follows the format(title,content). -
body: A list of entries, they should be separated by<hr>, follows the same order assections. -
colororcolour: A discord.Colour object that overrides the default color, which is the vertical bar on the left of the embed. -
url: A webpage to link to. -
thumbnail: This should be a link/url to an image. It will be displayed small at the top right of the embed. -
image: This should be a link/url to an image. It will be displayed large at the bottom of the embed -
footer: Some text to put at the bottom of the embed.
if arg1 != self.firstNumber:
embed = embedMessage.embed(
title = 'ERROR',
description = f'Sorry, the first number must be {self.firstNumber}!',
color = embedMessage.errorColor
)
await ctx.send(embed=embed)
return
This if statement checks if the first argument is the same as firstNumber, which is defined in config.yaml. If it isn't, it outputs an error telling the user why it refuses to add the 2 given numbers.
ans = arg1 + arg2
if ans == self.favNumber:
embed = embedMessage.embed(
title = 'WOW!',
description = f'The answer is {self.favNumber}, my favorite number!',
color = discord.Color.from_rgb(255, 215, 0)
)
await ctx.send(embed=embed)
return
embed = embedMessage.embed(
title = 'SUCCESS',
description = f'The answer is {ans}.',
color = embedMessage.defaultColor
)
await ctx.send(embed=embed)
This section defines ans as arg1 plus arg2, checks if ans is the same as favNumber (defined in the config), and if it is, outputs an embed with a special color, stating the answer as its favorite number. If ans is not the same as favNumber, it simply outputs the answer in an embed.
## Listener defining
@commands.Cog.listener()
async def on_message(self, msg):
This part is defining a listener, which activates when something happens. In this case, it activates when a message is sent. A list of listeners can be found here and here.
if msg.guild.me.id != msg.author.id and if msg.content.startswith(self.listenFor):
await msg.reply(self.replyWith)
This part checks to make sure that the message sent wasn't a message sent by the bot, which prevents the bot constantly replying to itself, then it makes sure that the message starts with the correct word/phrase/string defined in config.yaml. If both of these conditions are met, the bot replies with the string defined in the config.
## Allow use of cog class by main bot instance
def setup(bot):
bot.add_cog(exampleCommand(bot))
The last part, this finalizes the cog, allowing it to be used by the bot.
This was just an example. You can look at the other default cogs to see how some more useful commands and features work, but they don't have wiki pages explaining how they work in extreme detail, so you're on your own if you want to reverse-engineer them.
Editing commands is much simpler than making a new one, it simply involves tweaking things that aren't set up as configurable in config.yaml within the cog file itself. Depending on what you are editing, you might be able to do it even without experience with python, though I would still recommend you have some before doing so.