如何在考虑速率限制的同时从频道中删除所有消息?

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) 结合使用以清除较新的消息,然后再使用此循环。这将减少一些时间来删除所有消息。