如何获得具有特定权限的所有角色

时间:2020-06-16 13:46:14

标签: discord.py-rewrite

我正在创建一个票务系统,我希望它能在多台服务器上工作,但是我不知道如何获得具有一定许可的服务器上的所有角色。或者,也许是一条额外的命令,供人们添加可以查看频道的角色。但是我不知道怎么办? 这就是我的atm:

@bot.command(name='ticket', aliases=['Ticket'])
async def ticket(ctx):
    ticketnum = random.randint(1000,9999)
    guild = ctx.message.guild
    channel = await guild.create_text_channel(name=f'Ticket-{ticketnum}')
    channel.set_permissions(guild.default_role, read_messages=False)
    await ctx.send(f'Created ticket: {channel}')

1 个答案:

答案 0 :(得分:0)

有一个commands.has_permissions()装饰器,或commands.has_guild_permissions(),可以在命令上使用:

@commands.has_permissions(administrator=True) # Just an example - use the permission you want
@bot.command(...)
async def ticket(ctx):
    # Rest of your code here

这将检查用户是否具有对他们可用的权限。


以下代码是等效的示例(不是唯一的方法)。

在这里,您将获得具有特定权限的所有角色:

roles = [r for r in ctx.guild.roles if any(p[1] and p[0] == "administrator" for p in r.permissions)]

# p[1] is checking that the second element of the tuple is True
# As the permissions are returned in the format:
# ("permission_name", boolean)
# Where True is saying the role has the permission enabled
# and False is saying that the role doesn't have the permission

您可以使用此列表检查作者是否具有以下任何角色:

@bot.command(...)
async def ticket(ctx):
    roles = [r for r in ctx.guild.roles if any(p[1] and p[0] == "administrator" for p in r.permissions)]
    if any(r in ctx.author.roles for r in roles):
        # Let the code run
    else:
        # Send an error message

编辑:

方法1::要设置多个角色的权限,您可以遍历已创建的角色列表中的每个角色:

@bot.command(...)
async def ticket(ctx):
    # Some code
    roles = [...]
    for role in roles:
        await channel.set_permissions(role, permission_name=True) # Or false

这可能会导致您的漫游器受到速率限制,因此我建议asyncio.sleep()在每次权限更新之间进行一些调整。

方法2:create_text_channel()时,您可以为所有目标角色添加一堆覆盖,有关添加覆盖的示例,请参见here

方法3:但是,我建议一个更简单的解决方案-拥有一个预先存在的目标频道,并具有您希望新频道拥有的权限。
这将使您可以简单地clone()说的频道:

@bot.command()
async def ticket(ctx):
    # Some code
    target_channel = bot.get_channel(112233445566778899)
    new_channel = await target_channel.clone(name="...")

然后您可以edit() new_channel的位置,如果需要的话。


参考: