不和谐.py |更新频道名称 on_member_join

时间:2021-03-25 23:26:38

标签: python discord discord.py

我正在尝试在成员加入/退出服务器时更新频道名称。 我有一个统计频道,显示会员人数。

我想我会创建一个函数,它从 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'

我尝试了几种方法来尝试修复它,但没有成功。

2 个答案:

答案 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()