mirror of
https://github.com/Sheldan/abstracto.git
synced 2026-03-29 14:54:33 +00:00
added closesilently command for modmail
largely refactored modmail future handling and error handling in case: no permission, unable to contact user fixed help command template
This commit is contained in:
@@ -43,7 +43,7 @@ public class Close extends AbstractConditionableCommand {
|
||||
List<Object> parameters = commandContext.getParameters().getParameters();
|
||||
String note = parameters.size() == 1 ? (String) parameters.get(0) : templateService.renderTemplate("modmail_close_default_note", new Object());
|
||||
ModMailThread thread = modMailThreadManagementService.getByChannel(commandContext.getUserInitiatedContext().getChannel());
|
||||
modMailThreadService.closeModMailThread(thread, commandContext.getChannel(), note);
|
||||
modMailThreadService.closeModMailThread(thread, commandContext.getChannel(), note, true);
|
||||
return CommandResult.fromSuccess();
|
||||
}
|
||||
|
||||
|
||||
@@ -3,14 +3,21 @@ package dev.sheldan.abstracto.modmail.commands;
|
||||
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
|
||||
import dev.sheldan.abstracto.core.command.condition.CommandCondition;
|
||||
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
|
||||
import dev.sheldan.abstracto.core.command.config.HelpInfo;
|
||||
import dev.sheldan.abstracto.core.command.config.Parameter;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandResult;
|
||||
import dev.sheldan.abstracto.core.config.FeatureEnum;
|
||||
import dev.sheldan.abstracto.modmail.commands.condition.RequiresModMailCondition;
|
||||
import dev.sheldan.abstracto.modmail.config.ModMailFeatures;
|
||||
import dev.sheldan.abstracto.modmail.models.database.ModMailThread;
|
||||
import dev.sheldan.abstracto.modmail.service.ModMailThreadService;
|
||||
import dev.sheldan.abstracto.modmail.service.management.ModMailThreadManagementService;
|
||||
import dev.sheldan.abstracto.templating.service.TemplateService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
@Component
|
||||
@@ -19,14 +26,36 @@ public class CloseSilently extends AbstractConditionableCommand {
|
||||
@Autowired
|
||||
private RequiresModMailCondition requiresModMailCondition;
|
||||
|
||||
@Autowired
|
||||
private ModMailThreadManagementService modMailThreadManagementService;
|
||||
|
||||
@Autowired
|
||||
private ModMailThreadService modMailThreadService;
|
||||
|
||||
@Autowired
|
||||
private TemplateService templateService;
|
||||
@Override
|
||||
public CommandResult execute(CommandContext commandContext) {
|
||||
return null;
|
||||
List<Object> parameters = commandContext.getParameters().getParameters();
|
||||
String note = parameters.size() == 1 ? (String) parameters.get(0) : templateService.renderTemplate("modmail_close_default_note", new Object());
|
||||
ModMailThread thread = modMailThreadManagementService.getByChannel(commandContext.getUserInitiatedContext().getChannel());
|
||||
modMailThreadService.closeModMailThread(thread, commandContext.getChannel(), note, false);
|
||||
return CommandResult.fromSuccess();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandConfiguration getConfiguration() {
|
||||
return null;
|
||||
Parameter note = Parameter.builder().name("note").type(String.class).remainder(true).optional(true).build();
|
||||
List<Parameter> parameters = Arrays.asList(note);
|
||||
HelpInfo helpInfo = HelpInfo.builder().templated(true).build();
|
||||
return CommandConfiguration.builder()
|
||||
.name("closeSilently")
|
||||
.module(ModMailModuleInterface.MODMAIL)
|
||||
.parameters(parameters)
|
||||
.help(helpInfo)
|
||||
.templated(true)
|
||||
.causesReaction(true)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -21,6 +21,7 @@ import dev.sheldan.abstracto.templating.model.MessageToSend;
|
||||
import dev.sheldan.abstracto.templating.service.TemplateService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.entities.*;
|
||||
import net.dv8tion.jda.api.exceptions.InsufficientPermissionException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
@@ -250,7 +251,9 @@ public class ModMailThreadServiceBean implements ModMailThreadService {
|
||||
}
|
||||
}
|
||||
|
||||
private void sendModMailFailure(String template, AUserInAServer aUserInAServer, ModMailThread modMailThread, MessageChannel channel, Throwable throwable) {
|
||||
@Transactional
|
||||
public void sendModMailFailure(String template, AUserInAServer aUserInAServer, Long modMailTreadId, MessageChannel channel, Throwable throwable) {
|
||||
ModMailThread modMailThread = modMailThreadManagementService.getById(modMailTreadId);
|
||||
try {
|
||||
FullUser fullUser = FullUser
|
||||
.builder()
|
||||
@@ -270,38 +273,81 @@ public class ModMailThreadServiceBean implements ModMailThreadService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void closeModMailThread(ModMailThread modMailThread, MessageChannel feedBack, String note) {
|
||||
public void closeModMailThread(ModMailThread modMailThread, MessageChannel feedBack, String note, Boolean notifyUser) {
|
||||
List<ModMailMessage> modMailMessages = modMailThread.getMessages();
|
||||
|
||||
List<CompletableFuture<Message>> messages = modMailMessageService.loadModMailMessages(modMailMessages);
|
||||
Long modMailThreadId = modMailThread.getId();
|
||||
for (int i = 0; i < messages.size(); i++) {
|
||||
CompletableFuture<Message> messageCompletableFuture = messages.get(i);
|
||||
Long messageId = modMailMessages.get(i).getMessageId();
|
||||
messageCompletableFuture.exceptionally(throwable -> {
|
||||
log.warn("Failed to load message {} in mod mail thread {}", messageId, modMailThread.getId());
|
||||
log.warn("Failed to load message {} in mod mail thread {}", messageId, modMailThreadId);
|
||||
return null;
|
||||
});
|
||||
}
|
||||
CompletableFuture.allOf(messages.toArray(new CompletableFuture[0])).thenAccept(aVoid -> {
|
||||
self.logModMailThread(modMailThread, messages, note, modMailMessages);
|
||||
}).exceptionally(throwable -> {
|
||||
log.warn("Failed to load some mod mail messages for mod mail thread {}. Still trying to post the ones we got.", modMailThread.getId(), throwable);
|
||||
self.logModMailThread(modMailThread, messages, note, modMailMessages);
|
||||
return null;
|
||||
CompletableFuture.allOf(messages.toArray(new CompletableFuture[0])).whenComplete((avoid, throwable) -> {
|
||||
if(throwable != null) {
|
||||
log.warn("Failed to load some mod mail messages for mod mail thread {}. Still trying to post the ones we got.", modMailThreadId, throwable);
|
||||
}
|
||||
self.logModMailThread(modMailThreadId, messages, note).thenRun(() -> {
|
||||
self.afterSuccessfulLog(modMailThreadId, feedBack, notifyUser);
|
||||
}).exceptionally(innerThrowable -> {
|
||||
sendModMailFailure("modmail_exception_generic", modMailThread.getUser(), modMailThreadId, feedBack, innerThrowable);
|
||||
log.error("Failed to log messages for mod mail thread {}.", modMailThreadId, innerThrowable);
|
||||
return null;
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void logModMailThread(ModMailThread modMailThread, List<CompletableFuture<Message>> messages, String note, List<ModMailMessage> modMailMessages) {
|
||||
public void afterSuccessfulLog(Long modMailThreadId, MessageChannel feedBack, Boolean notifyUser) {
|
||||
ModMailThread modMailThread = modMailThreadManagementService.getById(modMailThreadId);
|
||||
User user = botService.getMemberInServer(modMailThread.getUser()).getUser();
|
||||
user.openPrivateChannel().queue(privateChannel -> {
|
||||
try {
|
||||
List<CompletableFuture<Message>> messageFutures = new ArrayList<>();
|
||||
if(notifyUser){
|
||||
messageFutures.addAll(channelService.sendTemplateInChannel("modmail_closing_user_message", new Object(), privateChannel));
|
||||
} else {
|
||||
messageFutures.add(CompletableFuture.completedFuture(null));
|
||||
}
|
||||
CompletableFuture.allOf(messageFutures.toArray(new CompletableFuture[0])).whenComplete((result, throwable) -> {
|
||||
if(throwable != null) {
|
||||
log.warn("Failed to send closing message to user {} after closing mod mail thread {}", user.getIdLong(), modMailThread.getId(), throwable);
|
||||
}
|
||||
try {
|
||||
channelService.deleteTextChannel(modMailThread.getChannel()).thenRun(() -> {
|
||||
self.closeModMailThreadInDb(modMailThreadId);
|
||||
}).exceptionally(throwable2 -> {
|
||||
log.error("Failed to delete text channel containing mod mail thread {}", modMailThread.getId(), throwable2);
|
||||
return null;
|
||||
});
|
||||
} catch (InsufficientPermissionException ex){
|
||||
log.error("Failed to delete text channel containing mod mail thread {}", modMailThread.getId(), ex);
|
||||
sendModMailFailure("modmail_exception_cannot_delete_channel", modMailThread.getUser(), modMailThreadId, feedBack, ex);
|
||||
} catch (Exception ex) {
|
||||
log.error("Failed to delete text channel containing mod mail thread {}", modMailThread.getId(), ex);
|
||||
}
|
||||
});
|
||||
} catch (Exception e) {
|
||||
log.error("Failed to render closing user message", e);
|
||||
sendModMailFailure("modmail_exception_generic", modMailThread.getUser(), modMailThreadId, feedBack, e);
|
||||
}
|
||||
}, throwable -> log.error("Failed to load private channel with user {}", user.getIdLong(), throwable));
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public CompletableFuture<Void> logModMailThread(Long modMailThreadId, List<CompletableFuture<Message>> messages, String note) {
|
||||
ModMailThread modMailThread = modMailThreadManagementService.getById(modMailThreadId);
|
||||
List<ModMailLoggedMessage> loggedMessages = new ArrayList<>();
|
||||
messages.forEach(future -> {
|
||||
try {
|
||||
if(!future.isCompletedExceptionally()) {
|
||||
Message loadedMessage = future.get();
|
||||
if(loadedMessage != null) {
|
||||
ModMailMessage modmailMessage = modMailMessages
|
||||
ModMailMessage modmailMessage = modMailThread.getMessages()
|
||||
.stream()
|
||||
.filter(modMailMessage -> modMailMessage.getMessageId().equals(loadedMessage.getIdLong()))
|
||||
.findFirst().get();
|
||||
@@ -330,19 +376,16 @@ public class ModMailThreadServiceBean implements ModMailThreadService {
|
||||
List<CompletableFuture<Message>> closeHeaderFutures = postTargetService.sendEmbedInPostTarget(messageToSend, MODMAIL_LOG_POSTTARGET, modMailThread.getServer().getId());
|
||||
completableFutures.addAll(closeHeaderFutures);
|
||||
completableFutures.addAll(self.sendMessagesToPostTarget(modMailThread, loggedMessages));
|
||||
CompletableFuture.allOf(completableFutures.toArray(new CompletableFuture[0])).thenAccept(aVoid -> {
|
||||
channelService.deleteTextChannel(modMailThread.getChannel()).thenAccept(o -> {
|
||||
self.closeModMailThreadInDb(modMailThread);
|
||||
});
|
||||
});
|
||||
return CompletableFuture.allOf(completableFutures.toArray(new CompletableFuture[0]));
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void closeModMailThreadInDb(ModMailThread modMailThread) {
|
||||
public void closeModMailThreadInDb(Long modMailThreadId) {
|
||||
ModMailThread modMailThread = modMailThreadManagementService.getById(modMailThreadId);
|
||||
log.info("Setting thread {} to closed.", modMailThread.getId());
|
||||
modMailThreadManagementService.setModMailThreadState(modMailThread, ModMailThreadState.CLOSED);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public List<CompletableFuture<Message>> sendMessagesToPostTarget(ModMailThread modMailThread, List<ModMailLoggedMessage> loadedMessages) {
|
||||
List<CompletableFuture<Message>> messageFutures = new ArrayList<>();
|
||||
loadedMessages.forEach(message -> {
|
||||
@@ -391,7 +434,7 @@ public class ModMailThreadServiceBean implements ModMailThreadService {
|
||||
modMailThreadManagementService.setModMailThreadState(modMailThread, ModMailThreadState.MOD_REPLIED);
|
||||
}).exceptionally(throwable -> {
|
||||
log.error("Failed to send message to user {}", modMailThread.getUser().getUserReference().getId());
|
||||
sendModMailFailure("modmail_exception_cannot_message_user", modMailThread.getUser(), modMailThread, feedBack, throwable);
|
||||
sendModMailFailure("modmail_exception_cannot_message_user", modMailThread.getUser(), modMailThread.getId(), feedBack, throwable);
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -28,6 +28,11 @@ public class ModMailThreadManagementServiceBean implements ModMailThreadManageme
|
||||
return getByChannel(channel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ModMailThread getById(Long modMailThreadId) {
|
||||
return modMailThreadRepository.getOne(modMailThreadId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ModMailThread getByChannel(AChannel channel) {
|
||||
return modMailThreadRepository.findByChannel(channel);
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"author": {
|
||||
"name": "${user.member.effectiveName}",
|
||||
"avatar": "${user.member.user.effectiveAvatarUrl}"
|
||||
},
|
||||
"color" : {
|
||||
"r": 200,
|
||||
"g": 0,
|
||||
"b": 255
|
||||
},
|
||||
"description": "<#include "close_failed_to_delete_text_channel">"
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"author": {
|
||||
"name": "${user.member.effectiveName}",
|
||||
"avatar": "${user.member.user.effectiveAvatarUrl}"
|
||||
},
|
||||
"color" : {
|
||||
"r": 200,
|
||||
"g": 0,
|
||||
"b": 255
|
||||
},
|
||||
"description": "<#include "modmail_generic_error">"
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"color" : {
|
||||
"r": 200,
|
||||
"g": 0,
|
||||
"b": 255
|
||||
},
|
||||
"description": "<#include "modmail_closing_user_message_description">"
|
||||
}
|
||||
@@ -17,5 +17,5 @@ public interface ModMailThreadService {
|
||||
void createModMailPrompt(AUser user, MessageChannel messageChannel);
|
||||
void relayMessageToModMailThread(ModMailThread modMailThread, Message message);
|
||||
void relayMessageToDm(ModMailThread modMailThread, String text, Message message, Boolean anonymous, MessageChannel feedBack);
|
||||
void closeModMailThread(ModMailThread modMailThread, MessageChannel feedBack, String note);
|
||||
void closeModMailThread(ModMailThread modMailThread, MessageChannel feedBack, String note, Boolean notifyUser);
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ import java.util.List;
|
||||
|
||||
public interface ModMailThreadManagementService {
|
||||
ModMailThread getByChannelId(Long channelId);
|
||||
ModMailThread getById(Long modMailThreadId);
|
||||
ModMailThread getByChannel(AChannel channel);
|
||||
List<ModMailThread> getThreadByUserAndState(AUserInAServer userInAServer, ModMailThreadState state);
|
||||
ModMailThread getOpenModmailThreadForUser(AUserInAServer userInAServer);
|
||||
|
||||
@@ -21,9 +21,8 @@
|
||||
<#if command.aliases?? && command.aliases?size gt 0>
|
||||
<#include "help_command_embed_command_aliases">: `${command.aliases?join("`, `")}`
|
||||
</#if>
|
||||
<#include "help_command_embed_command_description">:
|
||||
<#if restricted?? && restricted>
|
||||
<#include "help_command_embed_command_description"><#if allowedRoles??> <#list allowedRoles as allowedRole> ${allowedRole.asMention}<#sep><#include "help_command_embed_or"><#else><#include "help_command_embed_command_executable_by_nobody"></#list> </#if>
|
||||
<#include "help_command_embed_command_executable_by">:<#if allowedRoles??> <#list allowedRoles as allowedRole> ${allowedRole.asMention}<#sep><#include "help_command_embed_or"><#else><#include "help_command_embed_command_executable_by_nobody"></#list> </#if>
|
||||
<#if immuneRoles?? ><#include "help_command_embed_command_immune">: <#list immuneRoles as immuneRole> ${immuneRole.asMention}<#sep><#include "help_command_embed_or"><#else>None</#list> </#if>
|
||||
<#else>
|
||||
<#include "help_command_embed_command_not_restricted">
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
Failed to delete text channel containing mod mail thread. The bot does not have permissions to do so.
|
||||
@@ -0,0 +1 @@
|
||||
Mod mail thread has been closed. If you have any questions please do not hesitate to contact us again.
|
||||
@@ -0,0 +1 @@
|
||||
Generic mod mail failure. Check the logs.
|
||||
Reference in New Issue
Block a user