Skip to content

Commit b797ffa

Browse files
committed
Fixed bugs with rate limiting by adding cooldown
* close command * change category command
1 parent 737e456 commit b797ffa

File tree

2 files changed

+67
-0
lines changed

2 files changed

+67
-0
lines changed

application/src/main/java/org/togetherjava/tjbot/commands/help/ChangeHelpCategoryCommand.java

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package org.togetherjava.tjbot.commands.help;
22

3+
import com.github.benmanes.caffeine.cache.Cache;
4+
import com.github.benmanes.caffeine.cache.Caffeine;
35
import net.dv8tion.jda.api.entities.Guild;
46
import net.dv8tion.jda.api.entities.Message;
57
import net.dv8tion.jda.api.entities.Role;
@@ -14,7 +16,10 @@
1416
import org.togetherjava.tjbot.commands.SlashCommandVisibility;
1517
import org.togetherjava.tjbot.config.Config;
1618

19+
import java.time.Instant;
20+
import java.time.temporal.ChronoUnit;
1721
import java.util.Optional;
22+
import java.util.concurrent.TimeUnit;
1823

1924
/**
2025
* Implements the {@code /change-help-category} command, which is able to change the category of a
@@ -29,7 +34,11 @@
2934
public final class ChangeHelpCategoryCommand extends SlashCommandAdapter {
3035
private static final String CATEGORY_OPTION = "category";
3136

37+
private static final int COOLDOWN_DURATION_VALUE = 1;
38+
private static final ChronoUnit COOLDOWN_DURATION_UNIT = ChronoUnit.HOURS;
39+
3240
private final HelpSystemHelper helper;
41+
private final Cache<Long, Instant> helpThreadIdToLastCategoryChange;
3342

3443
/**
3544
* Creates a new instance.
@@ -49,6 +58,11 @@ public ChangeHelpCategoryCommand(@NotNull Config config, @NotNull HelpSystemHelp
4958

5059
getData().addOptions(category);
5160

61+
helpThreadIdToLastCategoryChange = Caffeine.newBuilder()
62+
.maximumSize(1_000)
63+
.expireAfterAccess(COOLDOWN_DURATION_VALUE, TimeUnit.of(COOLDOWN_DURATION_UNIT))
64+
.build();
65+
5266
this.helper = helper;
5367
}
5468

@@ -66,6 +80,16 @@ public void onSlashCommand(@NotNull SlashCommandInteractionEvent event) {
6680
return;
6781
}
6882

83+
if (isHelpThreadOnCooldown(helpThread)) {
84+
event
85+
.reply("Please wait a bit, this command can only be used once per %d %s."
86+
.formatted(COOLDOWN_DURATION_VALUE, COOLDOWN_DURATION_UNIT))
87+
.setEphemeral(true)
88+
.queue();
89+
return;
90+
}
91+
helpThreadIdToLastCategoryChange.put(helpThread.getIdLong(), Instant.now());
92+
6993
event.deferReply().queue();
7094

7195
helper.renameChannelToCategoryTitle(helpThread, category)
@@ -96,4 +120,13 @@ public void onSlashCommand(@NotNull SlashCommandInteractionEvent event) {
96120
return action.flatMap(any -> helpThread.sendMessage(headsUpWithoutRole)
97121
.flatMap(message -> message.editMessage(headsUpWithRole)));
98122
}
123+
124+
private boolean isHelpThreadOnCooldown(@NotNull ThreadChannel helpThread) {
125+
return Optional
126+
.ofNullable(helpThreadIdToLastCategoryChange.getIfPresent(helpThread.getIdLong()))
127+
.map(lastCategoryChange -> lastCategoryChange.plus(COOLDOWN_DURATION_VALUE,
128+
COOLDOWN_DURATION_UNIT))
129+
.filter(Instant.now()::isBefore)
130+
.isPresent();
131+
}
99132
}

application/src/main/java/org/togetherjava/tjbot/commands/help/CloseCommand.java

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package org.togetherjava.tjbot.commands.help;
22

3+
import com.github.benmanes.caffeine.cache.Cache;
4+
import com.github.benmanes.caffeine.cache.Caffeine;
35
import net.dv8tion.jda.api.EmbedBuilder;
46
import net.dv8tion.jda.api.entities.MessageEmbed;
57
import net.dv8tion.jda.api.entities.ThreadChannel;
@@ -8,14 +10,23 @@
810
import org.togetherjava.tjbot.commands.SlashCommandAdapter;
911
import org.togetherjava.tjbot.commands.SlashCommandVisibility;
1012

13+
import java.time.Instant;
14+
import java.time.temporal.ChronoUnit;
15+
import java.util.Optional;
16+
import java.util.concurrent.TimeUnit;
17+
1118
/**
1219
* Implements the {@code /close} command to close question threads.
1320
* <p>
1421
* Can be used in active (non-archived) question threads. Will close, i.e. archive, the thread upon
1522
* use. Meant to be used once a question has been resolved.
1623
*/
1724
public final class CloseCommand extends SlashCommandAdapter {
25+
private static final int COOLDOWN_DURATION_VALUE = 1;
26+
private static final ChronoUnit COOLDOWN_DURATION_UNIT = ChronoUnit.HOURS;
27+
1828
private final HelpSystemHelper helper;
29+
private final Cache<Long, Instant> helpThreadIdToLastClose;
1930

2031
/**
2132
* Creates a new instance.
@@ -25,6 +36,11 @@ public final class CloseCommand extends SlashCommandAdapter {
2536
public CloseCommand(@NotNull HelpSystemHelper helper) {
2637
super("close", "Close this question thread", SlashCommandVisibility.GUILD);
2738

39+
helpThreadIdToLastClose = Caffeine.newBuilder()
40+
.maximumSize(1_000)
41+
.expireAfterAccess(COOLDOWN_DURATION_VALUE, TimeUnit.of(COOLDOWN_DURATION_UNIT))
42+
.build();
43+
2844
this.helper = helper;
2945
}
3046

@@ -40,10 +56,28 @@ public void onSlashCommand(@NotNull SlashCommandInteractionEvent event) {
4056
return;
4157
}
4258

59+
if (isHelpThreadOnCooldown(helpThread)) {
60+
event
61+
.reply("Please wait a bit, this command can only be used once per %d %s."
62+
.formatted(COOLDOWN_DURATION_VALUE, COOLDOWN_DURATION_UNIT))
63+
.setEphemeral(true)
64+
.queue();
65+
return;
66+
}
67+
helpThreadIdToLastClose.put(helpThread.getIdLong(), Instant.now());
68+
4369
MessageEmbed embed = new EmbedBuilder().setDescription("Closed the thread.")
4470
.setColor(HelpSystemHelper.AMBIENT_COLOR)
4571
.build();
4672

4773
event.replyEmbeds(embed).flatMap(any -> helpThread.getManager().setArchived(true)).queue();
4874
}
75+
76+
private boolean isHelpThreadOnCooldown(@NotNull ThreadChannel helpThread) {
77+
return Optional.ofNullable(helpThreadIdToLastClose.getIfPresent(helpThread.getIdLong()))
78+
.map(lastCategoryChange -> lastCategoryChange.plus(COOLDOWN_DURATION_VALUE,
79+
COOLDOWN_DURATION_UNIT))
80+
.filter(Instant.now()::isBefore)
81+
.isPresent();
82+
}
4983
}

0 commit comments

Comments
 (0)