发送大量 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().
解决了这个问题
我是 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().
解决了这个问题