Discord API 的速率限制和斜线命令 (discord.py)

问题描述 投票:0回答:1

我最近遇到了一个问题——特别是斜杠命令。两者都同步它们并实际使用它们。

因此,据我了解,每当您向 Discord API 发出请求时,您都会面临速率限制的风险(例如同步命令树),您的终端会吐出类似“警告:您正在使用”的内容。受到速率限制,请在 xxx 重试。我偶尔会弹出此消息,但最近我的代码一直“挂起”,并且我无法捕获任何错误或异常,因为发生这种情况时不会产生任何输出。

这里是相关代码,第一部分是命令同步,尽管我怀疑它遇到了速率限制,但实际上并没有向终端输出任何内容。 - 从输出中可以看出,它会输出日志记录,但随后会挂起几分钟,即使我只同步 3 个命令。同样,有时它会这样做,有时它几乎是瞬时的。

第二部分是我在使用普通斜杠命令(我已确认已同步)时遇到的错误,在 Discord 中出现模糊错误,而终端中没有任何内容。

代码(同步斜杠命令):

    @discord.app_commands.command()
    async def reload(self, interaction: discord.Interaction, extension: str = None):
        await interaction.response.defer()
        print('reload command used')
        self.logger.info(f"Reload command triggered with extension: {extension}")

        if not os.path.isdir(self.ext_dir):
            self.logger.error(f"Extension directory {self.ext_dir} does not exist.")
            return

        if extension is not None and extension != 'cogmgr':
            try:
                await self.bot.unload_extension(f'{self.ext_dir}.{extension}')
                self.logger.info(f'Unloaded extension {extension}')
                await self.bot.load_extension(f'{self.ext_dir}.{extension}')
                self.logger.info(f'Loaded extension {extension}')
            except commands.ExtensionError:
                self.logger.error(f'Failed to load extension {extension}\n{traceback.format_exc()}')
        else:
            for filename in os.listdir(self.ext_dir):
                if filename.endswith('.py') and not filename.startswith('_') and not filename == 'cogmgr':
                    try:
                        await self.bot.unload_extension(f'{self.ext_dir}.{filename[:-3]}')
                        self.logger.info(f'Unloaded extension {filename[:-3]}')
                        await self.bot.load_extension(f'{self.ext_dir}.{filename[:-3]}')
                        self.logger.info(f'Loaded extension {filename[:-3]}')
                    except commands.ExtensionError:
                        self.logger.error(f'Failed to load extension {filename[:-3]}\n{traceback.format_exc()}')
        await interaction.followup.send(f'Reloaded {extension if extension is not None else 'all extensions'}')


Output (this example shows a minute or two of delay, but it can, and has taken up to five before):

[2024-12-12 09:22:17,192] INFO: Syncing commands with Discord...
[2024-12-12 09:22:19,590] INFO: Syncing commands with Discord...
[2024-12-12 09:22:23,551] INFO: Syncing commands with Discord...
[2024-12-12 09:23:15,350] INFO: Successfully synced commands.
[2024-12-12 09:23:15,873] INFO: Successfully synced commands.


代码(普通斜杠命令):

    @discord.app_commands.command()
    async def container(self, interaction:discord.Integration, container:str):
        await interaction.response.defer()
        print(container)

        content = self.container_request(container)
        print(content)

        if content is None:
            if self.result_un.status_code == 200:

                #call successful, container not found
                self.logger.info(f'Status code: {self.result_un.status_code} container-visit call successfully sent, however container was not found in the Port Connect database\ncheck for typos')
                #await interaction.followup.send(f'Call Error: The container was not found in the Port Connect database, but the call was successful\nStatus code: {self.result_un.status_code}')
            else:

                self.logger.error(f'Status code: {self.result_un.status_code} container-visit call was not successful')
                #await interaction.followup.send(f'Call Error: The call was unsuccessful\nStatus code: {self.result_un.status_code}')

            return

        self.logger.info(f'Status code: {self.result_un.status_code} container-visit call successfully sent, data returned')

        embed = discord.Embed(title=content['container'])
        embed.set_author(name='Port Bot')

        keys = list (content.keys())

        for i in range(len(keys)):

            key = keys[i]
            value = content[key]

            embed.add_field(name=key, value=value, inline=False)
       
        await interaction.followup.send(embed=embed)


async def setup(bot):
    logging.basicConfig(level=logging.INFO, format="[%(asctime)s] %(levelname)s: %(message)s")
    await bot.add_cog(Containerhandler(bot))


output (from discord):

portbot APP — Yesterday at 16:16
Unknown Integration
Only you can see this • Dismiss message

最终,我的问题是,速率限制是否适用于同步和使用命令的使用,以及如何实际捕获它 - 我在那里的 HTTP 异常似乎没有捕获任何内容。此外,在 Discord 中,“未知的集成”是什么意思?

我知道代码不符合 pep8,我正在三个显示器上工作,并且有足够的空间来排长队。请不要恨我

http exception discord discord.py
1个回答
0
投票

没有人会因为代码格式不正确而“恨你”(除非是雇主或其他人)。您可以在此处阅读有关速率限制的内容。

为了回答您的问题,速率限制适用于所有请求,大多数端点的限制约为每秒 50 个请求。对于无效请求也有单独的限制。

要真正捕获错误,您可以使用 HTTP 处理,因为速率限制会返回

HTTP 429
响应。查看您的代码,您的同步似乎本身就是一个命令。像这样的东西应该足够了:

@bot.event #Should be self explanatory
async def on_command_error(ctx, error): #Should be self explanatory
    if isinstance(error, discord.HTTPException): #See if the error is from discord's HTTP exceptions
        if error.status == 429: #Check error code for rate limiting
            print("Rate limited!") # Do whatever you want

除了您的

Unknown Integration
问题之外,似乎this可能是原因(阅读最后3条评论)。我的猜测(但只是我的猜测)是,当您“同步”命令时,您对命令做了一些操作,导致它们获得新的 id。

尽管官方 Discord API 采用不同的编程语言,但 Discord.py 是其 API 包装器,因此肯定会遇到许多相同的问题。但是,这将是一个不同的问题,您需要进行更多研究并深入研究代码以找出此问题发生的位置。

© www.soinside.com 2019 - 2024. All rights reserved.