Skip to content

Allow command_prefix in client handler to accept predicate function returning a string #69

@SuperSajuuk

Description

@SuperSajuuk

Type of Feature Request

Code

Describe the feature you would like to see implemented.

Currently, setting up a bot requires locking in a specific command_prefix (eg "!" or "?") which cannot be changed, other than by the bot dev (which would be global to all communities).

For small bots, or indeed bots designed for a single community, locking in a prefix is probably quite useful, but if you're building bots where people can configure a lot of functionality for their communities, being able to configure the prefix the bot responds to on a per-guild basis is quite useful. Bot command "collision" is a well known problem, where more than one bot responds to the prefix, because they're all configured to use the same one: as a result, community owners might want to have different bots respond to different prefixes, so no two bots can respond to the same thing.

In discord.py, one way this is achieved is allowing the command_prefix variable in the client handler to accept a predicate function. The predicate returns a string whenever the commands handler is invoked, which can be used by bot developers to dynamically obtain the prefix that is relevant to the community that the bot was invoked in. In this context, the predicate accepts two required positions arguments: the first is the Bot itself, the second is the message that triggered the bot.

An example is below:

py
# Gets the command prefix for the guild, or if nothing is defined, uses "!" as a default.
def get_prefix(bot, message):
	return bot.options[message.guild.id].get("prefix", "!")

# This would be a dictionary filled up at connect with guild configurations, 
# stored in whichever format is decided by the bot dev. Assume its been 
# set up to be available in the Bot client class below, which enables it to be
# accessible through the predicate function above.
options = {}

# In order to set up the bot, a subclass of client
# is needed.
class MyBot(commands.Bot):
	def __init__(self, prefix, **o):
		super().__init__(command_prefix=prefix, **o)
		# Set up variables like self.db or self.utils which can be instantiated later by a setup_hook.

	async def setup_hook(self):
		# Do a bunch of stuff here to instantiate database connections or similar.
		# The setup_hook is basically an entry point to do whatever you need to do to set up your subclassed Bot class.

# Create an instance of the subclassed client
client = MyBot(command_prefix=get_prefix, intents=intents)
client.config = config
client.environment = ENVIRONMENT

Why do you think this feature would be beneficial?

As mentioned above, allowing the bot to parse prefixes on a per-guild basis would allow communities to have more control over the bots they're using in a way that prevents collisions. It also removes a pain point for bot devs where they would have to tell people "my bot prefix is ! and cannot be changed: if you have other bots that use the same prefix, ensure they don't have similar commands or you may get unintended behaviour".

No Duplicates

  • I believe this is not a duplicate request.

Attachments

No response

Metadata

Metadata

Labels

enhancementNew feature or request

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions