added current values to post post target

added support for custom setup steps for each feature
added mod mail category setup step
This commit is contained in:
Sheldan
2020-05-25 23:11:44 +02:00
parent 3714fd2582
commit 213f42ffbd
36 changed files with 342 additions and 24 deletions

View File

@@ -0,0 +1,28 @@
package dev.sheldan.abstracto.modmail.setup;
import dev.sheldan.abstracto.core.interactive.DelayedAction;
import dev.sheldan.abstracto.core.interactive.DelayedActionConfig;
import dev.sheldan.abstracto.core.service.ConfigService;
import dev.sheldan.abstracto.modmail.service.ModMailThreadServiceBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class ModMailCategoryDelayedAction implements DelayedAction {
@Autowired
private ConfigService configService;
@Override
public void execute(DelayedActionConfig delayedActionConfig) {
ModMailCategoryDelayedActionConfig concrete = (ModMailCategoryDelayedActionConfig) delayedActionConfig;
configService.setConfigValue(ModMailThreadServiceBean.MODMAIL_CATEGORY, concrete.getServerId(), concrete.getValue());
}
@Override
public boolean handles(DelayedActionConfig delayedActionConfig) {
return delayedActionConfig instanceof ModMailCategoryDelayedActionConfig;
}
}

View File

@@ -0,0 +1,32 @@
package dev.sheldan.abstracto.modmail.setup;
import dev.sheldan.abstracto.core.interactive.DelayedActionConfig;
import dev.sheldan.abstracto.core.models.database.AConfig;
import dev.sheldan.abstracto.modmail.models.template.ModMailCategoryActionModel;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
import net.dv8tion.jda.api.entities.Category;
@Getter
@Setter
@Builder
public class ModMailCategoryDelayedActionConfig implements DelayedActionConfig {
private Long serverId;
private AConfig value;
private Category category;
@Override
public String getTemplateName() {
return "setup_modmail_category_action";
}
@Override
public Object getTemplateModel() {
return ModMailCategoryActionModel
.builder()
.category(this.category)
.categoryId(value.getLongValue())
.build();
}
}

View File

@@ -0,0 +1,140 @@
package dev.sheldan.abstracto.modmail.setup;
import dev.sheldan.abstracto.core.exception.AbstractoRunTimeException;
import dev.sheldan.abstracto.core.exception.ChannelNotFoundException;
import dev.sheldan.abstracto.core.interactive.*;
import dev.sheldan.abstracto.core.models.AServerChannelUserId;
import dev.sheldan.abstracto.core.models.FeatureValidationResult;
import dev.sheldan.abstracto.core.models.database.AChannel;
import dev.sheldan.abstracto.core.models.database.AConfig;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.core.service.BotService;
import dev.sheldan.abstracto.core.service.ConfigService;
import dev.sheldan.abstracto.core.service.management.ChannelManagementService;
import dev.sheldan.abstracto.core.service.management.ConfigManagementService;
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
import dev.sheldan.abstracto.modmail.models.template.SetupModMailCategoryMessageModel;
import dev.sheldan.abstracto.modmail.service.ModMailThreadServiceBean;
import dev.sheldan.abstracto.modmail.validator.ModMailFeatureValidator;
import dev.sheldan.abstracto.templating.service.TemplateService;
import lombok.extern.slf4j.Slf4j;
import net.dv8tion.jda.api.entities.Category;
import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.Message;
import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.function.Consumer;
@Component
@Slf4j
public class ModMailCategorySetupBean implements ModMailCategorySetup {
@Autowired
private InteractiveUtils interactiveUtils;
@Autowired
private TemplateService templateService;
@Autowired
private ChannelManagementService channelManagementService;
@Autowired
private UserInServerManagementService userInServerManagementService;
@Autowired
private InteractiveService interactiveService;
@Autowired
private ConfigService configService;
@Autowired
private ConfigManagementService configManagementService;
@Autowired
private ModMailFeatureValidator modMailFeatureValidator;
@Autowired
private BotService botService;
@Override
public CompletableFuture<SetupStepResult> execute(AServerChannelUserId user, SetupStepParameter parameter) {
String messageTemplateKey = "setup_modmail_category_message";
SetupModMailCategoryMessageModel model = SetupModMailCategoryMessageModel
.builder()
.build();
if(configManagementService.configExists(user.getGuildId(), ModMailThreadServiceBean.MODMAIL_CATEGORY)) {
Guild guild = botService.getGuildByIdNullable(user.getGuildId());
Long categoryId = configService.getLongValue(ModMailThreadServiceBean.MODMAIL_CATEGORY, user.getGuildId());
Category category = guild.getCategoryById(categoryId);
model.setCategory(category);
}
String messageText = templateService.renderTemplate(messageTemplateKey, model);
Optional<AChannel> channel = channelManagementService.loadChannel(user.getChannelId());
CompletableFuture<SetupStepResult> future = new CompletableFuture<>();
AUserInAServer aUserInAServer = userInServerManagementService.loadUser(user.getGuildId(), user.getUserId());
if(channel.isPresent()) {
Runnable finalAction = getTimeoutRunnable(user.getGuildId(), user.getChannelId());
Consumer<MessageReceivedEvent> configAction = (MessageReceivedEvent event) -> {
try {
SetupStepResult result;
Message message = event.getMessage();
if(checkForExit(message)) {
result = SetupStepResult.fromCancelled();
} else {
String messageContent = event.getMessage().getContentRaw();
Long categoryId = Long.parseLong(messageContent);
Guild guild = botService.getGuildByIdNullable(user.getGuildId());
FeatureValidationResult featureValidationResult = FeatureValidationResult.builder().validationResult(true).build();
modMailFeatureValidator.validateModMailCategory(featureValidationResult, guild, categoryId);
if(featureValidationResult.getValidationResult()) {
AConfig fakeValue = configService.getFakeConfigForValue(ModMailThreadServiceBean.MODMAIL_CATEGORY, user.getGuildId(), messageContent);
ModMailCategoryDelayedActionConfig build = ModMailCategoryDelayedActionConfig
.builder()
.serverId(user.getGuildId())
.category(guild.getCategoryById(categoryId))
.value(fakeValue)
.build();
List<DelayedActionConfig> delayedSteps = Arrays.asList(build);
result = SetupStepResult
.builder()
.result(SetupStepResultType.SUCCESS)
.delayedActionConfigList(delayedSteps)
.build();
} else {
throw new AbstractoRunTimeException("Category id does not conform.");
}
}
future.complete(result);
} catch (Exception e) {
log.error("Failed to handle post target step.", e);
future.completeExceptionally(e);
}
};
interactiveService.createMessageWithResponse(messageText, aUserInAServer, channel.get(), parameter.getPreviousMessageId(), configAction, finalAction);
} else {
future.completeExceptionally(new ChannelNotFoundException(user.getGuildId(), user.getChannelId()));
}
return future;
}
protected Runnable getTimeoutRunnable(Long serverId, Long channelId) {
return () -> {
interactiveUtils.sendTimeoutMessage(serverId, channelId);
};
}
protected boolean checkForExit(Message message) {
return message.getContentRaw().trim().equalsIgnoreCase("exit");
}
}

View File

@@ -35,16 +35,20 @@ public class ModMailFeatureValidatorBean implements ModMailFeatureValidator {
boolean checkSucceeded = featureValidatorService.checkSystemConfig(ModMailThreadServiceBean.MODMAIL_CATEGORY, server, validationResult);
if(checkSucceeded) {
Long modMailCategory = configService.getLongValue(ModMailThreadServiceBean.MODMAIL_CATEGORY, server.getId());
Category categoryById = guild.getCategoryById(modMailCategory);
if(categoryById == null) {
validationResult.setValidationResult(false);
ModMailCategoryValidationError newError = ModMailCategoryValidationError
.builder()
.currentCategoryId(modMailCategory)
.build();
validationResult.getValidationErrors().add(newError);
}
validateModMailCategory(validationResult, guild, modMailCategory);
}
}
}
public void validateModMailCategory(FeatureValidationResult validationResult, Guild guild, Long modMailCategory) {
Category categoryById = guild.getCategoryById(modMailCategory);
if(categoryById == null) {
validationResult.setValidationResult(false);
ModMailCategoryValidationError newError = ModMailCategoryValidationError
.builder()
.currentCategoryId(modMailCategory)
.build();
validationResult.getValidationErrors().add(newError);
}
}
}

View File

@@ -0,0 +1 @@
<#assign category>${param.category.name}</#assign><#include "setup_modmail_category_action_display">

View File

@@ -0,0 +1 @@
<#assign categoryName><#if category?has_content>${category.name}<#else><#include "setup_modmail_category_message_no_category">></#if></#assign><#include "setup_modmail_category_message_display">

View File

