Home > Software design >  Discord.py - Can't get custom commands to work within inherited class
Discord.py - Can't get custom commands to work within inherited class

Time:11-15

I'm trying to get custom commands to work in my Discord server. But it doesn't work when I'm not using a decorator, and I do not know how to make it work within a class.

Please help.

(XXX.. just replaces an ID here)

Please have a look at add_my_commands() function. This one should be able to take the prefix and respond with the info. This doesn't work currently.

I have a main.py file which runs separately, as follows:

# Import discord.py
import discord
from discord.ext import commands

# Import Bot Token
from apikeys import *

# Import classes
from steward_bot import MyClient

intents = discord.Intents.default()  # or .all() if you ticked all, that is easier
intents.message_content = True
intents.members = True  # If you ticked the SERVER MEMBERS INTENT

# Initialize client
bot = MyClient(command_prefix="!", intents=intents)
bot.run(DISCORD_TOKEN)

The MyClient class:

class MyClient(commands.Bot):
    def __init__(self, *args, command_prefix, **kwargs):
        super().__init__(
            *args, command_prefix=command_prefix, case_insensitive=True, **kwargs
        )
        self.target_message_id = XXXX
        self.add_my_commands()

    async def on_ready(self):
        print("We have logged in as {0.user}".format(self))
        print("---------------------------------------------")

    async def on_member_remove(self, member):
        channel = self.get_channel(XXXX)
        await channel.send("Goodbye")

    async def on_raw_reaction_add(self, payload):
        """
        Give a role based on a reaction emoji
        """
        if payload.message_id != self.target_message_id:
            return

        guild = self.client.get_guild(payload.guild_id)

        print(payload.emoji.name)
        print("Hello")

    # Responding to messages
    async def on_message(self, message):

        if message.author == self.user:
            return

        if message.content == "Test":
            await message.channel.send("Hey hey chill")

        if message.content == "cool":
            await message.add_reaction("\U0001F60E")

        if message.content == "give me our prefix":
            await message.channel.send(str(self.command_prefix))

        await self.process_commands(message)

    # Throws out reactions to messages
    async def on_reaction_add(self, reaction, user):
        await reaction.message.channel.send(f"{user} reacted with {reaction.emoji}")

    def add_my_commands(self):
        @self.command(name="info", pass_context=True)
        async def info(ctx):
            """
            ctx - context (information about how the command was executed)

            info
            """
            print(ctx)
            await ctx.send("Hello X")
            await ctx.send(ctx.guild)
            await ctx.send(ctx.author)
            await ctx.send(ctx.message.id)

Within the server, I want to run the command "!info" and get the information out. Would appreciate any help!

CodePudding user response:

No need to define your entire bot within a class. Create a main.py file with your bot defined and import cogs from there. I'd also set up my commands through a cog with commands.command().

Example of how I'd go about adding an !info command:

main.py

import discord
from discord.ext import commands
from info import InfoCog

intents = discord.Intents.default()
intents.members = True
intents.guilds = True
intents.messages = True
intents.reactions = True
intents.presences = True
# Initialize client
bot = commands.Bot(command_prefix='!', intents=intents)

bot.add_cog(InfoCog(bot))

@bot.event
async def on_ready(self):
        print("We have logged in as {0.user}".format(self))
        print("---------------------------------------------")

bot.run(TOKEN)

info.py

import discord
from discord.ext import commands

class InfoCog(commands.Cog):
    def __init__(self, bot):
        self.bot = bot

    

    @commands.command()
    async def info(self, ctx):
        await ctx.send('Info')

Or, you could jumble everything into one file. This is how I used to do it with all my commands & events. It was easier to get the hang of at first.

main.py

# Import discord.py
import discord
from discord.ext import commands

intents = discord.Intents.default()
intents.members = True
intents.guilds = True
intents.messages = True
intents.reactions = True
intents.presences = True

bot = commands.Bot(command_prefix='!', intents=intents)


@bot.event
async def on_ready(bot):
        print("We have logged in as {0.user}".format(bot))
        print("---------------------------------------------")

# [...]

@bot.command()
async def info(ctx):
    await ctx.send('info')

# [...]

@bot.event
async def on_message(message):
    if message.author == bot.user:
        return
    if message.content == "give me our prefix":
        await message.channel.send(str(bot.command_prefix))
    if message.content == "Test":
        await message.channel.send("Hey hey chill")
    # [...]

@bot.event()
async def on_member_remove(member):
    channel = bot.get_channel(CHANNELID)
    await channel.send(f"Goodbye, {member}")

# [...]

bot.run(TOKEN)
  • Related