diff --git a/src/main/java/net/discordjug/javabot/data/config/guild/ModerationConfig.java b/src/main/java/net/discordjug/javabot/data/config/guild/ModerationConfig.java index 507d4f5bb..a0d637f78 100644 --- a/src/main/java/net/discordjug/javabot/data/config/guild/ModerationConfig.java +++ b/src/main/java/net/discordjug/javabot/data/config/guild/ModerationConfig.java @@ -16,6 +16,7 @@ @EqualsAndHashCode(callSuper = true) public class ModerationConfig extends GuildConfigItem { private long reportChannelId = 0; + private long reportUserThreadHolderId = 0; private long applicationChannelId = 0; private long logChannelId = 0; private long suggestionChannelId = 0; @@ -90,6 +91,10 @@ public class ModerationConfig extends GuildConfigItem { public TextChannel getReportChannel() { return this.getGuild().getTextChannelById(this.reportChannelId); } + + public TextChannel getReportUserThreadHolder() { + return this.getGuild().getTextChannelById(this.reportUserThreadHolderId); + } public TextChannel getApplicationChannel() { return this.getGuild().getTextChannelById(this.applicationChannelId); diff --git a/src/main/java/net/discordjug/javabot/systems/moderation/report/ReportManager.java b/src/main/java/net/discordjug/javabot/systems/moderation/report/ReportManager.java index 6414a8c01..f8e739a86 100644 --- a/src/main/java/net/discordjug/javabot/systems/moderation/report/ReportManager.java +++ b/src/main/java/net/discordjug/javabot/systems/moderation/report/ReportManager.java @@ -17,6 +17,7 @@ import net.dv8tion.jda.api.EmbedBuilder; import net.dv8tion.jda.api.entities.*; import net.dv8tion.jda.api.entities.channel.Channel; +import net.dv8tion.jda.api.entities.channel.concrete.TextChannel; import net.dv8tion.jda.api.entities.channel.concrete.ThreadChannel; import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel; import net.dv8tion.jda.api.events.interaction.ModalInteractionEvent; @@ -43,14 +44,66 @@ */ @Slf4j @RequiredArgsConstructor -@AutoDetectableComponentHandler({"resolve-report","report"}) +@AutoDetectableComponentHandler({"resolve-report", ReportManager.REPORT_INTERACTION_NAME}) public class ReportManager implements ButtonHandler, ModalHandler { + static final String REPORT_INTERACTION_NAME = "report"; private final BotConfig botConfig; @Override public void handleButton(@NotNull ButtonInteractionEvent event, Button button) { - event.deferReply(true).queue(); String[] id = ComponentIdBuilder.split(event.getComponentId()); + if ("resolve-report".equals(id[0])) { + handleResolveReportButton(event, id); + } else if (REPORT_INTERACTION_NAME.equals(id[0])&&"create-thread".equals(id[1])) { + createReportUserThread(event, id); + }else { + Responses.error(event, "Unexpected button").queue(); + } + } + + private void createReportUserThread(ButtonInteractionEvent event, String[] id) { + TextChannel reportUserChannel = botConfig.get(event.getGuild()) + .getModerationConfig() + .getReportUserThreadHolder(); + ThreadChannel reportThread = event.getGuild().getThreadChannelById(id[2]); + if(reportThread==null) { + Responses.error(event, "This report has been handled already.").queue(); + return; + } + List reportEmbeds = event.getMessage().getEmbeds(); + String title; + if (reportEmbeds.isEmpty()) { + title = "report information"; + } else { + title = reportEmbeds.get(0).getTitle(); + } + reportUserChannel + .createThreadChannel(title, true) + .queue(reporterThread -> { + reporterThread.getManager().setInvitable(false).queue(); + reporterThread + .sendMessage(event.getUser().getAsMention() + + "\nYou can provide additional information regarding your report here.\n" + + "Messages sent in this thread can be seen by staff members but not other users.") + .addEmbeds(reportEmbeds) + .queue(); + reporterThread.addThreadMember(event.getUser()).queue(); + reportThread + .sendMessageEmbeds( + new EmbedBuilder() + .setTitle("Additional information from reporter") + .setDescription("The reporter created a thread for additional information: " + reporterThread.getAsMention() + "\n\n[thread link](" + reporterThread.getJumpUrl() + ")") + .build()) + .queue(); + event.editComponents(ActionRow.of(event.getComponent().asDisabled())).queue(success -> { + Responses.info(event.getHook(), "Information thread created", "The thread "+reporterThread.getAsMention()+" has been created for you. You can provide additional details related to your report there.").queue(); + }); + + }); + } + + private void handleResolveReportButton(ButtonInteractionEvent event, String[] id) { + event.deferReply(true).queue(); ThreadChannel thread = event.getGuild().getThreadChannelById(id[1]); if (thread == null) { Responses.error(event.getHook(), "Could not find the corresponding thread channel.").queue(); @@ -64,7 +117,7 @@ public void handleButton(@NotNull ButtonInteractionEvent event, Button button) { /** * Resolves a report thread. * This closes the current thread. - * Tis method does not check whether the current thread is actually a report thread. + * This method does not check whether the current thread is actually a report thread. * @param resolver the {@link User} responsible for resolving the report * @param reportThread the thread of the report to resolve */ @@ -99,7 +152,7 @@ protected Modal buildUserReportModal(@NotNull UserContextInteractionEvent event) .setMaxLength(MessageEmbed.VALUE_MAX_LENGTH) .build(); String title = "Report " + UserUtils.getUserTag(event.getTarget()); - return Modal.create(ComponentIdBuilder.build("report", "user", event.getTarget().getId()), title.substring(0, Math.min(title.length(), Modal.MAX_TITLE_LENGTH))) + return Modal.create(ComponentIdBuilder.build(REPORT_INTERACTION_NAME, "user", event.getTarget().getId()), title.substring(0, Math.min(title.length(), Modal.MAX_TITLE_LENGTH))) .addActionRow(messageInput) .build(); } @@ -120,7 +173,7 @@ protected Modal buildMessageReportModal(@NotNull MessageContextInteractionEvent TextInput messageInput = TextInput.create("reason", "Report Description", TextInputStyle.PARAGRAPH) .setMaxLength(MessageEmbed.VALUE_MAX_LENGTH) .build(); - return Modal.create(ComponentIdBuilder.build("report", "message", event.getTarget().getId()), title.substring(0, Math.min(title.length(), Modal.MAX_TITLE_LENGTH))) + return Modal.create(ComponentIdBuilder.build(REPORT_INTERACTION_NAME, "message", event.getTarget().getId()), title.substring(0, Math.min(title.length(), Modal.MAX_TITLE_LENGTH))) .addActionRow(messageInput) .build(); } @@ -133,7 +186,7 @@ protected Modal buildMessageReportModal(@NotNull MessageContextInteractionEvent * @param targetId The targeted user's id. * @return The {@link WebhookMessageCreateAction}. */ - protected WebhookMessageCreateAction handleUserReport(InteractionHook hook, @NotNull String reason, String targetId) { + WebhookMessageCreateAction handleUserReport(InteractionHook hook, @NotNull String reason, String targetId) { if (reason.isBlank()) { return Responses.error(hook, "No report reason was provided."); } @@ -147,9 +200,10 @@ protected WebhookMessageCreateAction handleUserReport(InteractionHook h return; } reportChannel.sendMessageEmbeds(embed.build()) - .queue(m -> this.createReportThread(m, target.getIdLong(), config.getModerationConfig())); - embed.setDescription("Successfully reported " + "`" + UserUtils.getUserTag(target) + "`!\nYour report has been send to our Moderators"); - hook.sendMessageEmbeds(embed.build()).queue(); + .queue(m -> this.createReportThread(m, target.getIdLong(), config.getModerationConfig(), + reportThread -> { + sendReportResponse(hook, target, embed, reportThread); + })); }, failure -> { Responses.error(hook, "The user to report seems not to exist any more.").queue(); log.warn("Cannot retrieve user {} when reporting them", targetId, failure); @@ -157,6 +211,15 @@ protected WebhookMessageCreateAction handleUserReport(InteractionHook h return null; } + private void sendReportResponse(InteractionHook hook, User targetUser, EmbedBuilder reportEmbed, ThreadChannel reportThread) { + reportEmbed.setDescription("Successfully reported " + "`" + UserUtils.getUserTag(targetUser) + "`!\nYour report has been send to our Moderators.\nIn case you want to supply additional details, please use the \"Create thread\" button below."); + hook.sendMessageEmbeds(reportEmbed.build()) + .addActionRow(Button.secondary( + ComponentIdBuilder.build(REPORT_INTERACTION_NAME, "create-thread", reportThread.getId()), + "Create thread for providing further details")) + .queue(); + } + private void handleMessageReport(ModalInteractionEvent event, String messageId) { String reason = event.getValue("reason").getAsString(); if (reason.isBlank()) { @@ -170,12 +233,11 @@ private void handleMessageReport(ModalInteractionEvent event, String messageId) embed.addField("Message", String.format("[Jump to Message](%s)", target.getJumpUrl()), false); MessageChannel reportChannel = config.getModerationConfig().getReportChannel(); reportChannel.sendMessageEmbeds(embed.build()).queue(m -> createReportThread(m, target.getAuthor().getIdLong(), config.getModerationConfig(), thread->{ + sendReportResponse(event.getHook(), target.getAuthor(), embed, thread); WebhookUtil.ensureWebhookExists(thread.getParentChannel().asStandardGuildMessageChannel(), wh->{ WebhookUtil.mirrorMessageToWebhook(wh, target, target.getContentRaw(), thread.getIdLong(), null, null); }); })); - embed.setDescription("Successfully reported " + "`" + UserUtils.getUserTag(target.getAuthor()) + "`!\nYour report has been send to our Moderators"); - event.getHook().sendMessageEmbeds(embed.build()).queue(); }, failure -> { Responses.error(event.getHook(), "The author of the message to report seems not to exist any more.").queue(); log.info("Cannot retrieve reported message {} in channel {} - the message might have been deleted", messageId, event.getChannel(), failure); @@ -192,10 +254,6 @@ private ActionRow setComponents(long targetId, long threadId) { ); } - private void createReportThread(Message message, long targetId, ModerationConfig config) { - createReportThread(message, targetId, config, thread->{}); - } - private void createReportThread(Message message, long targetId, ModerationConfig config, Consumer onSuccess) { message.createThreadChannel(message.getEmbeds().get(0).getTitle()).queue( thread -> { @@ -207,10 +265,6 @@ private void createReportThread(Message message, long targetId, ModerationConfig ); } - - - - private EmbedBuilder buildReportEmbed(User reported, User reportedBy, String reason, Channel channel) { return new EmbedBuilder() .setAuthor(UserUtils.getUserTag(reported), null, reported.getEffectiveAvatarUrl())