Skip to content

Commit a72c796

Browse files
Merge pull request #376 from Java-Discord/dynxsty/qotw
Refactor QOTW
2 parents d05e1ea + aaf6c39 commit a72c796

33 files changed

+466
-1246
lines changed

build.gradle.kts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,8 @@ dependencies {
3030
compileOnly("org.jetbrains:annotations:23.0.0")
3131

3232
// DIH4JDA (Command Framework) & JDA
33-
implementation("xyz.dynxsty:dih4jda:1.6.1")
34-
implementation("net.dv8tion:JDA:5.0.0-beta.1") {
33+
implementation("xyz.dynxsty:dih4jda:1.6.2")
34+
implementation("net.dv8tion:JDA:5.0.0-beta.2") {
3535
exclude(module = "opus-java")
3636
}
3737

src/main/java/net/javadiscord/javabot/data/config/guild/QOTWConfig.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,14 @@
33
import lombok.Data;
44
import lombok.EqualsAndHashCode;
55
import net.dv8tion.jda.api.entities.Role;
6+
import net.dv8tion.jda.api.entities.channel.concrete.ForumChannel;
67
import net.dv8tion.jda.api.entities.channel.concrete.NewsChannel;
78
import net.dv8tion.jda.api.entities.channel.concrete.TextChannel;
9+
import net.dv8tion.jda.api.entities.channel.forums.ForumTag;
810
import net.javadiscord.javabot.data.config.GuildConfigItem;
911

12+
import java.util.List;
13+
1014
/**
1115
* Configuration for the guild's qotw system.
1216
*/
@@ -15,8 +19,10 @@
1519
public class QOTWConfig extends GuildConfigItem {
1620
private long questionChannelId;
1721
private long submissionChannelId;
22+
private long submissionsForumChannelId;
1823
private long questionRoleId;
1924
private long qotwReviewRoleId;
25+
private String submissionForumOngoingReviewTagName = "";
2026

2127
public NewsChannel getQuestionChannel() {
2228
return this.getGuild().getNewsChannelById(this.questionChannelId);
@@ -26,11 +32,27 @@ public TextChannel getSubmissionChannel() {
2632
return this.getGuild().getTextChannelById(this.submissionChannelId);
2733
}
2834

35+
public ForumChannel getSubmissionsForumChannel() {
36+
return this.getGuild().getForumChannelById(this.submissionsForumChannelId);
37+
}
38+
2939
public Role getQOTWRole() {
3040
return this.getGuild().getRoleById(this.questionRoleId);
3141
}
3242

3343
public Role getQOTWReviewRole() {
3444
return this.getGuild().getRoleById(this.qotwReviewRoleId);
3545
}
46+
47+
/**
48+
* Gets a {@link ForumTag} based on the specified name.
49+
*
50+
* @return The specified {@link ForumTag} or null if there is no tag matching the specified name.
51+
*/
52+
public ForumTag getSubmissionsForumOngoingReviewTag() {
53+
ForumChannel forumChannel = getSubmissionsForumChannel();
54+
if (forumChannel == null) return null;
55+
List<ForumTag> tags = forumChannel.getAvailableTagsByName(this.submissionForumOngoingReviewTagName, true);
56+
return tags.stream().findFirst().orElse(null);
57+
}
3658
}

src/main/java/net/javadiscord/javabot/data/h2db/commands/ExportTableSubcommand.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,6 @@ public ExportTableSubcommand(ExecutorService asyncPool, SystemsConfig systemsCon
5252
.addChoice("Message Cache", "MESSAGE_CACHE")
5353
.addChoice("Question of the Week Accounts", "QOTW_POINTS")
5454
.addChoice("Question of the Week Questions", "QOTW_QUESTION")
55-
.addChoice("Question of the Week Submissions", "QOTW_SUBMISSIONS")
5655
.addChoice("Reserved Help Channels", "RESERVED_HELP_CHANNELS")
5756
.addChoice("Starboard", "STARBOARD")
5857
.addChoice("Warns", "WARN")
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package net.javadiscord.javabot.listener;
2+
3+
import lombok.RequiredArgsConstructor;
4+
import net.dv8tion.jda.api.entities.channel.ChannelType;
5+
import net.dv8tion.jda.api.entities.channel.concrete.ThreadChannel;
6+
import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
7+
import net.dv8tion.jda.api.hooks.ListenerAdapter;
8+
import net.dv8tion.jda.api.interactions.components.buttons.Button;
9+
import net.javadiscord.javabot.data.config.BotConfig;
10+
import net.javadiscord.javabot.data.config.guild.QOTWConfig;
11+
import net.javadiscord.javabot.util.InteractionUtils;
12+
import org.jetbrains.annotations.NotNull;
13+
14+
/**
15+
* Listens for new messages inside QOTW submissions and warns the author about the webhook limitations.
16+
*/
17+
@RequiredArgsConstructor
18+
public class QOTWSubmissionListener extends ListenerAdapter {
19+
private final BotConfig botConfig;
20+
21+
@Override
22+
public void onMessageReceived(@NotNull MessageReceivedEvent event) {
23+
if (!event.isFromGuild() || !event.isFromThread() || event.getChannelType() != ChannelType.GUILD_PRIVATE_THREAD) {
24+
return;
25+
}
26+
QOTWConfig qotwConfig = botConfig.get(event.getGuild()).getQotwConfig();
27+
ThreadChannel thread = event.getChannel().asThreadChannel();
28+
// TODO: fix check
29+
if (thread.getParentChannel().getIdLong() != qotwConfig.getSubmissionChannelId()) {
30+
return;
31+
}
32+
if (event.getMessage().getContentRaw().length() > 2000) {
33+
event.getChannel().sendMessageFormat("""
34+
Hey %s!
35+
Please keep in mind that messages **over 2000 characters** get split in half due to webhook limitations.
36+
If you want to make sure that your submission is properly formatted, split your message into smaller chunks instead.""",
37+
event.getAuthor().getAsMention())
38+
.setActionRow(Button.secondary(InteractionUtils.DELETE_ORIGINAL_TEMPLATE, "\uD83D\uDDD1️"))
39+
.queue();
40+
}
41+
}
42+
}

src/main/java/net/javadiscord/javabot/systems/help/HelpExperienceJob.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ public class HelpExperienceJob {
2828
/**
2929
* Removes a specified amount of experience from everyone's help account.
3030
*/
31-
@Scheduled(cron = "0 0 0 * * *")//daily 00:00
31+
@Scheduled(cron = "0 0 0 * * *") // Daily, 00:00 UTC
3232
public void execute() {
3333
asyncPool.execute(() -> {
3434
try {

src/main/java/net/javadiscord/javabot/systems/notification/NotificationService.java

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,12 @@
66
import net.dv8tion.jda.api.entities.User;
77
import net.javadiscord.javabot.data.config.BotConfig;
88
import net.javadiscord.javabot.systems.qotw.QOTWPointsService;
9-
import net.javadiscord.javabot.systems.qotw.submissions.dao.QOTWSubmissionRepository;
109
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
1110
import net.dv8tion.jda.api.requests.restaction.MessageCreateAction;
1211
import org.jetbrains.annotations.Contract;
1312
import org.jetbrains.annotations.NotNull;
1413
import org.springframework.stereotype.Service;
1514

16-
import java.util.concurrent.ExecutorService;
1715
import java.util.function.Function;
1816

1917
/**
@@ -24,8 +22,6 @@
2422
public class NotificationService {
2523
private final QOTWPointsService qotwPointsService;
2624
private final BotConfig botConfig;
27-
private final ExecutorService asyncPool;
28-
private final QOTWSubmissionRepository qotwSubmissionRepository;
2925

3026
@Contract("_ -> new")
3127
public @NotNull GuildNotificationService withGuild(Guild guild) {
@@ -38,11 +34,11 @@ public class NotificationService {
3834
}
3935

4036
public @NotNull QOTWGuildNotificationService withQOTW(Guild guild) {
41-
return new QOTWGuildNotificationService(this, guild, asyncPool, qotwSubmissionRepository);
37+
return new QOTWGuildNotificationService(this, guild);
4238
}
4339

4440
public @NotNull QOTWNotificationService withQOTW(Guild guild, User user) {
45-
return new QOTWNotificationService(this, qotwPointsService, user, guild, botConfig.getSystems(), asyncPool, qotwSubmissionRepository);
41+
return new QOTWNotificationService(this, qotwPointsService, user, guild, botConfig.getSystems());
4642
}
4743

4844
/**

src/main/java/net/javadiscord/javabot/systems/notification/QOTWGuildNotificationService.java

Lines changed: 9 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -8,18 +8,12 @@
88
import net.dv8tion.jda.api.entities.MessageEmbed;
99
import net.dv8tion.jda.api.entities.User;
1010
import net.dv8tion.jda.api.entities.channel.concrete.ThreadChannel;
11+
import net.javadiscord.javabot.systems.qotw.model.QOTWSubmission;
1112
import net.javadiscord.javabot.systems.qotw.submissions.SubmissionStatus;
12-
import net.javadiscord.javabot.systems.qotw.submissions.dao.QOTWSubmissionRepository;
13-
import net.javadiscord.javabot.systems.qotw.submissions.model.QOTWSubmission;
14-
import net.javadiscord.javabot.util.ExceptionLogger;
1513

1614
import org.jetbrains.annotations.NotNull;
17-
import org.springframework.dao.DataAccessException;
1815

19-
import javax.annotation.Nullable;
2016
import java.time.Instant;
21-
import java.util.Optional;
22-
import java.util.concurrent.ExecutorService;
2317

2418
/**
2519
* Handles all sorts of guild qotw notifications.
@@ -32,42 +26,29 @@ public class QOTWGuildNotificationService {
3226
*/
3327
protected final NotificationService notificationService;
3428
private final Guild guild;
35-
private final ExecutorService asyncPool;
36-
private final QOTWSubmissionRepository qotwSubmissionRepository;
3729

3830
/**
3931
* Sends the executed action, performed on a QOTW submission thread, to the {@link Guild}s log channel.
4032
*
4133
* @param reviewedBy The user which reviewed the QOTW submission thread.
42-
* @param submissionThread The submission thread itself.
34+
* @param submission The {@link QOTWSubmission}.
4335
* @param status The {@link SubmissionStatus}.
44-
* @param reasons The reasons for taking this action.
4536
*/
46-
public void sendSubmissionActionNotification(User reviewedBy, ThreadChannel submissionThread, SubmissionStatus status, @Nullable String... reasons) {
47-
asyncPool.execute(()->{
48-
try {
49-
Optional<QOTWSubmission> submissionOptional = qotwSubmissionRepository.getSubmissionByThreadId(submissionThread.getIdLong());
50-
submissionOptional.ifPresent(submission -> guild.getJDA().retrieveUserById(submission.getAuthorId()).queue(author -> {
51-
notificationService.withGuild(guild).sendToModerationLog(c -> c.sendMessageEmbeds(buildSubmissionActionEmbed(author, submissionThread, reviewedBy, status, reasons)));
52-
log.info("{} {} {}'s QOTW Submission{}", reviewedBy.getAsTag(), status.name().toLowerCase(), author.getAsTag(), reasons != null ? " for: " + String.join(", ", reasons) : ".");
53-
}));
54-
}catch (DataAccessException e) {
55-
ExceptionLogger.capture(e, QOTWGuildNotificationService.class.getSimpleName());
56-
}
37+
public void sendSubmissionActionNotification(User reviewedBy, @NotNull QOTWSubmission submission, SubmissionStatus status) {
38+
submission.retrieveAuthor(author -> {
39+
notificationService.withGuild(guild).sendToModerationLog(c -> c.sendMessageEmbeds(buildSubmissionActionEmbed(author, submission.getThread(), reviewedBy, status)));
40+
log.info("{} {} {}'s QOTW Submission", reviewedBy.getAsTag(), status.getVerb(), author.getAsTag());
5741
});
5842
}
5943

60-
private @NotNull MessageEmbed buildSubmissionActionEmbed(@NotNull User author, ThreadChannel thread, @NotNull User reviewedBy, @NotNull SubmissionStatus status, String... reasons) {
44+
private @NotNull MessageEmbed buildSubmissionActionEmbed(@NotNull User author, ThreadChannel thread, @NotNull User reviewedBy, @NotNull SubmissionStatus status) {
6145
EmbedBuilder builder = new EmbedBuilder()
6246
.setAuthor(reviewedBy.getAsTag(), null, reviewedBy.getEffectiveAvatarUrl())
63-
.setTitle(String.format("%s %s %s's QOTW Submission", reviewedBy.getAsTag(), status.name().toLowerCase(), author.getAsTag()))
47+
.setTitle(String.format("%s %s %s's QOTW Submission", reviewedBy.getAsTag(), status.getVerb(), author.getAsTag()))
6448
.setTimestamp(Instant.now());
65-
if (thread != null && status != SubmissionStatus.DELETED) {
49+
if (thread != null) {
6650
builder.addField("Thread", thread.getAsMention(), true);
6751
}
68-
if (reasons != null && reasons.length > 0) {
69-
builder.addField("Reason(s)", String.join(", ", reasons), true);
70-
}
7152
return builder.build();
7253
}
7354
}

src/main/java/net/javadiscord/javabot/systems/notification/QOTWNotificationService.java

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,11 @@
88
import net.javadiscord.javabot.data.config.SystemsConfig;
99
import net.javadiscord.javabot.systems.qotw.QOTWPointsService;
1010
import net.javadiscord.javabot.systems.qotw.model.QOTWAccount;
11-
import net.javadiscord.javabot.systems.qotw.submissions.dao.QOTWSubmissionRepository;
1211
import net.javadiscord.javabot.util.Responses;
1312
import org.jetbrains.annotations.NotNull;
1413
import org.springframework.dao.DataAccessException;
1514

16-
import javax.annotation.Nonnull;
1715
import java.time.Instant;
18-
import java.util.concurrent.ExecutorService;
1916

2017
/**
2118
* An extension of {@link QOTWGuildNotificationService} which also handles user qotw
@@ -28,8 +25,8 @@ public final class QOTWNotificationService extends QOTWGuildNotificationService
2825
private final QOTWAccount account;
2926
private final SystemsConfig systemsConfig;
3027

31-
QOTWNotificationService(NotificationService notificationService, QOTWPointsService pointsService,@NotNull User user, Guild guild, SystemsConfig systemsConfig, ExecutorService asyncPool, QOTWSubmissionRepository qotwSubmissionRepository) {
32-
super(notificationService, guild, asyncPool, qotwSubmissionRepository);
28+
QOTWNotificationService(NotificationService notificationService, QOTWPointsService pointsService,@NotNull User user, Guild guild, SystemsConfig systemsConfig) {
29+
super(notificationService, guild);
3330
this.user = user;
3431
this.guild = guild;
3532
QOTWAccount account;
@@ -51,8 +48,8 @@ public void sendAccountIncrementedNotification() {
5148
notificationService.withUser(user).sendDirectMessage(c -> c.sendMessageEmbeds(buildAccountIncrementEmbed(account.getPoints())));
5249
}
5350

54-
public void sendSubmissionDeclinedEmbed(@Nonnull String reason) {
55-
notificationService.withUser(user).sendDirectMessage(c -> c.sendMessageEmbeds(buildSubmissionDeclinedEmbed(reason)));
51+
public void sendSubmissionDeclinedEmbed() {
52+
notificationService.withUser(user).sendDirectMessage(c -> c.sendMessageEmbeds(buildSubmissionDeclinedEmbed()));
5653
}
5754

5855
private @NotNull EmbedBuilder buildQOTWNotificationEmbed() {
@@ -83,16 +80,14 @@ public void sendSubmissionDeclinedEmbed(@Nonnull String reason) {
8380
.build();
8481
}
8582

86-
private @NotNull MessageEmbed buildSubmissionDeclinedEmbed(String reasons) {
83+
private @NotNull MessageEmbed buildSubmissionDeclinedEmbed() {
8784
return this.buildQOTWNotificationEmbed()
8885
.setColor(Responses.Type.ERROR.getColor())
8986
.setDescription(String.format("""
9087
Hey %s,
91-
Your QOTW-Submission was **declined** for the following reasons:
92-
**`%s`**
93-
88+
Your QOTW-Submission was **declined**.
9489
However, you can try your luck again next week!""",
95-
user.getAsMention(), reasons))
90+
user.getAsMention()))
9691
.build();
9792
}
9893
}

0 commit comments

Comments
 (0)