javascript - Discord webhook 速率限制

标签 javascript discord discord.js webhooks rate-limiting

我正在开发一个私有(private)浏览器扩展程序,它从网页中提取一些信息并通过 webhook 将其发布到 Discord channel 。

浏览器扩展确实评估 x-ratelimit-...响应 header 以遵守速率限制限制。

在进行“垃圾邮件测试”时,似乎正确遵守了速率限制限制,并且到目前为止一切正常。但是,即使 ratelimit-remaining 在发送一堆消息 (15+) 后,我仍然会时不时地受到速率限制。是 > 0 .

为了解决这个问题,我已经停止了 ratelimit-remaining1并在 ratelimit-reset 上增加一秒时间戳。但这似乎没有帮助。

let rateLimitRemaining = 5;
let rateLimitReset = 0;

function sendContent()
{
    if ( contentQueue.length > 0 )
    {
        console.log( "Messages in content queue: " + contentQueue.length );

        let content = contentQueue[ 0 ];
        let dateTimestamp = getCurrentUTCTimestamp();

        // Don't send if remaining rate limit is <= 1 and current UTC time is less than reset timestamp
        if ( rateLimitRemaining <= 1 && dateTimestamp <= rateLimitReset )
            return;

        contentQueue.shift();

        let url = "...";
        sendMessage( content, url );
    }
}

function sendMessage( content, url )
{
    let payload = JSON.stringify( { "content": content } );
    $.ajax(
    {
        contentType: 'application/json',
        method: "POST",
        url: url,
        data: payload,
        dataType: 'json'
    } ).done( function( response, status, jqXHR )
    {
        rateLimitRemaining = parseInt( jqXHR.getResponseHeader( 'x-ratelimit-remaining' ) );
        // Add an additional second to the reset timestamp
        rateLimitReset = parseInt( jqXHR.getResponseHeader( 'x-ratelimit-reset' ) ) + 1;

        let timeToResetRemaining = rateLimitReset - getCurrentUTCTimestamp();
        console.log( '[' + getCurrentDateTime() + '] Content sent to webhook. Remaining until rate limit: ' + rateLimitRemaining + ' / Reset @ ' + rateLimitReset + ' (' + getCurrentUTCTimestamp() + ') (' + timeToResetRemaining + ')' );
    } ).fail( function( jqXHR, status, error )
    {
        let response = jqXHR.responseJSON;

        // If we got rate limited, respect the retry_after delay
        if ( response.hasOwnProperty( 'message' ) && response.message.indexOf( 'rate limited' ) !== 0 )
        {
            rateLimitRemaining = 0;
            rateLimitReset = getCurrentUTCTimestamp() + Math.ceil( response.retry_after / 1000 ) + 1;
        }

        console.log( '[' + getCurrentDateTime() + '] Error sending request to webhook.' );
        console.log( response );
    } );
}

Rate limited, even though remaining requests are 3

同样奇怪的是,触发速率限制的同一个请求有它的x-ratelimit-remaining > 0 处的响应 header 。

Rate limit response header > 0

我在这里想念什么?我的错误在哪里?我需要服用x-ratelimit-bucketx-ratelimit-reset-after也考虑?

最佳答案

根据不和谐的开发人员文档, header 中的速率限制不为零似乎很奇怪。不确定您的应用程序中是否是这种情况,但它确实提到“用于控制表情符号的路线不遵循正常的速率限制约定。这些路线在每个公会的基础上受到特别限制,以防止滥用。这意味着我们返回的配额API 可能不准确,您可能会遇到 429。”。
开发人员文档声明您应该依靠 Retry-After header 或 retry-after 字段来确定重试时间,因此最好这样做而不是其他 header 。无论剩余 header 是否可用,API 速率限制的更好模式是将所有查询添加到队列中,成功时将其从队列中删除,失败时状态为 429,为队列设置超时基于 Retry-After header 。这将确保您的请求继续得到处理。您绝对可以在浏览器端的 javascript 中执行此操作,但是我将把它作为练习留给读者,因为它可能不是最好的方法(见下文)。
如果您打算让其他人使用此代码或发布它,那么您将不希望直接从浏览器调用 API,因为它会提供对您的 webhook 凭据的访问权限。相反,让您的浏览器针对服务器进行身份验证,然后隐藏您的 webhook 凭据。然后,如果您要在服务器上使用 node.js,我建议您使用 discord.js SDK,它会自动处理速率限制。

关于javascript - Discord webhook 速率限制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59117210/

相关文章:

javascript - 如何通过在 Firefox 中单击按钮来执行 VBScript 文件?

javascript - 将 $scope 变量值传递给工厂变量/函数

javascript - 内联嵌入字段不起作用

javascript - Discord Bot Node JS 简单错误.send

docker - 停止放大或缩小之前,在StatefulSet中停止所有Pod

javascript - 如何在与 "clearInterval"不同的 if 语句中使用 "setInterval"

javascript - 使用 discord.js 更改用户昵称

javascript - 如何防止滑动的 div 取代其他元素?

javascript - Paper.js/ Canvas : smoothen text's slow movement

javascript - 对提到的用户的 addRole 不起作用