@@ -4,7 +4,9 @@ import dev.sheldan.abstracto.core.config.FeatureConfig;
import dev.sheldan.abstracto.core.config.FeatureEnum;
import dev.sheldan.abstracto.core.config.FeatureMode;
import dev.sheldan.abstracto.core.config.PostTargetEnum;
import dev.sheldan.abstracto.core.interactive.SetupStep;
import dev.sheldan.abstracto.core.service.FeatureValidator;
import dev.sheldan.abstracto.modmail.setup.ModMailCategorySetup;
import dev.sheldan.abstracto.modmail.validator.ModMailFeatureValidator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@@ -18,6 +20,9 @@ public class ModMailFeature implements FeatureConfig {
@Autowired
private ModMailFeatureValidator modMailFeatureValidator;
@Autowired
private ModMailCategorySetup modMailCategorySetup;
@Override
public FeatureEnum getFeature() {
return ModMailFeatures.MOD_MAIL;
@@ -47,4 +52,9 @@ public class ModMailFeature implements FeatureConfig {
public List<String> getRequiredSystemConfigKeys() {
return Arrays.asList("modMailClosingText");
}
@Override
public List<SetupStep> getCustomSetupSteps() {
return Arrays.asList(modMailCategorySetup);
}
}

View File

@@ -0,0 +1,14 @@
package dev.sheldan.abstracto.modmail.models.template;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
import net.dv8tion.jda.api.entities.Category;
@Getter
@Setter
@Builder
public class ModMailCategoryActionModel {
private Category category;
private Long categoryId;
}

View File

@@ -0,0 +1,13 @@
package dev.sheldan.abstracto.modmail.models.template;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
import net.dv8tion.jda.api.entities.Category;
@Getter
@Setter
@Builder
public class SetupModMailCategoryMessageModel {
private Category category;
}

View File

@@ -0,0 +1,6 @@
package dev.sheldan.abstracto.modmail.setup;
import dev.sheldan.abstracto.core.interactive.SetupStep;
public interface ModMailCategorySetup extends SetupStep {
}

View File

@@ -1,6 +1,9 @@
package dev.sheldan.abstracto.modmail.validator;
import dev.sheldan.abstracto.core.models.FeatureValidationResult;
import dev.sheldan.abstracto.core.service.FeatureValidator;
import net.dv8tion.jda.api.entities.Guild;
public interface ModMailFeatureValidator extends FeatureValidator {
void validateModMailCategory(FeatureValidationResult validationResult, Guild guild, Long modMailCategory);
}

View File

@@ -4,8 +4,12 @@ import dev.sheldan.abstracto.core.exception.ChannelNotFoundException;
import dev.sheldan.abstracto.core.models.AServerChannelUserId;
import dev.sheldan.abstracto.core.models.database.AChannel;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.core.models.database.PostTarget;
import dev.sheldan.abstracto.core.models.template.commands.SetupPostTargetMessageModel;
import dev.sheldan.abstracto.core.service.BotService;
import dev.sheldan.abstracto.core.service.ConfigService;
import dev.sheldan.abstracto.core.service.management.ChannelManagementService;
import dev.sheldan.abstracto.core.service.management.PostTargetManagement;
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
import dev.sheldan.abstracto.templating.service.TemplateService;
import lombok.extern.slf4j.Slf4j;
@@ -43,11 +47,29 @@ public class PostTargetSetupStep extends AbstractConfigSetupStep {
@Autowired
private TemplateService templateService;
@Autowired
private BotService botService;
@Autowired
private PostTargetManagement postTargetManagement;
@Override
public CompletableFuture<SetupStepResult> execute(AServerChannelUserId user, SetupStepParameter parameter) {
PostTargetStepParameter systemConfigStepParameter = (PostTargetStepParameter) parameter;
String messageTemplateKey = "setup_posttarget_" + systemConfigStepParameter.getPostTargetKey();
String messageText = templateService.renderSimpleTemplate(messageTemplateKey);
PostTargetStepParameter postTargetStepParameter = (PostTargetStepParameter) parameter;
TextChannel currentTextChannel;
if(postTargetManagement.postTargetExists(postTargetStepParameter.getPostTargetKey(), user.getGuildId())) {
PostTarget postTarget = postTargetManagement.getPostTarget(postTargetStepParameter.getPostTargetKey(), user.getGuildId());
currentTextChannel = botService.getTextChannelFromServer(user.getGuildId(), postTarget.getChannelReference().getId()).orElse(null);
} else {
currentTextChannel = null;
}
SetupPostTargetMessageModel model = SetupPostTargetMessageModel
.builder()
.postTargetKey(postTargetStepParameter.getPostTargetKey())
.currentTextChannel(currentTextChannel)
.build();
String messageTemplateKey = "setup_post_target_message";
String messageText = templateService.renderTemplate(messageTemplateKey, model);
Optional<AChannel> channel = channelManagementService.loadChannel(user.getChannelId());
CompletableFuture<SetupStepResult> future = new CompletableFuture<>();
AUserInAServer aUserInAServer = userInServerManagementService.loadUser(user.getGuildId(), user.getUserId());
@@ -63,11 +85,12 @@ public class PostTargetSetupStep extends AbstractConfigSetupStep {
} else {
if(message.getMentionedChannels().size() == 0) {
future.completeExceptionally(new RuntimeException());
return;
}
TextChannel textChannel = message.getMentionedChannels().get(0);
PostTargetDelayedActionConfig build = PostTargetDelayedActionConfig
.builder()
.postTargetKey(systemConfigStepParameter.getPostTargetKey())
.postTargetKey(postTargetStepParameter.getPostTargetKey())
.serverId(user.getGuildId())
.textChannel(textChannel)
.channelId(textChannel.getIdLong())

View File

@@ -62,6 +62,14 @@ public class SetupServiceBean implements SetupService {
.build();
steps.add(execution);
});
featureConfig.getCustomSetupSteps().forEach(setupStep -> {
SetupExecution execution = SetupExecution
.builder()
.step(setupStep)
.parameter(EmptySetupParameter.builder().build())
.build();
steps.add(execution);
});
for (int i = 0; i < steps.size(); i++) {
SetupExecution setupExecution = steps.get(i);
setupExecution.getParameter().setPreviousMessageId(initialMessageId);

View File

@@ -0,0 +1 @@
<#assign currentTarget><#if currentTextChannel?has_content>${currentTextChannel.asMention}<#else><#include "setup_post_target_no_channel_set"></#if></#assign><#include "setup_posttarget_${postTargetKey}">

View File

@@ -1,5 +1,6 @@
package dev.sheldan.abstracto.core.config;
import dev.sheldan.abstracto.core.interactive.SetupStep;
import dev.sheldan.abstracto.core.service.FeatureValidator;
import java.util.Collections;
@@ -18,4 +19,5 @@ public interface FeatureConfig {
default List<FeatureValidator> getAdditionalFeatureValidators() { return Collections.emptyList(); }
default List<String> getRequiredEmotes() { return Collections.emptyList(); }
default List<FeatureMode> getAvailableModes() { return Collections.emptyList(); };
default List<SetupStep> getCustomSetupSteps() { return Collections.emptyList(); }
}

View File

@@ -0,0 +1,12 @@
package dev.sheldan.abstracto.core.interactive;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
@Builder
public class EmptySetupParameter implements SetupStepParameter {
private Long previousMessageId;
}

View File

@@ -0,0 +1,14 @@
package dev.sheldan.abstracto.core.models.template.commands;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
import net.dv8tion.jda.api.entities.TextChannel;
@Getter
@Setter
@Builder
public class SetupPostTargetMessageModel {
private String postTargetKey;
private TextChannel currentTextChannel;
}

View File

@@ -1 +1 @@
The channel in which where bans should be logged to.
The channel in which where bans should be logged to. Currently: ${currentTarget}

View File

@@ -1 +1 @@
The channel in which decayed warnings should be logged to.
The channel in which decayed warnings should be logged to. Currently: ${currentTarget}

View File

@@ -1 +1 @@
The channel in which deleted messages should be logged to.
The channel in which deleted messages should be logged to. Currently: ${currentTarget}

View File

@@ -1 +1 @@
The channel in which edited messages should be logged to.
The channel in which edited messages should be logged to. Currently: ${currentTarget}

View File

@@ -1 +1 @@
The channel in which guild joins should be logged to.
The channel in which guild joins should be logged to. Currently: ${currentTarget}

View File

@@ -1 +1 @@
The channel in which kicks should be logged to.
The channel in which kicks should be logged to. Currently: ${currentTarget}

View File

@@ -1 +1 @@
The channel where guild leavers should be logged to.
The channel where guild leavers should be logged to. Currently: ${currentTarget}

View File

@@ -1 +1 @@
The channel where mutes should be logged to. Un-mutes will also be in this channel.
The channel where mutes should be logged to. Un-mutes will also be in this channel. Currently: ${currentTarget}

View File

@@ -1 +1 @@
The channel where warnings should be logged to.
The channel where warnings should be logged to. Currently: ${currentTarget}

View File

@@ -0,0 +1 @@
Mod mail threads will be created in category `${category}`.

View File

@@ -0,0 +1 @@
The ID of the category you want to create the mod mail threads in. Currently: ${categoryName}

View File

@@ -1 +1 @@
The channel towards which the closed mod mail threads should be logged to. (In the appropriate mode)
The channel towards which the closed mod mail threads should be logged to. (In the appropriate mode) Currently: ${currentTarget}

View File

@@ -1 +1 @@
The channel which should be used to notify the responsible people about new mod mail threads.
The channel which should be used to notify the responsible people about new mod mail threads. Currently: ${currentTarget}