From 1648d8a884af16aa331f3e4f2e2991a71d9fade8 Mon Sep 17 00:00:00 2001 From: Zabuzard Date: Thu, 1 Sep 2022 21:11:07 +0200 Subject: [PATCH] Auto posting advice on uncategorized help threads * after 5 mins --- .../togetherjava/tjbot/commands/Features.java | 2 +- .../tjbot/commands/help/HelpSystemHelper.java | 57 ++++++++++++++++++- .../commands/help/ImplicitAskListener.java | 7 ++- 3 files changed, 63 insertions(+), 3 deletions(-) diff --git a/application/src/main/java/org/togetherjava/tjbot/commands/Features.java b/application/src/main/java/org/togetherjava/tjbot/commands/Features.java index c348b607f8..7b71f93443 100644 --- a/application/src/main/java/org/togetherjava/tjbot/commands/Features.java +++ b/application/src/main/java/org/togetherjava/tjbot/commands/Features.java @@ -64,7 +64,7 @@ public static Collection createFeatures(JDA jda, Database database, Con ModerationActionsStore actionsStore = new ModerationActionsStore(database); ModAuditLogWriter modAuditLogWriter = new ModAuditLogWriter(config); ScamHistoryStore scamHistoryStore = new ScamHistoryStore(database); - HelpSystemHelper helpSystemHelper = new HelpSystemHelper(config, database); + HelpSystemHelper helpSystemHelper = new HelpSystemHelper(jda, config, database); // NOTE The system can add special system relevant commands also by itself, // hence this list may not necessarily represent the full list of all commands actually diff --git a/application/src/main/java/org/togetherjava/tjbot/commands/help/HelpSystemHelper.java b/application/src/main/java/org/togetherjava/tjbot/commands/help/HelpSystemHelper.java index 43531b326c..23bf93705f 100644 --- a/application/src/main/java/org/togetherjava/tjbot/commands/help/HelpSystemHelper.java +++ b/application/src/main/java/org/togetherjava/tjbot/commands/help/HelpSystemHelper.java @@ -1,6 +1,8 @@ package org.togetherjava.tjbot.commands.help; import net.dv8tion.jda.api.EmbedBuilder; +import net.dv8tion.jda.api.JDA; +import net.dv8tion.jda.api.MessageBuilder; import net.dv8tion.jda.api.entities.*; import net.dv8tion.jda.api.requests.RestAction; import net.dv8tion.jda.api.requests.restaction.MessageAction; @@ -19,6 +21,9 @@ import java.util.List; import java.util.Locale; import java.util.Optional; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; import java.util.function.Consumer; import java.util.function.Predicate; import java.util.regex.Matcher; @@ -46,20 +51,26 @@ public final class HelpSystemHelper { static final int TITLE_COMPACT_LENGTH_MIN = 2; static final int TITLE_COMPACT_LENGTH_MAX = 70; + private static final ScheduledExecutorService SERVICE = Executors.newScheduledThreadPool(3); + private static final int SEND_UNCATEGORIZED_ADVICE_AFTER_MINUTES = 5; + private final Predicate isOverviewChannelName; private final String overviewChannelPattern; private final Predicate isStagingChannelName; private final String stagingChannelPattern; private final String categoryRoleSuffix; private final Database database; + private final JDA jda; /** * Creates a new instance. * + * @param jda the JDA instance to use * @param config the config to use * @param database the database to store help thread metadata in */ - public HelpSystemHelper(Config config, Database database) { + public HelpSystemHelper(JDA jda, Config config, Database database) { + this.jda = jda; HelpSystemConfig helpConfig = config.getHelpSystem(); this.database = database; @@ -239,6 +250,50 @@ List getActiveThreadsIn(TextChannel channel) { .toList(); } + void scheduleUncategorizedAdviceCheck(long threadChannelId, long authorId) { + SERVICE.schedule(() -> { + try { + executeUncategorizedAdviceCheck(threadChannelId, authorId); + } catch (Exception e) { + logger.warn( + "Unknown error during an uncategorized advice check on thread {} by author {}.", + threadChannelId, authorId, e); + } + }, SEND_UNCATEGORIZED_ADVICE_AFTER_MINUTES, TimeUnit.MINUTES); + } + + private void executeUncategorizedAdviceCheck(long threadChannelId, long authorId) { + logger.debug("Executing uncategorized advice check for thread {} by author {}.", + threadChannelId, authorId); + jda.retrieveUserById(authorId).flatMap(author -> { + ThreadChannel threadChannel = jda.getThreadChannelById(threadChannelId); + if (threadChannel == null) { + logger.debug( + "Channel for uncategorized advice check seems to be deleted (thread {} by author {}).", + threadChannelId, authorId); + return new CompletedRestAction<>(jda, null); + } + + Optional category = getCategoryOfChannel(threadChannel); + if (category.isPresent()) { + logger.debug( + "Channel for uncategorized advice check seems to have a category now (thread {} by author {}).", + threadChannelId, authorId); + return new CompletedRestAction<>(jda, null); + } + + // Still no category, send advice + MessageEmbed embed = HelpSystemHelper.embedWith( + """ + Hey there 👋 You have to select a category for your help thread, otherwise nobody can see your question. + Please use the `/change-help-category` slash-command and pick what fits best, thanks 🙂 + """); + Message message = new MessageBuilder(author.getAsMention()).setEmbeds(embed).build(); + + return threadChannel.sendMessage(message); + }).queue(); + } + record HelpThreadName(@Nullable ThreadActivity activity, @Nullable String category, String title) { static HelpThreadName ofChannelName(CharSequence channelName) { diff --git a/application/src/main/java/org/togetherjava/tjbot/commands/help/ImplicitAskListener.java b/application/src/main/java/org/togetherjava/tjbot/commands/help/ImplicitAskListener.java index fa84b9fb7a..46086246cb 100644 --- a/application/src/main/java/org/togetherjava/tjbot/commands/help/ImplicitAskListener.java +++ b/application/src/main/java/org/togetherjava/tjbot/commands/help/ImplicitAskListener.java @@ -162,7 +162,12 @@ private RestAction handleEvent(ThreadChannel threadChannel, Message message, return sendInitialMessage(threadChannel, message, title) .flatMap(any -> notifyUser(threadChannel, message)) .flatMap(any -> message.delete()) - .flatMap(any -> helper.sendExplanationMessage(threadChannel)); + .flatMap(any -> helper.sendExplanationMessage(threadChannel)) + .map(any -> { + helper.scheduleUncategorizedAdviceCheck(threadChannel.getIdLong(), + author.getIdLong()); + return null; + }); } private static MessageAction sendInitialMessage(ThreadChannel threadChannel,