简体   繁体   中英

Can an event execute a command? If so, how can I make my one do so?

So I am trying to have an event where, once the user types a specific word (not a command, literally a word/string), the event will trigger an existing command. Yeah you may wonder "Why not have the user type the command itself?" well, the reason why this isn't the case it's kinda hard to explain. Check this out:

My event will work only if the person types "nothing" (literally the word nothing). Eventually, the person won't expect the bot to actually take this as a command, and so he/she won't type it as command (with the prefix and all that) This is my code:

@client.command()
async def menu(ctx)
#here, well, goes what I want the command to do but it's not the issue

@client.event
async def on_message(message):
    if message.content.startswith("nothing"):
        #here idk how to execute the command up there. That's my question

I hope I am being clear with my issue. Don't worry about what the command exectues, or why the message for the event is "nothing". I just really want to know how to make this work.

Some friends suggested me to invoke the command, but I didn't really know how to do that, and everytime I would try it wouldn't work. Others suggested to call the function, but I also tried that and it wouldn't work. I don't know if I typed it correctly or if it simply won't work. I hope someone helps me out here. Thanks in advance.

If your client is a Bot instance you can use Bot.get_context() to create your own context and invoke the command from there:

import discord
from discord.ext import commands

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

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

@bot.event
async def on_message(message):
    if message.content.startswith('foo'):
        ctx = await bot.get_context(message, cls=commands.Context)
        ctx.command = bot.get_command('menu')
        await bot.invoke(ctx)

    await bot.process_commands(message)

get_context , this takes a message object. Then invoke . Keep in mind, there are 3 downsides to using this method.

  1. The converters (the type hints) won't be triggered. You need to pass the correct types into the arguments.
  2. Checks will be bypassed. You could invoke an owner only command with a non-owner and it would still work. If you still want to run all the checks, see can_run , which will run all the checks and raise an error if any checks fail.
  3. If ctx.invoke was invoked outside of a command (eg eval), the error handler won't fire.
@client.command()
async def menu(ctx):
    await ctx.send("Hello")


@client.event
async def on_message(message):
    if message.content.startswith("nothing"):
        ctx = await client.get_context(message)
        await ctx.invoke(menu)
    await client.process_commands(message)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM