Skip to content

Commit 5340c80

Browse files
Merge pull request #378 from Java-Discord/dynxsty/post_based_help
Remove Text-based Help System & further improve the Forum-based Help System
2 parents 5443214 + cda22f5 commit 5340c80

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+328
-2022
lines changed

src/main/java/net/javadiscord/javabot/data/config/GuildConfig.java

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ public class GuildConfig {
3131
private transient Path file;
3232

3333
private HelpConfig helpConfig;
34-
private HelpForumConfig helpForumConfig;
3534
private ModerationConfig moderationConfig;
3635
private QOTWConfig qotwConfig;
3736
private MetricsConfig metricsConfig;
@@ -49,7 +48,6 @@ public GuildConfig(Guild guild, Path file) {
4948
this.file = file;
5049
// Initialize all config items.
5150
this.helpConfig = new HelpConfig();
52-
this.helpForumConfig = new HelpForumConfig();
5351
this.moderationConfig = new ModerationConfig();
5452
this.qotwConfig = new QOTWConfig();
5553
this.metricsConfig = new MetricsConfig();
@@ -97,8 +95,6 @@ private void setGuild(Guild guild) {
9795
this.guild = guild;
9896
if (this.helpConfig == null) this.helpConfig = new HelpConfig();
9997
this.helpConfig.setGuildConfig(this);
100-
if (this.helpForumConfig == null) this.helpForumConfig = new HelpForumConfig();
101-
this.helpForumConfig.setGuildConfig(this);
10298
if (this.moderationConfig == null) this.moderationConfig = new ModerationConfig();
10399
this.moderationConfig.setGuildConfig(this);
104100
if (this.qotwConfig == null) this.qotwConfig = new QOTWConfig();

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

Lines changed: 14 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,9 @@
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.Category;
6+
import net.dv8tion.jda.api.entities.channel.concrete.ForumChannel;
77
import net.javadiscord.javabot.data.config.GuildConfigItem;
8-
import net.javadiscord.javabot.systems.help.naming_strategies.*;
98

10-
import java.util.List;
119
import java.util.Map;
1210

1311
/**
@@ -21,21 +19,7 @@ public class HelpConfig extends GuildConfigItem {
2119
*/
2220
private Map<String, Long> helpOverviewMessageIds = Map.of();
2321

24-
/**
25-
* The id of the channel category that contains all open channels.
26-
*/
27-
private long openCategoryId;
28-
29-
/**
30-
* The id of the channel category that contains all reserved channels.
31-
*/
32-
private long reservedCategoryId;
33-
34-
/**
35-
* The id of the channel category where dormant channels are put when they
36-
* aren't needed in the open category (due to preferred channel count).
37-
*/
38-
private long dormantCategoryId;
22+
private long helpForumChannelId = 0;
3923

4024
/**
4125
* The id of the helper role.
@@ -47,89 +31,34 @@ public class HelpConfig extends GuildConfigItem {
4731
*/
4832
private long helpPingRoleId;
4933

50-
/**
51-
* The strategy to use when naming help channels. This is only used when
52-
* {@link HelpConfig#recycleChannels} is set to false.
53-
*/
54-
private String channelNamingStrategy = "animal";
55-
56-
/**
57-
* If true, the system will manage a fixed set of help channels which are
58-
* created in advance. If false, the system will create and remove channels
59-
* as needed to maintain the {@link HelpConfig#preferredOpenChannelCount}.
60-
* Note that if this is true, the preferred open channel count is ignored.
61-
*/
62-
private boolean recycleChannels = false;
63-
64-
/**
65-
* The string which is shown as the 'topic' for open channels.
66-
*/
67-
private String openChannelTopic = "Ask your question here!";
68-
69-
/**
70-
* The message that's sent in a recycled help channel to tell users that it
71-
* is now open for someone to ask a question.
72-
*/
73-
private String reopenedChannelMessage = "`✅` **This channel is now available!**\n> This channel is no longer reserved. Feel free to ask your question here!";
74-
7534
/**
7635
* The message that's sent as soon as a user asks a question in an open help
7736
* channel. This is only sent if it's not null.
7837
*/
79-
private String reservedChannelMessage = "`⌛` **This channel has been reserved for your question.**\n> Please use `/unreserve` when you\u0027re finished.";
38+
private String reservedChannelMessageTemplate = "`⌛` **This post has been reserved for your question.**\n> Hey %s! Please use `/close` or the `Close Post` button above when you're finished. Please remember to follow the help guidelines. This post will be automatically closed after %s minutes of inactivity.\n\n**TIP:** Narrow down your issue to __simple__ and __precise__ questions to maximize the chance that others will reply in here.";
8039

8140
/**
82-
* The message that's sent in a recycled help channel to tell users that it
41+
* The message that's sent in a post to tell users that it
8342
* is now marked as dormant and no more messages can be sent.
8443
*/
85-
private String dormantChannelMessage = "`\uD83D\uDCA4` **Channel marked as dormant**\n> It is no longer possible to send messages in this channel until it becomes available again.\n> If your question was not answered yet, feel free to claim a new available help channel.";
44+
private String dormantChannelMessageTemplate = "`\uD83D\uDCA4` **Post marked as dormant**\n> This post has been inactive for over %s minutes, thus, it has been **archived**.\n> If your question was not answered yet, feel free to re-open this post or create a new one.";
8645

8746
/**
88-
* The number of open help channels to maintain. If fewer than this many
89-
* open channels exist, the system will try to create more.
47+
* The message that's sent when a user unreserved a channel where other users
48+
* participated in.
9049
*/
91-
private int preferredOpenChannelCount = 3;
92-
93-
/**
94-
* A list of successive timeouts (in minutes) to use when checking to see if
95-
* a help channel is still active. The bot waits X minutes since the last
96-
* human message before sending an activity check, and waits
97-
*/
98-
private List<Integer> inactivityTimeouts = List.of(30, 60, 120, 180);
50+
private String helpThanksMessageTemplate = "Before your post will be closed, would you like to express your gratitude to any of the people who helped you? When you're done, click **I'm done here. Close this post!**.";
9951

10052
/**
10153
* The number of minutes of inactivity before a channel is considered inactive.
10254
*/
103-
private int inactivityTimeoutMinutes = 30;
104-
105-
/**
106-
* The number of minutes to wait before closing an inactive channel. An
107-
* inactive channel is one in which the most recent message is an unanswered
108-
* activity check that was sent by this bot.
109-
*/
110-
private int removeInactiveTimeoutMinutes = 60;
55+
private int inactivityTimeoutMinutes = 300;
11156

11257
/**
11358
* The number of minutes to wait before closing a channel waiting for a response
11459
* to a thanks question.
11560
*/
116-
private int removeThanksTimeoutMinutes = 15;
117-
118-
/**
119-
* The number of seconds to wait between each help channel update check.
120-
*/
121-
private long updateIntervalSeconds = 60;
122-
123-
/**
124-
* The number of channels which can be reserved by a single user at any time.
125-
*/
126-
private int maxReservedChannelsPerUser = 3;
127-
128-
/**
129-
* The message which is sent to users who aren't allowed to reserve a help
130-
* channel.
131-
*/
132-
private String reservationNotAllowedMessage = "You are not allowed to reserve this help channel. Please try again later.";
61+
private int removeThanksTimeoutMinutes = 10;
13362

13463
/**
13564
* How often users may use the /help-ping command.
@@ -176,33 +105,15 @@ public class HelpConfig extends GuildConfigItem {
176105
*/
177106
private Map<Long, Double> experienceRoles = Map.of(0L, 0.0);
178107

179-
public Category getOpenChannelCategory() {
180-
return getGuild().getCategoryById(this.openCategoryId);
181-
}
182-
183-
public Category getReservedChannelCategory() {
184-
return getGuild().getCategoryById(this.reservedCategoryId);
185-
}
186-
187-
public Category getDormantChannelCategory() {
188-
return getGuild().getCategoryById(this.dormantCategoryId);
108+
public ForumChannel getHelpForumChannel() {
109+
return getGuild().getForumChannelById(helpForumChannelId);
189110
}
190111

191112
public Role getHelperRole() {
192-
return this.getGuild().getRoleById(this.helperRoleId);
113+
return getGuild().getRoleById(helperRoleId);
193114
}
194115

195116
public Role getHelpPingRole() {
196-
return this.getGuild().getRoleById(this.helpPingRoleId);
197-
}
198-
199-
public ChannelNamingStrategy getChannelNamingStrategy() {
200-
return switch (this.channelNamingStrategy) {
201-
case "alphabet" -> new AlphabetNamingStrategy();
202-
case "greek" -> new GreekAlphabetNamingStrategy();
203-
case "animal" -> new AnimalNamingStrategy();
204-
case "coffee" -> new CoffeeNamingStrategy();
205-
default -> throw new IllegalArgumentException("Invalid channel naming strategy.");
206-
};
117+
return getGuild().getRoleById(helpPingRoleId);
207118
}
208119
}

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

Lines changed: 0 additions & 22 deletions
This file was deleted.

src/main/java/net/javadiscord/javabot/listener/StateListener.java

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,8 @@
1212
import net.dv8tion.jda.api.hooks.ListenerAdapter;
1313
import net.javadiscord.javabot.annotations.PreRegisteredListener;
1414
import net.javadiscord.javabot.data.config.BotConfig;
15-
import net.javadiscord.javabot.data.config.guild.HelpConfig;
1615
import net.javadiscord.javabot.data.h2db.DbActions;
17-
import net.javadiscord.javabot.systems.help.ChannelSemanticCheck;
18-
import net.javadiscord.javabot.systems.help.HelpChannelUpdater;
16+
import net.javadiscord.javabot.systems.help.checks.ChannelSemanticCheck;
1917
import net.javadiscord.javabot.systems.help.HelpExperienceService;
2018
import net.javadiscord.javabot.systems.notification.NotificationService;
2119
import net.javadiscord.javabot.systems.staff_commands.tags.CustomTagManager;
@@ -27,7 +25,6 @@
2725
import java.time.Instant;
2826
import java.util.List;
2927
import java.util.concurrent.ScheduledExecutorService;
30-
import java.util.concurrent.TimeUnit;
3128
import java.util.stream.Collectors;
3229

3330
/**
@@ -53,14 +50,6 @@ public void onReady(@NotNull ReadyEvent event) {
5350
log.info("Logged in as " + event.getJDA().getSelfUser().getAsTag());
5451
log.info("Guilds: " + event.getJDA().getGuilds().stream().map(Guild::getName).collect(Collectors.joining(", ")));
5552
for (Guild guild : event.getJDA().getGuilds()) {
56-
// Schedule the help channel updater to run periodically for each guild.
57-
HelpConfig helpConfig = botConfig.get(guild).getHelpConfig();
58-
asyncPool.scheduleAtFixedRate(
59-
new HelpChannelUpdater(guild, botConfig, dbActions, asyncPool, channelSemanticChecks, helpExperienceService),
60-
5,
61-
helpConfig.getUpdateIntervalSeconds(),
62-
TimeUnit.SECONDS
63-
);
6453
notificationService.withGuild(guild).sendToModerationLog(c -> c.sendMessageEmbeds(buildBootedUpEmbed()));
6554
}
6655
try {
Lines changed: 27 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,36 @@
11
package net.javadiscord.javabot.listener;
22

3+
import lombok.extern.slf4j.Slf4j;
34
import net.dv8tion.jda.api.entities.Guild;
45
import net.dv8tion.jda.api.entities.User;
5-
import net.dv8tion.jda.api.entities.channel.concrete.TextChannel;
6+
import net.dv8tion.jda.api.entities.UserSnowflake;
7+
import net.dv8tion.jda.api.entities.channel.concrete.ForumChannel;
8+
import net.dv8tion.jda.api.entities.channel.concrete.ThreadChannel;
69
import net.dv8tion.jda.api.events.guild.member.GuildMemberRemoveEvent;
710
import net.dv8tion.jda.api.hooks.ListenerAdapter;
811
import net.javadiscord.javabot.data.config.BotConfig;
9-
import net.javadiscord.javabot.data.h2db.DbActions;
10-
import net.javadiscord.javabot.systems.help.HelpChannelManager;
11-
import net.javadiscord.javabot.systems.help.HelpExperienceService;
12-
import net.javadiscord.javabot.util.ExceptionLogger;
13-
14-
import java.sql.SQLException;
15-
import java.util.concurrent.ScheduledExecutorService;
1612

1713
import lombok.RequiredArgsConstructor;
14+
import net.javadiscord.javabot.data.config.guild.HelpConfig;
15+
import net.javadiscord.javabot.data.h2db.DbActions;
16+
import net.javadiscord.javabot.systems.help.HelpManager;
17+
import net.javadiscord.javabot.systems.help.dao.HelpAccountRepository;
18+
import net.javadiscord.javabot.systems.help.dao.HelpTransactionRepository;
19+
import org.jetbrains.annotations.NotNull;
1820

1921
/**
2022
* Listens for the {@link GuildMemberRemoveEvent}.
2123
*/
24+
@Slf4j
2225
@RequiredArgsConstructor
2326
public class UserLeaveListener extends ListenerAdapter {
24-
private final BotConfig botConfig;
2527
private final DbActions dbActions;
26-
private final ScheduledExecutorService asyncPool;
27-
private final HelpExperienceService helpExperienceService;
28+
private final BotConfig botConfig;
29+
private final HelpAccountRepository helpAccountRepository;
30+
private final HelpTransactionRepository helpTransactionRepository;
2831

2932
@Override
30-
public void onGuildMemberRemove(GuildMemberRemoveEvent event) {
33+
public void onGuildMemberRemove(@NotNull GuildMemberRemoveEvent event) {
3134
if (event.getUser().isBot() || event.getUser().isSystem()) return;
3235
if (!botConfig.get(event.getGuild()).getServerLockConfig().isLocked()) {
3336
unreserveAllChannels(event.getUser(), event.getGuild());
@@ -41,13 +44,18 @@ public void onGuildMemberRemove(GuildMemberRemoveEvent event) {
4144
* @param guild The guild they're leaving.
4245
*/
4346
private void unreserveAllChannels(User user, Guild guild) {
44-
try {
45-
HelpChannelManager manager = new HelpChannelManager(botConfig, guild, dbActions, asyncPool, helpExperienceService);
46-
manager.unreserveAllOwnedChannels(user);
47-
} catch (SQLException e) {
48-
ExceptionLogger.capture(e, getClass().getSimpleName());
49-
TextChannel logChannel = botConfig.get(guild).getModerationConfig().getLogChannel();
50-
logChannel.sendMessage("Database error while unreserving channels for a user who left: " + e.getMessage()).queue();
47+
HelpConfig config = botConfig.get(guild).getHelpConfig();
48+
ForumChannel forum = config.getHelpForumChannel();
49+
if (forum != null) {
50+
for (ThreadChannel post : forum.getThreadChannels()) {
51+
if (post.isArchived() || post.isLocked()) continue;
52+
if (post.getOwnerIdLong() == user.getIdLong()) {
53+
HelpManager manager = new HelpManager(post, dbActions, botConfig, helpAccountRepository, helpTransactionRepository);
54+
manager.close(UserSnowflake.fromId(guild.getSelfMember().getIdLong()), "User left the server");
55+
}
56+
}
57+
} else {
58+
log.warn("Could not find forum channel for guild {}", guild.getName());
5159
}
5260
}
5361
}

0 commit comments

Comments
 (0)