diff --git a/application/src/main/java/org/togetherjava/tjbot/features/help/HelpThreadAutoArchiver.java b/application/src/main/java/org/togetherjava/tjbot/features/help/HelpThreadAutoArchiver.java index 41792957ff..74f657829f 100644 --- a/application/src/main/java/org/togetherjava/tjbot/features/help/HelpThreadAutoArchiver.java +++ b/application/src/main/java/org/togetherjava/tjbot/features/help/HelpThreadAutoArchiver.java @@ -8,6 +8,7 @@ import net.dv8tion.jda.api.entities.MessageEmbed; import net.dv8tion.jda.api.entities.channel.concrete.ForumChannel; import net.dv8tion.jda.api.entities.channel.concrete.ThreadChannel; +import net.dv8tion.jda.api.interactions.components.buttons.Button; import net.dv8tion.jda.api.requests.RestAction; import net.dv8tion.jda.api.utils.TimeUtil; import org.slf4j.Logger; @@ -88,8 +89,8 @@ private void autoArchiveForThread(ThreadChannel threadChannel) { """ Your question has been closed due to inactivity. - If it was not resolved yet, feel free to just post a message below - to reopen it, or create a new thread. + If it was not resolved yet, **click the button below** to keep it + open, or feel free to create a new thread. Note that usually the reason for nobody calling back is that your question may have been not well asked and hence no one felt confident @@ -128,41 +129,48 @@ private void handleArchiveFlow(ThreadChannel threadChannel, MessageEmbed embed) () -> triggerAuthorIdNotFoundArchiveFlow(threadChannel, embed)); } - private void triggerArchiveFlow(ThreadChannel threadChannel, long authorId, - MessageEmbed embed) { + private void triggerArchiveFlow(ThreadChannel threadChannel, long authorId, MessageEmbed embed) { + // --- UPDATED: Added ActionRow with custom namespace ID --- Function> sendEmbedWithMention = - member -> threadChannel.sendMessage(member.getAsMention()).addEmbeds(embed); + member -> threadChannel.sendMessage(member.getAsMention()) + .addEmbeds(embed) + .addActionRow(Button.primary("OTHER:thread-inactivity:mark-active", "Mark Active")); Supplier> sendEmbedWithoutMention = - () -> threadChannel.sendMessageEmbeds(embed); + () -> threadChannel.sendMessageEmbeds(embed) + .addActionRow(Button.primary("OTHER:thread-inactivity:mark-active", "Mark Active")); + // --------------------------------------------------------- threadChannel.getGuild() - .retrieveMemberById(authorId) - .mapToResult() - .flatMap(authorResults -> { - if (authorResults.isFailure()) { - logger.info( - "Trying to archive a thread ({}), but OP ({}) left the server, sending embed without mention", - threadChannel.getId(), authorId, authorResults.getFailure()); - - return sendEmbedWithoutMention.get(); - } - - return sendEmbedWithMention.apply(authorResults.get()); - }) - .flatMap(_ -> threadChannel.getManager().setArchived(true)) - .queue(); + .retrieveMemberById(authorId) + .mapToResult() + .flatMap(authorResults -> { + if (authorResults.isFailure()) { + logger.info( + "Trying to archive a thread ({}), but OP ({}) left the server, sending embed without mention", + threadChannel.getId(), authorId, authorResults.getFailure()); + + return sendEmbedWithoutMention.get(); + } + + return sendEmbedWithMention.apply(authorResults.get()); + }) + .flatMap(_ -> threadChannel.getManager().setArchived(true)) + .queue(); } - private void triggerAuthorIdNotFoundArchiveFlow(ThreadChannel threadChannel, - MessageEmbed embed) { + private void triggerAuthorIdNotFoundArchiveFlow(ThreadChannel threadChannel, MessageEmbed embed) { logger.info( "Was unable to find a matching thread for id: {} in DB, archiving thread without mentioning OP", threadChannel.getId()); + + // --- UPDATED: Added ActionRow with custom namespace ID --- threadChannel.sendMessageEmbeds(embed) - .flatMap(sentEmbed -> threadChannel.getManager().setArchived(true)) - .queue(); + .addActionRow(Button.primary("OTHER:thread-inactivity:mark-active", "Mark Active")) + .flatMap(sentEmbed -> threadChannel.getManager().setArchived(true)) + .queue(); + // --------------------------------------------- } } diff --git a/application/src/main/java/org/togetherjava/tjbot/features/help/HelpThreadCreatedListener.java b/application/src/main/java/org/togetherjava/tjbot/features/help/HelpThreadCreatedListener.java index bbf8490a2c..e012626419 100644 --- a/application/src/main/java/org/togetherjava/tjbot/features/help/HelpThreadCreatedListener.java +++ b/application/src/main/java/org/togetherjava/tjbot/features/help/HelpThreadCreatedListener.java @@ -47,6 +47,10 @@ public final class HelpThreadCreatedListener extends ListenerAdapter private static final Logger log = LoggerFactory.getLogger(HelpThreadCreatedListener.class); private final HelpSystemHelper helper; + private static final String MARK_ACTIVE_ID = "mark-active"; + private final ComponentIdInteractor inactivityInteractor = + new ComponentIdInteractor(UserInteractionType.OTHER, "thread-inactivity"); + private final Cache threadIdToCreatedAtCache = Caffeine.newBuilder() .maximumSize(1_000) .expireAfterAccess(2, TimeUnit.of(ChronoUnit.MINUTES)) @@ -187,7 +191,16 @@ private Consumer handleParentMessageDeleted(Member user, ThreadChanne @Override public void onButtonClick(ButtonInteractionEvent event, List args) { - // This method handles chatgpt's automatic response "dismiss" button + // Check if the button belongs to the "thread-inactivity" namespace + if (inactivityInteractor.isMatch(event.getComponentId())) { + String subId = inactivityInteractor.getComponentId(event.getComponentId()); + + if (subId.equals("mark-active")) { + handleMarkActiveInteraction(event); + return; // EXIT: This logic is owned by handleMarkActiveInteraction + } + } + // Handle chatgpt's automatic response "dismiss" button event.deferEdit().queue(); ThreadChannel channel = event.getChannel().asThreadChannel(); @@ -248,4 +261,17 @@ private void registerThreadDataInDB(Message message, ThreadChannel threadChannel helper.writeHelpThreadToDatabase(authorId, threadChannel); } + + private void handleMarkActiveInteraction(ButtonInteractionEvent event) { + event.deferEdit().queue(); + + if (event.getChannel() instanceof ThreadChannel thread) { + // Reopen the thread so people can chat, then delete the bot's warning + thread.getManager().setArchived(false).queue(); + event.getMessage().delete().queue(); + + log.info("Thread {} was manually reactivated via button by {}", + thread.getId(), event.getUser().getName()); + } + } }