Как удалить все сообщения с канала с учетом лимита скорости?

В настоящее время я программирую бота, который сможет очистить канал от всех его сообщений. При этом я столкнулся с несколькими проблемами.

Я начал с использования

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);

Теперь, когда я его использую, я получаю сообщение об ошибке «Ограничение скорости», что имеет смысл.

Но теперь я ищу способ удалить все свои сообщения, оставаясь при этом в пределах лимита скорости.


Как я могу узнать, что следующий запрос (на удаление сообщения) вызовет ограничение скорости (чтобы мой бот мог дождаться выхода ограничения)?

Есть ли способ получить текущий «ковш» с помощью оболочки/API?

Или есть вообще лучший способ очистить канал?


person Étienne    schedule 30.08.2019    source источник
comment
посмотрите на этот вопрос может вам помочь   -  person Ezz    schedule 30.08.2019
comment
Самый простой способ удалить все сообщения в канале, не достигая ограничения скорости, — это удалить и заново создать канал.   -  person MX D    schedule 30.08.2019


Ответы (1)


Как кто-то в комментариях упомянул; Если вы действительно хотите удалить все сообщения в канале, «копирование» канала и удаление старого — это решение.

Вот так:

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), чтобы очистить новые сообщения, прежде чем использовать этот цикл. Это сократит время на удаление всех сообщений.

person Kaynn    schedule 30.08.2019
comment
Изменяет ли клонирование указанного канала его идентификатор? - person Étienne; 03.09.2019
comment
Новый клонированный канал должен иметь новый идентификатор; Ни один канал на одном сервере не должен иметь тот же идентификатор, что и другой канал. - person Kaynn; 03.09.2019