【问题标题】:Command takes 10 minutes to run after 2 successful runs成功运行 2 次后,命令需要 10 分钟才能运行
【发布时间】:2021-12-14 21:46:17
【问题描述】:

我有一个命令允许我编辑文本频道信息,例如名称、主题等。

运行命令时,我每次都会运行相同的命令:.channel > React with E, React with N, type name 我会重复此操作两到三次,通常在第三次尝试时,它会等待 10 分钟,然后才能真正更改名称并编辑嵌入,我问了一个朋友,我们俩都不知道在这种情况下该怎么办。

我也不知道定义 'editstart' 函数以便我可以使用 'back' 是不是最好的做事方式,但这是我遇到困境时首先想到的事情之一。

代码:(我删除了很多,但保留了所有重要的部分)

@commands.command()
@commands.has_permissions(manage_channels=True)
async def channel(self, ctx):
    embed=discord.Embed(colour=author.colour)

    ...

    message=await ctx.send(embed=embed)

    try:
        def check(reaction, user):
            return user == ctx.author and str(reaction.emoji) in emojis
        reaction, user=await self.client.wait_for('reaction_add', timeout=15, check=check)

        if str(reaction.emoji) == '????':
            information=discord.Embed(colour=author.colour)

            ...

            reactions=[...]
            async def addreact():
                for reaction in reactions:
                    await message.add_reaction(f'{reaction}')
            await addreact()

            async def editstart():
                try:
                    def check(reaction, user):
                        return user == ctx.author and str(reaction.emoji) in reactions
                    reaction, user=await self.client.wait_for('reaction_add', timeout=30, check=check)

                    if str(reaction.emoji) == '????':
                        ...

                        try:
                            def check(name):
                                return name.author == ctx.author and name.channel == ctx.channel
                            name=await self.client.wait_for('message', timeout=30, check=check)

                            if name.content.lower() == 'back':
                                await name.delete()
                                await message.edit(embed=information)
                                await addreact()
                                await editstart()
                            elif name.content.lower() == 'cancel':
                                embed=discord.Embed(colour=author.colour)

                                ...

                                await name.delete()
                                await message.edit(embed=embed)
                            else:
                                embed=discord.Embed(colour=author.colour)

                                ...

                                await channel.edit(name=f"{name.content}")
                                await name.delete()
                                await message.edit(embed=embed)
                        except asyncio.TimeoutError:
                            await ctx.send(embed=timeouterror, delete_after=3)
                    elif str(reaction.emoji) == ...:
                        ...
                    ...
                except asyncio.TimeoutError:
                    ...
            await editstart()
    except asyncio.TimeoutError:
        ...

【问题讨论】:

  • 更改频道名称的速率限制为每个频道每10分钟2次

标签: python python-3.x discord discord.py


【解决方案1】:

Discord API 除了全局速率限制外,还有许多未记录的每条路由子限制。他们没有记录限制的官方理由是因为“它们可以随时更改。我们不保证速率限制将保持不变”(source)。

目前,频道名称更改请求以及许多其他公会更新(例如频道主题更改、频道 nsfw 切换等)被限制为每 10 分钟两次。

您的代码“停滞”了 10 分钟,因为在后台,Discord API 返回到 discord.py 一个 429 速率限制响应和一个重试时间,然后 discord.py 在内部处理速率限制并等待速率限制然后再次重新运行您的命令。如果您不希望这种行为,建议设置命令冷却时间和/或通过asyncio.wait_for() 添加强制请求超时。

import asyncio

# twice per 600 seconds (10 minutes), per channel
@commands.cooldown(2, 600, commands.BucketType.channel)
@bot.command()
async def changename(ctx, channel: discord.TextChannel, *, name):
    try:
        # waits at most 5 seconds, raise exception if takes longer than that
        await asyncio.wait_for(channel.edit(name=name), 5)
    except asyncio.TimeoutError:
        await ctx.send("Failed to change name! Try again later.")
    else:
        await ctx.send("Name was changed!")


@bot.event
async def on_command_error(ctx, error):
    if isinstance(error, commands.CommandOnCooldown):
        await ctx.send(f"This command is on cooldown! Try again in {error.retry_after:.1f} second(s).")

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多