如何在考虑速率限制的同时从频道中删除所有消息?
How to delete all messages from a channel while accounting for the rate limit?
我目前正在编写一个机器人程序,它将能够从他的所有消息中清除一个频道。在这样做的过程中,我遇到了一些问题。
我开始使用
IEnumerable<IMessage> messages = await channel.GetMessagesAsync(1000).FlattenAsync();
await ((ITextChannel)channel).DeleteMessagesAsync(messages);
它有效,但由于某些未知原因,您无法删除超过 2 周的邮件。
人们告诉我,如果您使用 DeleteAsync() 单独删除每条消息,就不会发生这种情况,所以我做到了
IEnumerable<IMessage> messages;
do
{
messages = await channel.GetMessagesAsync(100).FlattenAsync();
foreach (IMessage item in messages)
{
item.DeleteAsync();
}
} while (messages.Count() != 0);
现在,当我使用它时,出现 "Rate limit triggered" 错误,这是有道理的。
但现在,我正在寻找一种方法来删除我的所有消息,同时保持在速率限制之下。
我怎么知道下一个请求(删除消息)会触发速率限制(这样我的机器人可以等待限制离开)?
有没有办法使用 wrapper/API 获取当前的 "Bucket"?
或者是否有更好的清除频道的方法?
喜欢评论中提到的某人;如果你真的想删除频道中的所有条消息,'copying'频道并删除旧的是一个解决方案。
像这样:
var oldChannel = ((ITextChannel)channel);
// Assuming you have a variable 'guild' that is a IGuild
// (Which is your targeted guild)
await guild.CreateTextChannelAsync(oldChannel.Name, newChannel =>
{
// Copies over all the properties of the channel to the new channel
newChannel.CategoryId = oldChannel.CategoryId;
newChannel.Topic = oldChannel.Topic;
newChannel.Position = oldChannel.Position;
newChannel.SlowModeInterval = oldChannel.SlowModeInterval;
newChannel.IsNsfw = oldChannel.IsNsfw;
});
await oldChannel.DeleteAsync();
缺点是机器人现在需要权限来管理频道,而不是管理消息。
虽然如果你真的只想删除消息而不使用前一种方法,你可以在删除每条消息之前添加一个延迟。像这样:
//...
foreach (IMessage item in messages)
{
await item.DeleteAsync();
// Waits half a second before deleting the next.
await Task.Delay(500)
}
//...
缺点是删除所有消息需要一些时间。
通过一些修改,您可以先将其与 ((ITextChannel)channel).DeleteMessagesAsync(messages)
结合使用以清除较新的消息,然后再使用此循环。这将减少一些时间来删除所有消息。
我目前正在编写一个机器人程序,它将能够从他的所有消息中清除一个频道。在这样做的过程中,我遇到了一些问题。
我开始使用
IEnumerable<IMessage> messages = await channel.GetMessagesAsync(1000).FlattenAsync();
await ((ITextChannel)channel).DeleteMessagesAsync(messages);
它有效,但由于某些未知原因,您无法删除超过 2 周的邮件。
人们告诉我,如果您使用 DeleteAsync() 单独删除每条消息,就不会发生这种情况,所以我做到了
IEnumerable<IMessage> messages;
do
{
messages = await channel.GetMessagesAsync(100).FlattenAsync();
foreach (IMessage item in messages)
{
item.DeleteAsync();
}
} while (messages.Count() != 0);
现在,当我使用它时,出现 "Rate limit triggered" 错误,这是有道理的。
但现在,我正在寻找一种方法来删除我的所有消息,同时保持在速率限制之下。
我怎么知道下一个请求(删除消息)会触发速率限制(这样我的机器人可以等待限制离开)?
有没有办法使用 wrapper/API 获取当前的 "Bucket"?
或者是否有更好的清除频道的方法?
喜欢评论中提到的某人;如果你真的想删除频道中的所有条消息,'copying'频道并删除旧的是一个解决方案。
像这样:
var oldChannel = ((ITextChannel)channel);
// Assuming you have a variable 'guild' that is a IGuild
// (Which is your targeted guild)
await guild.CreateTextChannelAsync(oldChannel.Name, newChannel =>
{
// Copies over all the properties of the channel to the new channel
newChannel.CategoryId = oldChannel.CategoryId;
newChannel.Topic = oldChannel.Topic;
newChannel.Position = oldChannel.Position;
newChannel.SlowModeInterval = oldChannel.SlowModeInterval;
newChannel.IsNsfw = oldChannel.IsNsfw;
});
await oldChannel.DeleteAsync();
缺点是机器人现在需要权限来管理频道,而不是管理消息。
虽然如果你真的只想删除消息而不使用前一种方法,你可以在删除每条消息之前添加一个延迟。像这样:
//...
foreach (IMessage item in messages)
{
await item.DeleteAsync();
// Waits half a second before deleting the next.
await Task.Delay(500)
}
//...
缺点是删除所有消息需要一些时间。
通过一些修改,您可以先将其与 ((ITextChannel)channel).DeleteMessagesAsync(messages)
结合使用以清除较新的消息,然后再使用此循环。这将减少一些时间来删除所有消息。