From 9e605d4d7a03ed8a18d758eb031fcaed6fac14ed Mon Sep 17 00:00:00 2001 From: Ankit Yadav Date: Sat, 31 Jan 2026 00:33:39 +0530 Subject: [PATCH 1/2] fix: AI message dismiss button when message that created thread was deleted, retrieveStartMessage() threw an error UNKNOWN_MESSAGE leading to non-functional dismiss button. this adds a handler, specifically for parent message deleted error by using getIterableHistoryInstead. --- .../help/HelpThreadCreatedListener.java | 23 ++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) 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 cd453eab63..f2f9bd9294 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 @@ -12,8 +12,12 @@ import net.dv8tion.jda.api.entities.channel.forums.ForumTag; import net.dv8tion.jda.api.events.interaction.component.ButtonInteractionEvent; import net.dv8tion.jda.api.events.message.MessageReceivedEvent; +import net.dv8tion.jda.api.exceptions.ErrorResponseException; import net.dv8tion.jda.api.hooks.ListenerAdapter; +import net.dv8tion.jda.api.requests.ErrorResponse; import net.dv8tion.jda.api.requests.RestAction; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.togetherjava.tjbot.features.EventReceiver; import org.togetherjava.tjbot.features.UserInteractionType; @@ -28,8 +32,10 @@ import java.util.List; import java.util.Objects; import java.util.concurrent.TimeUnit; +import java.util.function.Consumer; import java.util.stream.Collectors; + /** * Listens for new help threads being created. That is, a user posted a question in the help forum. *

@@ -38,6 +44,7 @@ */ public final class HelpThreadCreatedListener extends ListenerAdapter implements EventReceiver, UserInteractor { + private static final Logger log = LoggerFactory.getLogger(HelpThreadCreatedListener.class); private final HelpSystemHelper helper; private final Cache threadIdToCreatedAtCache = Caffeine.newBuilder() @@ -46,6 +53,7 @@ public final class HelpThreadCreatedListener extends ListenerAdapter .build(); private final ComponentIdInteractor componentIdInteractor = new ComponentIdInteractor(getInteractionType(), getName()); + private static final int FIRST_MESSAGE_ONLY = 1; /** * Creates a new instance. @@ -167,9 +175,22 @@ public void onButtonClick(ButtonInteractionEvent event, List args) { ThreadChannel channel = event.getChannel().asThreadChannel(); Member interactionUser = Objects.requireNonNull(event.getMember()); + Consumer handleParentMessageDeleted = error -> { + if (error instanceof ErrorResponseException ere + && ere.getErrorResponse() == ErrorResponse.UNKNOWN_MESSAGE) { + channel.getIterableHistory().reverse().limit(FIRST_MESSAGE_ONLY).queue(messages -> { + if (!messages.isEmpty()) { + handleDismiss(interactionUser, channel, messages.getFirst(), event, args); + } + }); + } else { + log.error("Failed to retrieve start message: ", error); + } + }; + channel.retrieveStartMessage() .queue(forumPostMessage -> handleDismiss(interactionUser, channel, forumPostMessage, - event, args)); + event, args), handleParentMessageDeleted); } From a8cfa134ae119ee482a1f3ed121ff9a916d0d7cf Mon Sep 17 00:00:00 2001 From: Ankit Yadav Date: Tue, 3 Feb 2026 00:11:04 +0530 Subject: [PATCH 2/2] refactor: HelpThreadCreatedListener * move AI dismiss fallback consumer to a seperate function for clarity * move variable FIRST_MESSAGE_ONLY to function scope as noOfMessage for clarity * improve error log message for clarity --- .../help/HelpThreadCreatedListener.java | 34 +++++++++++-------- 1 file changed, 20 insertions(+), 14 deletions(-) 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 f2f9bd9294..bbf8490a2c 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 @@ -53,7 +53,6 @@ public final class HelpThreadCreatedListener extends ListenerAdapter .build(); private final ComponentIdInteractor componentIdInteractor = new ComponentIdInteractor(getInteractionType(), getName()); - private static final int FIRST_MESSAGE_ONLY = 1; /** * Creates a new instance. @@ -167,30 +166,37 @@ public void acceptComponentIdGenerator(ComponentIdGenerator generator) { componentIdInteractor.acceptComponentIdGenerator(generator); } - @Override - public void onButtonClick(ButtonInteractionEvent event, List args) { - // This method handles chatgpt's automatic response "dismiss" button - event.deferEdit().queue(); - - ThreadChannel channel = event.getChannel().asThreadChannel(); - Member interactionUser = Objects.requireNonNull(event.getMember()); - - Consumer handleParentMessageDeleted = error -> { + private Consumer handleParentMessageDeleted(Member user, ThreadChannel channel, + ButtonInteractionEvent event, List args) { + int noOfMessages = 1; // we only care about first message from channel history + return error -> { if (error instanceof ErrorResponseException ere && ere.getErrorResponse() == ErrorResponse.UNKNOWN_MESSAGE) { - channel.getIterableHistory().reverse().limit(FIRST_MESSAGE_ONLY).queue(messages -> { + channel.getIterableHistory().reverse().limit(noOfMessages).queue(messages -> { if (!messages.isEmpty()) { - handleDismiss(interactionUser, channel, messages.getFirst(), event, args); + handleDismiss(user, channel, messages.getFirst(), event, args); } }); } else { - log.error("Failed to retrieve start message: ", error); + log.error( + "Trying to dismiss AI help message for thread: {}, unable to find original message.", + channel.getId(), error); } }; + } + + @Override + public void onButtonClick(ButtonInteractionEvent event, List args) { + // This method handles chatgpt's automatic response "dismiss" button + event.deferEdit().queue(); + + ThreadChannel channel = event.getChannel().asThreadChannel(); + Member interactionUser = Objects.requireNonNull(event.getMember()); channel.retrieveStartMessage() .queue(forumPostMessage -> handleDismiss(interactionUser, channel, forumPostMessage, - event, args), handleParentMessageDeleted); + event, args), + handleParentMessageDeleted(interactionUser, channel, event, args)); }