Implement fully functional clearchat command
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
The command now supports potentially-infinite message deletion and exception catching (eg messages older than 2 weeks). No longer limited to 100 messages per run.
This commit is contained in:
parent
e1ecc310cc
commit
7d9c820243
@ -6,6 +6,8 @@ import net.dv8tion.jda.api.entities.MessageHistory;
|
|||||||
import net.dv8tion.jda.api.entities.TextChannel;
|
import net.dv8tion.jda.api.entities.TextChannel;
|
||||||
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
|
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
|
||||||
import net.dv8tion.jda.api.hooks.ListenerAdapter;
|
import net.dv8tion.jda.api.hooks.ListenerAdapter;
|
||||||
|
import net.dv8tion.jda.api.interactions.InteractionHook;
|
||||||
|
import net.dv8tion.jda.api.requests.restaction.interactions.ReplyCallbackAction;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import wtf.beatrice.hidekobot.utils.RandomUtil;
|
import wtf.beatrice.hidekobot.utils.RandomUtil;
|
||||||
|
|
||||||
@ -49,22 +51,132 @@ public class SlashCommandListener extends ListenerAdapter
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int deleteCount = event.getOption("amount").getAsInt();
|
int toDeleteAmount = event.getOption("amount").getAsInt(); // not null because the int arg is required
|
||||||
if(deleteCount < 2 || deleteCount > 98)
|
|
||||||
|
if(toDeleteAmount <= 0)
|
||||||
{
|
{
|
||||||
event.reply("Sorry! I can't delete that amount of messages!").queue();
|
event.reply("Sorry, I can't delete that amount of messages!").queue();
|
||||||
return;
|
}
|
||||||
|
else {
|
||||||
|
// answer by saying that the operation has begun.
|
||||||
|
InteractionHook replyInteraction = event.reply("Clearing...").complete();
|
||||||
|
|
||||||
|
// int to keep track of how many messages we deleted.
|
||||||
|
int deleted = 0;
|
||||||
|
|
||||||
|
int limit = 95; //discord limits this method to range 2-100. we set it to 95 to be safe..
|
||||||
|
|
||||||
|
// increase the count by 1, because we technically aren't clearing the first ID ever
|
||||||
|
// which is actually the slash command's ID and not a message.
|
||||||
|
toDeleteAmount++;
|
||||||
|
|
||||||
|
// count how many times we have to iterate this to delete the full <toDeleteAmount> messages.
|
||||||
|
int iterations = toDeleteAmount / limit;
|
||||||
|
|
||||||
|
//if there are some messages left, but less than <limit>, we need one more iterations.
|
||||||
|
int remainder = toDeleteAmount % limit;
|
||||||
|
if(remainder != 0) iterations++;
|
||||||
|
|
||||||
|
// set the starting point.
|
||||||
|
long messageId = event.getInteraction().getIdLong();
|
||||||
|
|
||||||
|
// boolean to see if we're trying to delete more messages than possible.
|
||||||
|
boolean outOfBounds = false;
|
||||||
|
|
||||||
|
// do iterate.
|
||||||
|
for(int iteration = 0; iteration < iterations; iteration++)
|
||||||
|
{
|
||||||
|
if(outOfBounds) break;
|
||||||
|
|
||||||
|
// set how many messages to delete for this iteration (usually <limit> unless there's a remainder)
|
||||||
|
int iterationSize = limit;
|
||||||
|
|
||||||
|
// if we are at the last iteration...
|
||||||
|
if(iteration+1 == iterations)
|
||||||
|
{
|
||||||
|
// check if we have <limit> or fewer messages to delete
|
||||||
|
if(remainder != 0) iterationSize = remainder;
|
||||||
}
|
}
|
||||||
|
|
||||||
event.reply("Clearing...").queue();
|
if(iterationSize == 1)
|
||||||
|
{
|
||||||
|
// grab the message
|
||||||
|
Message toDelete = ((TextChannel)channel).retrieveMessageById(messageId).complete();
|
||||||
|
//only delete one message
|
||||||
|
if(toDelete != null) toDelete.delete().queue();
|
||||||
|
else outOfBounds = true;
|
||||||
|
// increase deleted counter by 1
|
||||||
|
deleted++;
|
||||||
|
} else {
|
||||||
|
// get the last <iterationSize - 1> messages.
|
||||||
|
MessageHistory.MessageRetrieveAction action = channel.getHistoryBefore(messageId, iterationSize - 1);
|
||||||
|
// note: first one is the most recent, last one is the oldest message.
|
||||||
|
List<Message> messages = new ArrayList<>();
|
||||||
|
// (we are skipping first iteration since it would return an error, given that the id is the slash command and not a message)
|
||||||
|
if(iteration!=0) messages.add(((TextChannel)channel).retrieveMessageById(messageId).complete());
|
||||||
|
messages.addAll(action.complete().getRetrievedHistory());
|
||||||
|
|
||||||
MessageHistory.MessageRetrieveAction action = channel.getHistoryBefore(event.getInteraction().getIdLong(), deleteCount);
|
// check if we only have one or zero messages left (trying to delete more than possible)
|
||||||
List<Message> messagesUnmodifiable = action.complete().getRetrievedHistory();
|
if(messages.size() <= 1)
|
||||||
List<Message> messages = new ArrayList<>(messagesUnmodifiable);
|
{
|
||||||
|
outOfBounds = true;
|
||||||
|
} else {
|
||||||
|
// before deleting, we need to grab the <previous to the oldest> message's id for next iteration.
|
||||||
|
action = channel.getHistoryBefore(messages.get(messages.size() - 1).getIdLong(), 1);
|
||||||
|
|
||||||
|
List<Message> previousMessage = action.complete().getRetrievedHistory();
|
||||||
|
|
||||||
|
// if that message exists (we are not out of bounds)... store it
|
||||||
|
if(!previousMessage.isEmpty()) messageId = previousMessage.get(0).getIdLong();
|
||||||
|
else outOfBounds = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// queue messages for deletion
|
||||||
|
if(messages.size() == 1)
|
||||||
|
{
|
||||||
|
messages.get(0).delete().queue();
|
||||||
|
}
|
||||||
|
else if(!messages.isEmpty())
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
((TextChannel) channel).deleteMessages(messages).complete();
|
||||||
|
/* alternatively, we could use purgeMessages, which is smarter...
|
||||||
|
however, it also tries to delete messages older than 2 weeks
|
||||||
|
which are restricted by discord, and thus has to use
|
||||||
|
a less efficient way that triggers rate-limiting very quickly. */
|
||||||
|
} catch (Exception e)
|
||||||
|
{
|
||||||
|
replyInteraction.editOriginal("Sorry, it seems like there was an issue! " + e.getMessage()).queue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// increase deleted counter by <list size>
|
||||||
|
deleted += messages.size();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// log having deleted the messages.
|
||||||
|
if(deleted < 1)
|
||||||
|
{
|
||||||
|
replyInteraction.editOriginal("Couldn't clear any message!").queue();
|
||||||
|
} else if(deleted == 1)
|
||||||
|
{
|
||||||
|
replyInteraction.editOriginal("Cleared 1 message!").queue();
|
||||||
|
} else {
|
||||||
|
replyInteraction.editOriginal("Cleared " + deleted + " messages!").queue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*MessageHistory.MessageRetrieveAction action = channel.getHistoryBefore(event.getInteraction().getIdLong(), toDeleteAmount);
|
||||||
|
List<Message> messages = action.complete().getRetrievedHistory();
|
||||||
|
|
||||||
//more than 2 messages, less than 100 for this method
|
//more than 2 messages, less than 100 for this method
|
||||||
((TextChannel) channel).deleteMessages(messages).queue();
|
((TextChannel) channel).deleteMessages(messages).queue();
|
||||||
|
|
||||||
|
// announce having cleared the messages.
|
||||||
|
replyInteraction.editOriginal("Cleared " + toDeleteAmount + " messages!").queue();*/
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user