DEV Community

Swislok-Dev
Swislok-Dev

Posted on

Customize Python Discord bot

Cogs
Loading Cogs

Some Event Listeners

Event listeners can be used in many different ways like keeping track of the servers that the bot gets added to.

To keep track of what server your bot has joined, the on_guild_join() method can be called via the @client.event decorator.

  • mkdir guilds.json
  • import json Python module
import json

...

@client.event
async def on_guild_join(guild):
    with open('guilds.json', 'r') as f:
        guilds = json.load(f)
    # Set default prefix variable and name of server
    guilds[str(guild.id)] = {
        "guild Name": guild.name,
        "Prefix": "$"
    }
    # Push dictionary to JSON file
    with open('guilds.json', 'w') as f:
        json.dump(guilds, f, indent=4)

...
Enter fullscreen mode Exit fullscreen mode

Likewise for when the bot is removed from the server to clean up the JSON file with on_guild_remove().

...

@client.event
async def on_guild_remove(guild):
    with open('guilds.json', 'r') as f:
        guilds = json.load(f)
    # Remove guild dictionary from JSON file
    guilds.pop(str(guild.id))
    # Apply changes to file
    with open('guilds.json', 'w') as f:
        json.dump(guilds, f, indent=4)

...
Enter fullscreen mode Exit fullscreen mode

If you would like to create some interaction with the bot and have a "conversation" the on_message() method has some things it can do.

This can be customized to fit your needs, but here's a basic example.

...

@client.event
async def on_message(message):
    # Stop the bot from replying to itself or any other bot
    if message.author.bot: return

    # Send a reply to a human
    if message.content == "ping":
        await message.channel.send("pong")

...
Enter fullscreen mode Exit fullscreen mode

Cogs

Adding commands and event listeners to the main file will create unnecessary clutter. Using extensions will create a space to fill in more methods to be used in more concise ways. To do this, the Cog class will be required.

Cog Decorator

To create a cog file, each will need to an instance of a new class.

Cog template

from nextcord.ext import commands

class <ClassName>(commands.Cog):
    # Initialize with `self` and `bot: commands.Bot`
    def __init__(self, bot: commands.Bot):
        self.bot = bot
    # All commands/listeners always take a parameter of "self"
    @commands.Cog.listener()
    async def <commandName>(self):

        # Do some stuff

def setup(bot: commands.Bot):
    bot.add_cog(<ClassName>(bot))
Enter fullscreen mode Exit fullscreen mode

Error Handler

Having a custom error handler will come in handy to provide client feedback about their issued command.

...

async def on_command_error(self, ctx: commands.Content, error: commands.CommandError):
    if isinstance(error, commands.CommandNotFound):
        message = f'{error}'
    elif isinstance(error, commands.UserInputError):
        message = 'Your input was incorrect'
    else:
        message = 'Something went wrong while running a command'

    await ctx.send(message, delete_after=5)
    await ctx.message.delete(delay=5)

...
Enter fullscreen mode Exit fullscreen mode

The isinstance() method takes in two parameters and returns a boolean:

  • an object
  • class or tuple
  • returns bool

Loading Cogs

After creating some cogs, go back into the main bot.py file and a for loop will be needed to load the cogs upon bot startup.

Along with this if not already done, you'll need to import the os module at the top of the file.

import os
...

# Load extensions on bot start
for filename in os.listdir('./cogs'):
    if filename.endswith('.py'):
        client.load_extension(f'cogs.{filename[:-3]}')

...
Enter fullscreen mode Exit fullscreen mode

If now errors found within the extensions the bot will start up and the cogs will now be ready for use.

Top comments (0)