Как я могу получить все роли с определенным разрешением - PullRequest
1 голос
/ 16 июня 2020

Я создавал систему заявок и хотел, чтобы она работала на нескольких серверах, но я не могу понять, как получить все роли на сервере с определенным разрешением. Или, может быть, дополнительная команда для людей, чтобы добавить роли, которые могут видеть каналы. Но я не знаю как? Вот что у меня есть в банкомате:

@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 голосов
/ 16 июня 2020

Есть декоратор 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

И это проверяет, что пользователь имеет доступное для них разрешение.


Следующий код является эквивалентным примером (не единственным способом сделать это).

Вот как вы получите все роли с определенным разрешением c:

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(), вы можете добавить кучу перезаписей для все целевые роли, см. здесь для примера добавления перезаписи.

Метод 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 и тому подобное, если хотите.


Ссылки:

...