【问题标题】:Discord.py — Check if the user has specific roles?Discord.py — 检查用户是否具有特定角色?
【发布时间】:2021-10-10 11:18:15
【问题描述】:

我正在尝试创建一个可以禁止服务器上的人和不在服务器上的人的命令。但是有一个问题:如果我使用async def ban(ctx, member: discord.Member, *, reason):来使用“roles”属性,那么它就无法禁止那些不在服务器上的人。如果我使用async def ban(ctx, member: discord.User, *, reason):,我将无法使用“角色”属性,因为它不是属性。

我为什么要这样做?我正在努力使服务器版主无法禁止具有版主角色的人

代码:

async def ban(ctx, member: discord.User = None, *, reason=None):
    if get(ctx.author.roles, id=866038959980544050) or get(ctx.author.roles, id=866436325503008768) or get(
            ctx.author.roles, id=866441730631008316) or ctx.author.guild_permissions.administrator:  # Check if the author has the Role "Moderator", "Admin", etc.

        if get(member.roles, id=867371024466968596) or get(member.roles, id=867132420489871411) and not ctx.author.guild_permissions.administrator:  # Check if the member has the Role "Moderator", "Admin", etc.
            await ctx.send("You cannot ban this user.")

【问题讨论】:

    标签: python discord discord.py


    【解决方案1】:

    这样做的一种方法是检查给定的member 是否在当前公会中。如果这是True,您可以使用他们的 id 或其他首选方法创建一个新的member object,否则您可以假设他们没有主持人角色。为简单起见,我只检查了单个角色,但您可以按照自己的方式进行调整。除此之外,其他所有内容都在下面的代码中进行了更详细的解释。

    if member in ctx.guild.members: # checks if the provided member is in the current server
        member = ctx.guild.get_member(member.id) # Get the member object of the user
        if get(member.roles, id=866038959980544050): # Check if this role is in the member's roles
            await ctx.send("This member has <@&866038959980544050>")
        else:
            await ctx.send("This member does not have <@&866038959980544050>")
        return # returns, since member was in the server
    # This happens if the provided member is not in the current server
    await ctx.send("This member, who is not in this server, does not have <@&866038959980544050>")
    

    【讨论】:

      【解决方案2】:

      假设您使用discord.ext.commands,您可以使用typing.Union 转换器来确保参数是用户或成员。

      import typing
      
      [...]
      
      async def ban(ctx, user: typing.Union[discord.Member, discord.User]):
      

      请注意,顺序很重要:通过首先使用discord.Member,它会先尝试应用此converter,然后再尝试discord.User,因此优先考虑转换为成员而不是转换为用户(这应该是您想要的)。

      为了区分这两种情况,您现在可以检查 user 是否属于 discord.Member 类型并对其执行检查。

          if type(user) is discord.Member:
              if YOUR_CHECKS:
                  await ctx.send('You cannot ban this user')
                  return
      
          # Perform ban
          await ctx.send('Ban successful')
      

      在测试时,我发现命令库会给你一个数字用户 id 而不是真实用户,并显示 Failed fetching discord object! Passing ID instead. 作为警告。如果您需要的不仅仅是用户 ID,您可以使用

      将其转换为 User 对象
          if type(user) is int:
              user = await bot.fetch_user(user)
              if user is None:
                  await ctx.send('User not found')
                  return
      

      请注意,fetch_user 是一个 API 调用,您可能希望避免使用它。请参阅docs 了解更多信息。

      【讨论】:

        【解决方案3】:

        你必须使用这个

        @bot.command(...)
        @commands.has_any_role(role id)
        ...
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2019-04-04
          • 2010-12-22
          • 2019-06-16
          • 1970-01-01
          • 1970-01-01
          • 2023-03-03
          • 1970-01-01
          相关资源
          最近更新 更多