如何让Discord.py机器人更快地删除角色



我制作了一个机器人程序,可以自动添加和删除角色。这一切都有效,但添加操作在运行命令后的15/20秒内即可完成。移除最多需要15分钟。

我做错了什么?我几个月前就开始编程了,从Python开始,所以任何提示都是有用的。

公会ID、通道ID和角色ID现在都是数字,我在里面放了占位符。


@tasks.loop(seconds=10)
async def autoderolergame():
tasks = []
guild = client.get_guild(guildid)
channel = guild.get_channel(channelid)
role = guild.get_role(roleid)
for member in guild.members:
if member not in channel.members:
try:
await member.remove_roles(role, reason='Leaving Voice channel')
except:
pass
if str(member.status) == 'offline':
try:
await member.remove_roles(role, reason='Going offline, so no more VIP rain')
except:
pass

我也试着将"为公会成员'公会中成员的异步。fetch_members((:'遗憾的是,这并没有什么不同。

我正在考虑在频道中保存一个用户列表,每10秒更新一次,然后查看列表,选择所有不再在频道中的用户,删除角色,然后将他们从列表中删除,这是更好的解决方案吗?我宁愿不这样做,因为我想使用Discord.py.的内置功能

谢谢你的帮助!

您可以使用异步方法使更快

import asyncio
remove_roles_semaphore = asyncio.Semaphore(20)
async def remove_role(member, role, reason):
async with remove_roles_semaphore:
try:
await member.remove_roles(role, reason=reason)
except:
pass

@tasks.loop(seconds=10)
async def autoderolergame():
guild = client.get_guild(guildid)
channel = guild.get_channel(channelid)
role = guild.get_role(roleid)
tasks = []
for member in guild.members:
if member not in channel.members:
tasks.append(remove_role(member, role, 'Leaving Voice channel')
if str(member.status) == 'offline':
tasks.append(remove_role(member, role, 'Going offline, so no more VIP rain')
await asyncio.gather(*tasks)

尽管要记住,你可以很容易地受到费率限制,但如果你达到全球费率限制(每秒50个请求(,你可能会被禁止。使用此方法的风险自负(您可能希望启用logging以查看任何费率限制警告(

我使用asyncio.Semaphore来限制并发请求的数量,可以随意更改值,但请记住,值越高,被禁止的几率就越高(不要超过50(。

遗憾的是,我不能真正测试代码,所以我不能保证它会更快

我找到了解决问题的方法。我用代码查看了所有的公会成员。

由于我希望在离开频道时删除角色,所以我只需要查看用户的角色,然后检查他们是否仍在房间中。

这是我的新代码:

@tasks.loop(seconds=10)
async def autoderolergame():
tasks = []
guild = client.get_guild(guildid)
channel = guild.get_channel(channelid)
role = guild.get_role(roleid)
for member in role.members: (<-- only changed this from guild to role)
if member not in channel.members:
try:
await member.remove_roles(role, reason='Leaving Voice channel')
except:
pass
if str(member.status) == 'offline':
try:
await member.remove_roles(role, reason='Going offline, so no more VIP rain')
except:
pass

由于ukasz Kwieciński给我的关于速率限制的提示,我也把秒改为更长的间隔。现在这不是问题,因为它的工作速度快了1000倍。

最新更新