机器人在事件上没有移除角色。

huangapple go评论61阅读模式
英文:

Bot is not removing role on event

问题

问题:

> 我正在使用 py-cord 创建一个事件,用于检测用户是否已添加角色。如果用户具有管理员权限,机器人将允许他,并且如果用户只具有 manage_roles 权限,机器人将从获得角色的人那里删除角色。举个例子,如果我只具有 manage roles 权限,我想为我的朋友添加一个角色,那么机器人将从我的朋友那里删除角色。如果我具有管理员权限,机器人将允许我。

我的代码:

@bot.event
async def on_member_update(before, after):
    if len(after.roles) > len(before.roles):
        # 成员添加了一个角色
        added_roles = [role for role in after.roles if role not in before.roles]
        for role in added_roles:
            if role.id == 1093503503680405614:
                # 检查角色ID是否与指定的角色ID匹配
                updater = after.guild.get_member(after.guild.me.id)
                if updater.guild_permissions.administrator:
                    print("他拥有管理员权限")
                elif updater.guild_permissions.manage_roles:
                    print("他没有管理员权限")
                    await after.remove_roles(role)

结果:

> 如果我没有管理员权限,机器人将允许具有该角色的用户,并打印("他拥有管理员权限")。

跟踪:

> 除了打印("他拥有管理员权限")之外,我定义的打印函数没有跟踪。

英文:

The problem:

> I'm making an event in py-cord that detects if the user has added a role. If he has administrator permission the bot would let him, and if he only has manage_roles permission the bot would remove the role from the person who got the role. As an example let's say I have only manage roles permission and I want to add to my friend a role, the bot would remove the role from my friend. And If I have administrator permission, the bot would let me

My code:

@bot.event
async def on_member_update(before, after):
    if len(after.roles) > len(before.roles):
        # A role was added to the member
        added_roles = [role for role in after.roles if role not in before.roles]
        for role in added_roles:
            if role.id == 1093503503680405614:
                # Check if the role ID matches the specified role ID
                updater = after.guild.get_member(after.guild.me.id)
                if updater.guild_permissions.administrator:
                    print("he has admin")
                elif updater.guild_permissions.manage_roles:
                    print("he has NOT admin")
                    await after.remove_roles(role)

Results:

> if I haven't administrator permission the bot would let the user with the role and print("he has admin")

Traceback:

> except printing "he has admin" the print function that I did define, there is no traceback.

答案1

得分: 1

### 问题 1
> `updater = after.guild.get_member(after.guild.me.id)`

[guild.me](https://discordpy.readthedocs.io/en/stable/api.html#discord.Guild.me) 将返回与您的机器人用户在该服务器上相关联的成员。因此,您将`updater`设定为始终是您的机器人。由于您的机器人可能在服务器上具有管理员权限,条件将始终为真。如何正确获取更新角色的用户?

### 问题 2
[on_member_update](https://discordpy.readthedocs.io/en/stable/api.html#discord.on_member_update) 事件只提供了 `before``after` 参数,它们是更新前后的 `Member` 对象。在这些对象中找不到执行操作的人。唯一找出是谁更新了成员的方法是查看审计日志。

### 解决方案
您需要通过审计日志来查找谁更新了成员的角色。例如,此函数返回最新更新提供的成员角色的管理员:
```py
async def get_role_updater(member):
   """找出谁更新了这个成员的角色"""
   guild = member.guild
   action = discord.AuditLogAction.member_role_update
   async for entry in guild.audit_logs(action=action, limit=5):
      if entry.target == member:
         return entry.user

我没有测试过这段代码,但假设它按预期工作,您可以简单地在您的代码中使用这个函数:

@bot.event
async def on_member_update(before, after):
    if len(after.roles) > len(before.roles):
        # 向成员添加了一个角色
        added_roles = [role for role in after.roles if role not in before.roles]
        for role in added_roles:
            if role.id == 1093503503680405614:
                # 检查角色ID是否匹配指定的角色ID
                updater = await get_role_updater(after)
                if updater.guild_permissions.administrator:
                    print("他拥有管理员权限")
                elif updater.guild_permissions.manage_roles:
                    print("他没有管理员权限")
                    await after.remove_roles(role)

<details>
<summary>英文:</summary>

### Ploblem 1
&gt; `updater = after.guild.get_member(after.guild.me.id)`

[guild.me](https://discordpy.readthedocs.io/en/stable/api.html#discord.Guild.me) will return the member related to your bot&#39;s user on that server. So you are setting `updater` to always be your bot. Since your bot probably has admin permission on the server, the conditional will always be true. How to get the user who updated the roles correctly?

### Problem 2
The [on_member_update](https://discordpy.readthedocs.io/en/stable/api.html#discord.on_member_update) event only provides the `before` and `after` arguments, which are the `Member` object before and after the update. There is no way to find out who performed the action looking at these objects. The only way to find out who updated the member is to look at the audit log.

### Solution
You will need to go through the audit log to find out who updated the member&#39;s roles. For example, this function returns the latest moderator who updated the provided member&#39;s roles:
```py
async def get_role_updater(member):
   &quot;&quot;&quot;find out who updated this member&#39;s roles&quot;&quot;&quot;
   guild = member.guild
   action = discord.AuditLogAction.member_role_update
   async for entry in guild.audit_logs(action=action, limit=5):
      if entry.target == member:
         return entry.user

I haven't tested this code, but assuming it's working as expected, you can simply use this function in your code:

@bot.event
async def on_member_update(before, after):
    if len(after.roles) &gt; len(before.roles):
        # A role was added to the member
        added_roles = [role for role in after.roles if role not in before.roles]
        for role in added_roles:
            if role.id == 1093503503680405614:
                # Check if the role ID matches the specified role ID
                updater = await get_role_updater(after)
                if updater.guild_permissions.administrator:
                    print(&quot;he has admin&quot;)
                elif updater.guild_permissions.manage_roles:
                    print(&quot;he has NOT admin&quot;)
                    await after.remove_roles(role)

答案2

得分: 0

在 "added_roles" 中,我认为你正在添加角色对象。也许尝试将 [ ] 中的文本替换为 role.id for role in after.roles if role not in before.roles

英文:

I think the problem is in this part:

added_roles = [role for role in after.roles if role not in before.roles]
        for role in added_roles:
            if role.id == 1093503503680405614:
                # Check if the role ID matches the specified role ID

In "added_roles", you are adding the role object I think. Maybe try replacing the text in the [ ] with role.id for role in after.roles if role not in before.roles

huangapple
  • 本文由 发表于 2023年4月6日 20:24:30
  • 转载请务必保留本文链接:https://go.coder-hub.com/75949474.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定