4
votes

I have a public bot that has cogs, but I just tested that if I load/unload a cog then it'll load/unload that cog across every server it's in, this of course is something that's horrible for a public bot

I'll show my load & unload command:

@client.command()
async def load(ctx, extension):
 client.load_extension(f"cogs.{extension}")

 await ctx.send(f"Successfully loaded the {extension} module :thumbsup: ")

@load.error
async def load_error(ctx, error):
 await ctx.send(f"The following error occured:```\n{error}\n```")

is the load command, and:

@client.command()
async def unload(ctx, extension):
 client.unload_extension(f"cogs.{extension}")

 await ctx.send(f"Successfully unloaded the {extension} module :thumbsup: ")

@unload.error
async def unload_error(ctx, error):
 await ctx.send(f"The following error occured:```\n{error}\n```")

is the unload command

Edit: I wouldn't mind trying something other than what I'm attempting

3
You'll have to program your cogs such that they're aware of where the commands are invoked from and ignore them on certain guilds. - Patrick Haugh
I probably wouldn't know how to do that, and I wouldn't be able to set it per server it joins since anyone can invite the bot - Jakaboi

3 Answers

1
votes

You can use a cog_check to check each command in a cog: eg

class MyCog(commands.Cog):
   def cog_check(self, ctx):
      return ctx.guild.id == 123

Since cogs are bound to the bot, loading and unloading them will effect the bot everywhere, there is no better way to make guild only cogs than using this.

0
votes

A solution to this would be adding a simple check to each command in the cogs you don't want public

#add a check to the top of the cog
def isPrivateCommand():
    async def predicate(ctx):
        return ctx.guild.id == YOURGUILDIDHERE
    return commands.check(predicate)

.
.
.

@commands.command
@isPrivateCommand()
async def ...

This check should make sure that the command will only be executed in your guild (the guild ID you put in the check).

Documentation on checks can be found here for discord.py rewrite

Happy coding!

0
votes

cogs belong to the bot, not to a server. So what you try to do is not possible. But (i guess you want to do something like dyno has to activate commands in a guild)

you can save all guilds that "loaded" a command in a database and then add a check to all commands if they are loaded

example_data = {
    "command_name": "example",
    "loaded_guilds": []
}


def isCommandLoaded():
    async def predicate(ctx):
        return ctx.guild.id in example_data["loaded_guilds"]:
    return commands.check(predicate)



@commands.command()
@isCommandLoaded()
async def example(self, ctx):
    """Example ..."""

than just build a load/unload command and save it to the db