Skip to content

Commit 6418409

Browse files
Issue 25 help thread system (#28)
* Create AskCommand.java * Almost done with ask command * done with the main command Need to add a command which shows active threads * Fixed a quick bug * spotlessApply * fixed some mistakes * Create AskCommand.java * Almost done with ask command * done with the main command Need to add a command which shows active threads * Fixed a quick bug * spotlessApply * fixed some mistakes * save * need to think about the active question will work * Finished with ask command * Got some issue but system overall working * channel is removed when archived * Almost done * pretty much finished * some minor fixess * edit system sill broken * edit command works now * made requested changes Co-authored-by: Haleloch <[email protected]>
1 parent b153548 commit 6418409

29 files changed

+1578
-54
lines changed

.github/PULL_REQUEST_TEMPLATE.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ It helps make it maintainable for us, and will save you from possibly recoding e
1717
If there's no relating issue, keep it NaN
1818
-->
1919

20-
Closes Issue: NaN
20+
Closes : NaN
2121

2222
## Description
2323

README.md

+6
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,12 @@ DB_PASSWORD=
4545
DB_URL=
4646
PORT_NUMBER=
4747
SERVER_NAME=
48+
//used for creating questions
49+
HELP_CHANNEL_ID=
50+
//Used to post the thread channels which are open
51+
ACTIVE_QUESTION_CHANNEL_ID=
52+
//the max amount of help threads that can be created in a day, default is 2
53+
ASK_LIMIT=
4854
```
4955

5056
### Part 3

src/main/java/io/github/org/programming/backend/handler/BaseHandler.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,9 @@ public abstract class BaseHandler extends ListenerAdapter {
3030
protected abstract long botOwnerId();
3131

3232

33-
public static void checkIfBuildIsNull(Object build) {
33+
public static void checkIfBuildIsNull(Object build, String className) {
3434
if (Objects.isNull(build)) {
35-
throw new IllegalArgumentException("Build is null");
35+
throw new IllegalArgumentException("Build is null for class: " + className);
3636
}
3737
}
3838
}

src/main/java/io/github/org/programming/backend/handler/MessageCommandHandler.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ protected MessageCommandHandler(@NotNull JDA jda, @NotNull Guild guild) {
6969
@SuppressWarnings("ResultOfMethodCallIgnored")
7070
private void addMessageCommand(@NotNull MessageCommandExtender command) {
7171

72-
BaseHandler.checkIfBuildIsNull(command.build());
72+
BaseHandler.checkIfBuildIsNull(command.build(), command.getClass().getSimpleName());
7373

7474
messageCommand.put(command.build().getCommandData().getName(), command);
7575
if (command.build().isGuildOnly()) {

src/main/java/io/github/org/programming/backend/handler/SlashCommandHandler.java

+1-2
Original file line numberDiff line numberDiff line change
@@ -90,8 +90,7 @@ protected SlashCommandHandler(@NotNull JDA jda, @NotNull Guild guild) {
9090
*/
9191
@SuppressWarnings("ResultOfMethodCallIgnored")
9292
private void addSlashCommand(@NotNull SlashCommandExtender command) {
93-
94-
BaseHandler.checkIfBuildIsNull(command.build());
93+
BaseHandler.checkIfBuildIsNull(command.build(), command.getClass().getSimpleName());
9594

9695
slashCommand.put(command.build().getSlashCommandData().getName(), command);
9796
if (command.build().isGuildOnly()) {

src/main/java/io/github/org/programming/backend/handler/UserCommandHandler.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ protected UserCommandHandler(@NotNull JDA jda, @NotNull Guild guild) {
7070
@SuppressWarnings("ResultOfMethodCallIgnored")
7171
private void addUserCommand(@NotNull UserCommandExtender command) {
7272

73-
BaseHandler.checkIfBuildIsNull(command.build());
73+
BaseHandler.checkIfBuildIsNull(command.build(), command.getClass().getSimpleName());
7474

7575
userCommand.put(command.build().getCommandData().getName(), command);
7676
if (command.build().isGuildOnly()) {

src/main/java/io/github/org/programming/bot/ProgrammingBot.java

+93-12
Original file line numberDiff line numberDiff line change
@@ -18,28 +18,36 @@
1818
*/
1919
package io.github.org.programming.bot;
2020

21+
import io.github.org.programming.bot.commands.thread.ActiveQuestionsHandler;
22+
import io.github.org.programming.bot.commands.thread.AskThreadStatus;
2123
import io.github.org.programming.bot.config.BotConfig;
2224
import io.github.org.programming.database.Database;
2325
import net.dv8tion.jda.api.JDA;
2426
import net.dv8tion.jda.api.JDABuilder;
2527
import net.dv8tion.jda.api.OnlineStatus;
26-
import net.dv8tion.jda.api.entities.Activity;
27-
import net.dv8tion.jda.api.entities.Guild;
28-
import net.dv8tion.jda.api.events.ReadyEvent;
28+
import net.dv8tion.jda.api.entities.*;
2929
import net.dv8tion.jda.api.hooks.ListenerAdapter;
3030
import net.dv8tion.jda.api.requests.GatewayIntent;
31-
import net.dv8tion.jda.api.utils.MemberCachePolicy;
31+
import net.dv8tion.jda.api.requests.restaction.pagination.ThreadChannelPaginationAction;
3232
import net.dv8tion.jda.api.utils.cache.CacheFlag;
33-
import org.jetbrains.annotations.NotNull;
3433
import org.jooq.DSLContext;
3534
import org.jooq.SQLDialect;
3635
import org.jooq.impl.DSL;
3736
import org.slf4j.Logger;
3837
import org.slf4j.LoggerFactory;
3938

39+
import java.time.Instant;
40+
import java.util.List;
41+
import java.util.Objects;
4042
import java.util.concurrent.ExecutorService;
4143
import java.util.concurrent.Executors;
4244
import java.util.concurrent.ScheduledExecutorService;
45+
import java.util.concurrent.TimeUnit;
46+
47+
import static io.github.org.programming.bot.commands.thread.ActiveQuestionsHandler.*;
48+
import static io.github.org.programming.bot.commands.thread.util.SupportedCategories.messageToSend;
49+
import static io.github.org.programming.database.thread.AskDatabase.deleteAskDatabaseWithTime;
50+
import static io.github.org.programming.database.thread.AskDatabase.getAskTimeStamps;
4351

4452
public class ProgrammingBot extends ListenerAdapter {
4553
private final Logger logger = LoggerFactory.getLogger(ProgrammingBot.class);
@@ -67,20 +75,63 @@ public ProgrammingBot(String[] args) throws Exception {
6775

6876
Guild guild = jda.awaitReady().getGuildById(BotConfig.getGuildId());
6977

70-
jda.awaitReady().addEventListener(new SlashCommandReg(jda, guild), this);
78+
jda.awaitReady().addEventListener(new RegisterSlashCommands(jda, guild), this);
7179

7280
logger.info("Bot is ready in guild {}", guild.getName());
7381

74-
if (Database.isConnected())
75-
logger.info("Database is connected");
76-
else
77-
logger.error("Database is not connected");
82+
scheduledExecutor.scheduleAtFixedRate(() -> {
83+
checkIfAskActiveQuestionMessageExists(guild);
84+
}, 0, 1, TimeUnit.DAYS);
85+
86+
// need to check this every minute
87+
scheduledExecutor.scheduleAtFixedRate(() -> {
88+
checkIfAskThreadTimeNeedsToBeRest(jda);
89+
}, 0, 1, TimeUnit.SECONDS);
90+
91+
scheduledExecutor.scheduleAtFixedRate(() -> {
92+
checkIfAskHelpThreadArchived(guild);
93+
}, 0, 1, TimeUnit.SECONDS);
94+
}
95+
96+
public synchronized void checkIfAskActiveQuestionMessageExists(Guild guild) {
97+
TextChannel activeQuestionsChannel =
98+
guild.getTextChannelById(BotConfig.getActiveQuestionChannelId());
99+
100+
if (activeQuestionsChannel == null) {
101+
throw new IllegalStateException("Active questions channel not found");
102+
}
103+
104+
String messageId = getActiveQuestionMessage(guild.getId());
105+
106+
if (messageId == null) {
107+
Message message = activeQuestionsChannel.sendMessage(messageToSend()).complete();
108+
updateActiveQuestionMessage(guild.getId(), message.getId());
109+
ActiveQuestionsHandler.setMessage(message);
110+
} else {
111+
activeQuestionsChannel.retrieveMessageById(messageId)
112+
.queue(this::dealWithSuccess,
113+
e -> dealWithError(e, guild, messageId, activeQuestionsChannel));
114+
}
115+
}
116+
117+
private void dealWithError(Throwable error, Guild guild, String messageId,
118+
TextChannel activeQuestionsChannel) {
119+
if (Objects.equals(error.getMessage(), "10008: Unknown Message")) {
120+
deleteActiveQuestionMessageId(guild.getId(), messageId);
121+
activeQuestionsChannel.sendMessage(messageToSend()).queue(success -> {
122+
updateActiveQuestionMessage(guild.getId(), success.getId());
123+
ActiveQuestionsHandler.setMessage(success);
124+
});
125+
}
126+
}
127+
128+
private void dealWithSuccess(Message message) {
129+
ActiveQuestionsHandler.setMessage(message);
78130
}
79131

80132
public void onDatabase() {
81133
context = DSL.using(Database.getConnection(), SQLDialect.POSTGRES);
82134

83-
84135
if (Database.isConnected()) {
85136
logger.info("Connected to database");
86137
} else {
@@ -95,10 +146,40 @@ public void onDatabase() {
95146
logger.error("Failed to close database", e);
96147
}
97148
}));
98-
99149
}
100150

101151
public static DSLContext getContext() {
102152
return context;
103153
}
154+
155+
public synchronized void checkIfAskThreadTimeNeedsToBeRest(JDA jda) {
156+
jda.getGuilds().forEach(c -> {
157+
List<Instant> oldTimeInstant = getAskTimeStamps(c.getId());
158+
// need to check if between 24 hours since last time asked
159+
oldTimeInstant.forEach(i -> {
160+
if (i.isAfter(Instant.now().minusSeconds(86400))) {
161+
deleteAskDatabaseWithTime(i, c.getId());
162+
}
163+
});
164+
});
165+
}
166+
167+
public synchronized void checkIfAskHelpThreadArchived(Guild guild) {
168+
TextChannel channel = guild.getTextChannelById(BotConfig.getActiveQuestionChannelId());
169+
ThreadChannelPaginationAction threadChannelPaginationAction =
170+
channel != null ? channel.retrieveArchivedPublicThreadChannels() : null;
171+
172+
if (threadChannelPaginationAction == null) {
173+
logger.debug("No archived thread channels found");
174+
return;
175+
}
176+
177+
List<ThreadChannel> archivedThreadChannels = threadChannelPaginationAction.complete();
178+
179+
for (ThreadChannel c : archivedThreadChannels) {
180+
String name = c.getName();
181+
String category = name.substring(1, name.indexOf("]")).toLowerCase();
182+
updateActiveQuestions(c, AskThreadStatus.CLOSED, category);
183+
}
184+
}
104185
}

src/main/java/io/github/org/programming/bot/SlashCommandReg.java renamed to src/main/java/io/github/org/programming/bot/RegisterSlashCommands.java

+8-2
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@
2424
import io.github.org.programming.bot.commands.moderation.BanCommand;
2525
import io.github.org.programming.bot.commands.moderation.KickCommand;
2626
import io.github.org.programming.bot.commands.moderation.UnBanCommand;
27+
import io.github.org.programming.bot.commands.thread.AskCommand;
28+
import io.github.org.programming.bot.commands.thread.CloseAskThread;
29+
import io.github.org.programming.bot.commands.thread.EditAskThread;
2730
import io.github.org.programming.bot.config.BotConfig;
2831
import net.dv8tion.jda.api.JDA;
2932
import net.dv8tion.jda.api.entities.Guild;
@@ -33,8 +36,8 @@
3336
import java.util.List;
3437

3538

36-
public class SlashCommandReg extends SlashCommandHandler {
37-
protected SlashCommandReg(@NotNull JDA jda, @NotNull Guild guild) {
39+
public class RegisterSlashCommands extends SlashCommandHandler {
40+
protected RegisterSlashCommands(@NotNull JDA jda, @NotNull Guild guild) {
3841
super(jda, guild);
3942

4043
List<SlashCommandExtender> extenders = new ArrayList<>();
@@ -43,6 +46,9 @@ protected SlashCommandReg(@NotNull JDA jda, @NotNull Guild guild) {
4346
extenders.add(new KickCommand());
4447
extenders.add(new BanCommand());
4548
extenders.add(new UnBanCommand());
49+
extenders.add(new AskCommand());
50+
extenders.add(new CloseAskThread());
51+
extenders.add(new EditAskThread());
4652

4753
queueAndRegisterSlashCommands(extenders);
4854
}

src/main/java/io/github/org/programming/bot/commands/moderation/UnBanCommand.java

+18-9
Original file line numberDiff line numberDiff line change
@@ -19,40 +19,44 @@
1919
package io.github.org.programming.bot.commands.moderation;
2020

2121
import io.github.org.programming.backend.builder.slash.SlashCommand;
22+
import io.github.org.programming.backend.builder.slash.SlashCommandBuilder;
2223
import io.github.org.programming.backend.extension.SlashCommandExtender;
2324
import io.github.org.programming.bot.config.BotConfig;
2425
import io.github.org.programming.database.moderation.ModerationDatabase;
2526
import net.dv8tion.jda.api.EmbedBuilder;
27+
import net.dv8tion.jda.api.Permission;
2628
import net.dv8tion.jda.api.entities.Member;
2729
import net.dv8tion.jda.api.entities.MessageEmbed;
2830
import net.dv8tion.jda.api.entities.TextChannel;
31+
import net.dv8tion.jda.api.entities.User;
2932
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
3033
import net.dv8tion.jda.api.interactions.commands.OptionMapping;
34+
import net.dv8tion.jda.api.interactions.commands.OptionType;
3135
import org.jetbrains.annotations.NotNull;
3236

3337

3438
public class UnBanCommand implements SlashCommandExtender {
3539
@Override
3640
public void onSlashCommandInteraction(@NotNull SlashCommandInteractionEvent event) {
37-
Member member = event.getOption("member", OptionMapping::getAsMember);
41+
User user = event.getOption("member", OptionMapping::getAsUser);
3842
Member moderator = event.getMember();
3943
String reason = event.getOption("reason", OptionMapping::getAsString);
4044

41-
int id = ModerationDatabase.updateModerationDataBase(event.getGuild().getId(),
42-
member.getId(), moderator.getId(), reason, "unban");
45+
int id = ModerationDatabase.updateModerationDataBase(event.getGuild().getId(), user.getId(),
46+
moderator.getId(), reason, "unban");
4347

4448
event.getGuild()
45-
.unban(member.getUser())
49+
.unban(user)
4650
.flatMap(channel -> event.getGuild()
4751
.getChannelById(TextChannel.class, BotConfig.getAuditLogChannelId())
48-
.sendMessageEmbeds(unbanEmbed(member, moderator, reason, id)))
49-
.flatMap(message -> event.reply("Unbanned " + member.getAsMention() + " for " + reason))
52+
.sendMessageEmbeds(unbanEmbed(user, moderator, reason, id)))
53+
.flatMap(message -> event.reply("Unbanned " + user.getAsMention() + " for " + reason))
5054
.queue();
5155

5256
}
5357

54-
private MessageEmbed unbanEmbed(Member member, @NotNull Member moderator,
55-
@NotNull String reason, int caseId) {
58+
private MessageEmbed unbanEmbed(User member, @NotNull Member moderator, @NotNull String reason,
59+
int caseId) {
5660
return new EmbedBuilder()
5761
.setTitle("The member + " + member.getAsMention() + " has been unbanned")
5862
.setDescription("The member has been unbanned by " + moderator.getAsMention() + " for "
@@ -65,6 +69,11 @@ private MessageEmbed unbanEmbed(Member member, @NotNull Member moderator,
6569

6670
@Override
6771
public SlashCommand build() {
68-
return null;
72+
return new SlashCommandBuilder("unban", "The user to unban")
73+
.addOption(OptionType.USER, "member", "The user to unban", true)
74+
.addOption(OptionType.STRING, "reason", "The reason for the unban", true)
75+
.build()
76+
.setBotPerms(Permission.BAN_MEMBERS)
77+
.setUserPerms(Permission.BAN_MEMBERS);
6978
}
7079
}

0 commit comments

Comments
 (0)