on_message() 和@bot.command 问题

Posted

技术标签:

【中文标题】on_message() 和@bot.command 问题【英文标题】:on_message() and @bot.command issue 【发布时间】:2018-09-25 00:40:56 【问题描述】:

当我的代码中有on_message() 时,它会停止所有其他@bot.command 命令的工作。我试过await bot.process_commands(message),但这也不起作用。这是我的代码:

@bot.event
@commands.has_role("Owner")
async def on_message(message):
    if message.content.startswith('/lockdown'):
        await bot.process_commands(message)
        embed = discord.Embed(title=":warning: Do you want to activate Lock Down?", description="Type 'confirm' to activate Lock Down mode", color=0xFFFF00)
        embed.add_field(name="\u200b", value="Lock Down mode is still in early development, expect some issues")
        channel = message.channel
        await bot.send_message(message.channel, embed=embed)
        msg = await bot.wait_for_message(author=message.author, content='confirm')
        embed = discord.Embed(title=":white_check_mark: Lock Down mode successfully activated", description="To deactivate type '/lockdownstop'", color=0x00ff00)
        embed.add_field(name="\u200b", value="Lock Down mode is still in early development, expect some issues")
        await bot.send_message(message.channel, embed=embed)

【问题讨论】:

如果您使用的是commands 扩展,为什么要处理on_message 中的命令? 【参考方案1】:

您必须将await bot.process_commands(message) 放在if 语句范围之外,无论消息是否以“/lockdown”开头,都应该运行process_command

@bot.event
async def on_message(message):
    if message.content.startswith('/lockdown'):
       ...
    await bot.process_commands(message)

顺便说一句,@commands.has_role(...) 不能应用于on_message。尽管没有任何错误(因为检查到位),has_role 实际上不会像您预期的那样工作。

@has_role 装饰器的替代方案是:

@bot.event
async def on_message(message):
    if message.channel.is_private or discord.utils.get(message.author.roles, name="Admin") is None:
        return False

    if message.content.startswith('/lockdown'):
       ...
    await bot.process_commands(message)

    

【讨论】:

@commands.has_role 不能与on_message 一起使用是有道理的,因为on_message 事件不是命令。每次向服务器发送消息时都会调用该事件。 还有一件事,看到@commands.has_role("...") 对on_message() 不起作用,你知道我怎么才能让它只扮演角色吗? @SirCinnamon 您可以从message 对象访问message.author.roles。然后你可以做类似for role in message.author.roles: if role.name == 'Owner'discordpy.readthedocs.io/en/latest/api.html#memberdiscordpy.readthedocs.io/en/latest/api.html#discord.Role @SirCinnamon 我可能会遍历角色,将结果保存到变量(类似于owner_role = True),然后如果您已经存在if 条件,则将其作为一部分。如果您需要更多代码示例,请提出新问题或编辑现有问题。 @has_role 装饰器的替代方案将在处理任何命令之前退出函数,除非满足第一个 if 条件

以上是关于on_message() 和@bot.command 问题的主要内容,如果未能解决你的问题,请参考以下文章

ON_COMMAND,ON_MESSAGE和ON_NOTIFY的区别

如何在“on_message”中提及某人

调用 on_message 时,tornado websocket 获取多条消息

Discord.py on_message() 但仅用于私人消息

discord.py 中 on_message 的冷却时间

为啥 on_message 会停止命令工作?