如何使用 discord.py 让 discord 机器人根据自己的消息触发命令?

How do I get the discord bot to trigger commands on it's own message using discord.py?

假设用户输入了无效的命令,机器人建议使用 (y/n) 的命令?如果是,则机器人应触发建议的命令。 我觉得这可以通过两种方式实现:

  1. 如果机器人可以根据自己的消息触发命令
  2. 如果我可以从其他 cogs 调用命令

我似乎无法让他们工作。

这里有一个例子可以帮助你们更好地帮助我:

假设下面的代码来自一个名为 Joke.py:

的齿轮
@commands.command()
async def joke(self,ctx):
await ctx.send("A Joke")

然后还有另一个 cog“CommandsCorrection.py”,用于纠正保存在 data.json 文件中的用户使用的错误命令:

@commands.Cog.listener()
async def on_message(self, message):
    channel = message.channel
    prefix = get_prefix(self,message)
    if message.author.id == bot.id:
        return
    elif message.content.startswith(prefix):
            withoutprefix = message.content.replace(prefix,"")
            if withoutprefix in data:
                return
            else:
                try:
                    rightCommand= get_close_matches(withoutprefix, data.keys())[0]
                    await message.channel.send(f"Did you mean {prefix}%s instead? Enter Y if yes, or N if no:" %rightCommand)
                    def check(m):
                        return m.content == "Y" or "N" and m.channel == channel
                    msg = await self.client.wait_for('message', check=check, timeout = 10.0)
                    msg.content = msg.content.lower()
                    if msg.content == "y":
                        await channel.send(f'{prefix}{rightCommand}')
                    elif msg.content == "n":
                        await channel.send('You said no.')
                except asyncio.TimeoutError:
                    await channel.send('Timed Out')
                except IndexError as error:
                    await channel.send("Command Not Found. Try !help for the list of commands and use '!' as prefix.")

在上面的代码中,await message.channel.send(f"Did you mean {prefix}%s instead? Enter Y if yes, or N if no:" %rightCommand) 建议正确的命令,await channel.send(f'{prefix}{rightCommand}') 发送正确的命令。

所以,例如:

user : !jok
bot  : Did you mean !joke instead? Enter Y if yes, or N if no:
user : y
bot  : !joke **I want to trigger the command when it sends this message by reading its own message or my just calling that command/function

我该怎么办?

一种解决方案是将命令逻辑与命令回调分开,并将其放入自己的协程中。然后你可以从任何命令回调中自由调用这些协程。

所以你会像这样转换代码:

@bot.command()
async def my_command(ctx):
    await ctx.send("Running command")

@bot.command()
async def other_command(ctx, arg):
    if arg == "command":
        await ctx.send("Running command")

变成这样:

async def command_logic(ctx):
    await ctx.send("Running command")

@bot.command()
async def my_command(ctx):
    await command_logic(ctx)

@bot.command()
async def other_command(ctx, arg):
    if arg == "command":
        await command_logic(ctx)

@Patrick Haugh 提出了这个想法,他正在做某事但并没有真正起作用,但我有办法让它起作用。 如果您对齿轮使用以下方法,您也将能够读取机器人命令:

import discord
from discord.ext import commands

async def command_logic(self, ctx):
    await ctx.send("Running command")

class Example(commands.Cog):

    def __init__(self, client):
        self.client = client


    @commands.command()
    async def my_command(self, ctx):
        await command_logic(self,ctx)

    @commands.Cog.listener()
    async def on_message(self, message):
        if message.content == '!command':
            ctx = await self.client.get_context(message)
            await command_logic(self,ctx)

def setup(client):
    client.add_cog(Example(client))