我正在尝试在成员加入/退出服务器时更新频道名称。 我有一个统计频道,显示会员人数。
我想我会创建一个函数,它从 ID 中获取频道,然后计算服务器成员的数量,最后使用正确的成员数量更改频道名称。
base.py
这是我在 base.py 文件中的函数 同样在这个文件中,我处理事件 on_member_join / on_member_remove。所以我想知道如何在用户进入或离开时调用 refresh() 函数。
class base(commands.Cog):
def __init__(self, client):
self.client = client
@client.command()
async def refresh(self, ctx):
stats_channel = client.get_channel(1234567890)
membri = len(ctx.guild.members)
await stats_channel.edit(name='? Users: {}'.format(membri))
一旦我定义了刷新函数,我就会尝试在用户进入时调用它
@commands.Cog.listener()
async def on_member_join(self, member):
await self.refresh()
print("Other stuff")
但是一旦有会员进入服务器,出现这个错误:
Ignoring exception in on_member_join
Traceback (most recent call last):
File "C:\Users\Matteo\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0\LocalCache\local-packages\Python38\site-packages\discord\client.py", line 343, in _run_event
await coro(*args, **kwargs)
File "C:\Users\Matteo\Desktop\Bot\comandi\base.py", line 33, in on_member_join
await self.refresh()
File "C:\Users\Matteo\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0\LocalCache\local-packages\Python38\site-packages\discord\ext\commands\core.py", line 372, in __call__
return await self.callback(self.cog, *args, **kwargs)
TypeError: refresh() missing 1 required positional argument: 'ctx'
我尝试了几种方法来尝试修复它,但没有成功。
答案 0 :(得分:0)
首先,您可以通过多种方式做到这一点。为什么刷新客户端命令?您是否希望用户手动调用它?如果是,请为 ctx 设置默认值。
@client.command()
async def refresh(self, ctx = None):
#other stuff
if ctx is not None:
await ctx.send('refreshed member count')
或者如果您不需要它作为命令
async def refresh(self): #no client.command() decorator
#do stuff here
答案 1 :(得分:-1)
不要
不要在成员每次加入服务器时更新频道名称。为什么?
Discord 对您可以更改频道名称的时间有很高的速率限制,即每 10 分钟 2 次。高于 2 倍将使您受到速率限制。这是为了彻底清除像您这样的计数器机器人。
做
如果你还想这样做,与其每次on_member_join事件触发都更新,你可以检查服务器上的成员数量并每隔一段时间更改频道名称,最好每30分钟或一小时一次。
您可以使用 tasks.loop
装饰器每隔一段时间触发一个函数。这是图书馆提供的。 Here
这里有一个你应该做的解决方案,而不是使用 on_member_join 事件。
# Define a variable to store the old amount.
old_amount = 0
@tasks.loop(minutes=30)
async def member_checker():
# Get the guild object
guild = bot.get_guild(YOUR_GUILD_ID)
# Check if it's not the same, if it is, update the channel.
if old_amount != guild.member_count:
# Update the old amount, and update your channel.
old_amount = guild.member_count
your_channel = guild.get_channel(YOUR_CHANNEL_ID)
await your_channel.edit(name=guild.member_count)
# This function is triggered before the loop occur
@member_checker.before_loop
async def before_looping_occur():
# You would also need this to not let the loop run before
# on ready occur, this is to avoid bot.get_guild returns None
await bot.wait_until_ready()
# Start this task somewhere
member_checker.start()