首页 > 解决方案 > discord.py REWRITE 中的 bot 命令,如何根据角色包含和角色不包含进行条件分支?

问题描述

我想在“ ready”命令中添加一些 if 语句,例如:“如果用户具有任何角色 A、B、C”然后做一些事情。否则,如果用户具有任何角色 D、E、F,则执行其他操作。我想如果有人可以帮助我解决下面的堆栈跟踪错误,那么它可能会解决代码下面的问题

import logging
import time
import discord
import asyncio
import time
from discord.ext import commands
from discord.ext.commands import MissingRequiredArgument

prefix = "!"
bot = commands.Bot(command_prefix=prefix, case_insensitive=True)

token = open("token.txt", "r").read()

class MemberRoles(commands.MemberConverter):
        async def convert(self, ctx, argument):
            member = await super().convert(ctx, argument)
            return [role.name for role in member.roles[1:]] # Remove everyone role!

@bot.command()
#i prefer not using @commands.has_any_role decorator because i want my 1 "ready" command to branch based on the role(s) the user has
#I am trying to make my bot command able to do multiple role checks
#I am trying to adapt this example "async def roles(ctx, *, member: MemberRoles):" from https://discordpy.readthedocs.io/en/rewrite/ext/commands/commands.html


async def ready(ctx, *, message: str, member: MemberRoles):
    '''
    !ready must include text after the command and can only be used if you are assigned ANY of these roles: Admin, Newbie
    '''

    if message is None:
        return
    else:
        try:
          #stuff
        except Exception as e:
            print(str(e))

#This part, about detecting which roles a member has does not work, see the question below the code for more information
    await ctx.send('I see the following roles: ' + ', '.join(member))


@bot.event
async def on_command_error(ctx, error):
    if isinstance(error, commands.MissingRequiredArgument):
        await ctx.channel.send("Cannot ready without a message.  Type !ready <your message> and try again.")
    else:
        raise error

bot.run(token)

我想如果有人可以帮助我解决这个堆栈跟踪错误,那么我可以解决下面的“问题”。堆栈跟踪错误在“ raise error”点抱怨。我看到的错误是“discord.ext.commands.errors.CommandInvokeError:命令引发异常:TypeError:ready()缺少1个必需的关键字参数:'member'”

问题:假设“MemberRoles”类是执行此操作的好方法,如何在“就绪”命令中使用它来实现我需要的 A、B、C 和 D、E、F IF Else 分支?

谢谢您的帮助!

标签: pythonpython-3.xdiscord.pydiscord.py-rewrite

解决方案


一个命令中只能有一个关键字参数,因为使用关键字参数来收集消息的结尾。您实际上只需要作者角色,因此您根本不需要使用转换器:

@bot.command
async def ready(ctx, *, message: str):
    author_roles = ctx.author.roles
    ...

至于检查角色,你可以做类似的事情

roles_one = {"A", "B", "B"}
roles_two = {"D", "E", "F"}
if any(role.name in roles_one for role in author_roles):
    ...
elif not any(role.name in roles_two for role in author_roles):
    ...

推荐阅读