发送大量 webhook 消息时结果不一致

Inconsistent results when sending a large volume of webhook messages

我是 node.js 和 discord.js 的新手,此机器人的先前版本是用 discord.py 编写的(现已弃用)。

此函数遍历我的 SQL 数据库中的所有 Webhook(ID 和令牌),并向每个 Webhook 发送一条消息。大约有 1500 个(每个服务器一个)。我必须大约每 5 秒发送一次消息。这在 python 版本中工作得很好,但只需要 运行 在大约 300 个公会上。我没有它的代码了,但它的工作方式是一样的(所有请求都是一次发送的,可能在 500 毫秒内发送了大约 300 个请求,而且效果很好),所以我认为这不是速率限制问题.

    client.on('messageCreate', (message) => {
        if (message.channelId === '906659272744665139') {
            console.log('found message');
    
                const url = message.content;
                var webhooklist = [];
                
                //get all the webhooks from the database
                db.prepare('SELECT * FROM webhooks').all().forEach(webhook => {
                    const webhookclient = new WebhookClient({id: webhook.webhookID, token: webhook.webhookToken});
                    webhooklist.push(webhookclient);
                })
    
                console.time('sent');
                
                var failed = 0;
                webhooklist.forEach(webhook => {
    
                    var row = new MessageActionRow()
                        .addComponents(
                            savebutton,
                            reportbutton
                        )
                    
                    webhook.send({content: url, components: [row]})
                        .catch(err => {
                            if (err instanceof DiscordAPIError) {
                                if (err.code === 10015) {
                                    //remove the webhook from the database
                                    db.prepare('DELETE FROM webhooks WHERE webhookID = ?').run(webhook.id);
                                    console.log(`Removed webhook ${webhook.id}`);
                            } else {
                                failed += 1;
                                console.log(err);
                            }
                        } else {
                            failed += 1;
                        }
                    });
                });
    
                console.timeEnd('sent');
                console.log(failed);
              
            });
        }
    });

问题: 一个请求被发送到每个 webhook,但是,消息实际上有一半时间没有被发送。例如,我正在查看这个机器人所在的 3 个不同的服务器,其中一个出现了一条消息,而在另外两个中没有出现(这些结果的任何其他组合也会发生,这不是问题服务器已设置)。也没有错误,由 failed 变量指示。需要澄清的是,大约 50% 的消息通过了,但另外 50% 的消息据称是由机器人发送的,但从未出现在频道中。

(很可能)不是问题的事情:

-不和谐率限制 原因:通过 webhook 发送消息不计入 bot 发送的消息,因此不会导致速率限制(全球每秒 50 条消息)。这会导致我受到速率限制的唯一方法是,如果我单独超过每个 webhook 的 5/5 速率限制(这与您尝试向一个频道发送垃圾邮件时发生的情况相同)。

-API 速率限制 原因:API 只有当我在 10 分钟内发送超过 10,000 个无效请求时,速率限制才会失效。所有请求都通过了,并且控制台中没有错误。如果我受到 API 速率限制,我将在长达一个小时内完全无法使用 discord API。

-我正在启动某种垃圾邮件防护 我已经考虑过了。由于大多数消息都能通过,我认为这不是问题所在。如果我确实针对请求量设置了任何过滤器,请求可能会超时,或者我会被阻止。

其他说明:

- 请求之间的延迟不是一个可行的解决方案,因为几乎任何数量的延迟乘以 1500 倍这 运行 都会导致此函数需要几分钟才能达到 运行。

-这可能与我遇到的另一个问题有关,按钮需要很长时间才能响应,因此交互通常会在我什至 运行 .deferReply() 之前超时,但是, none 的 Webhook 请求超时(这表明这可能不是问题所在)

-我的网络最近似乎很慢,尽管我有千兆位,但同样,如果网络是问题所在,就会出现错误。

总而言之,像这样的大量 webhook 消息应该有效,所以这个问题很可能是客户端问题。

发现问题:在如此短的时间内发送的大量 webhook 消息使我的互联网速度变慢,以至于很多网络请求最终都没有通过。我编写此函数的方式没有正确记录这些错误。我通过使用 await 而不是 .then().

解决了这个问题