diff --git a/abstracto-application/abstracto-modules/experience-tracking/experience-tracking-impl/src/main/java/dev/sheldan/abstracto/experience/listener/SendMessageToChannelLevelAction.java b/abstracto-application/abstracto-modules/experience-tracking/experience-tracking-impl/src/main/java/dev/sheldan/abstracto/experience/listener/SendMessageToChannelLevelAction.java new file mode 100644 index 000000000..a7e18118a --- /dev/null +++ b/abstracto-application/abstracto-modules/experience-tracking/experience-tracking-impl/src/main/java/dev/sheldan/abstracto/experience/listener/SendMessageToChannelLevelAction.java @@ -0,0 +1,99 @@ +package dev.sheldan.abstracto.experience.listener; + +import com.google.gson.Gson; +import dev.sheldan.abstracto.core.exception.InputFormatException; +import dev.sheldan.abstracto.core.models.ServerUser; +import dev.sheldan.abstracto.core.models.template.display.MemberDisplay; +import dev.sheldan.abstracto.core.service.ChannelService; +import dev.sheldan.abstracto.core.service.MemberService; +import dev.sheldan.abstracto.core.templating.model.MessageToSend; +import dev.sheldan.abstracto.core.templating.service.TemplateService; +import dev.sheldan.abstracto.core.utils.FutureUtils; +import dev.sheldan.abstracto.core.utils.ParseUtils; +import dev.sheldan.abstracto.experience.model.LevelActionPayload; +import dev.sheldan.abstracto.experience.model.SendMessageToChannelLevelActionMessageModel; +import dev.sheldan.abstracto.experience.model.SendMessageToChannelLevelActionPayload; +import dev.sheldan.abstracto.experience.model.database.AUserExperience; +import dev.sheldan.abstracto.experience.model.database.LevelAction; +import lombok.extern.slf4j.Slf4j; +import net.dv8tion.jda.api.entities.Guild; +import net.dv8tion.jda.api.entities.channel.middleman.GuildChannel; +import net.dv8tion.jda.api.entities.channel.middleman.GuildMessageChannel; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component +@Slf4j +public class SendMessageToChannelLevelAction implements LevelActionListener { + + public static final String ACTION_NAME = "send_message_to_channel_above_level"; + private static final String LEVEL_ACTION_SEND_MESSAGE_TEMPLATE_KEY = "levelAction_sendMessageToChannel_template"; + + @Autowired + private Gson gson; + + @Autowired + private ChannelService channelService; + + @Autowired + private TemplateService templateService; + + @Autowired + private MemberService memberService; + + @Override + public String getName() { + return ACTION_NAME; + } + + @Override + public void apply(AUserExperience userExperience, LevelAction levelAction, MemberActionModification container) { + SendMessageToChannelLevelActionPayload payload = (SendMessageToChannelLevelActionPayload) levelAction.getLoadedPayload(); + SendMessageToChannelLevelActionMessageModel.SendMessageToChannelLevelActionMessageModelBuilder messageModelBuilder = SendMessageToChannelLevelActionMessageModel + .builder() + .level(userExperience.getLevelOrDefault()) + .templateKey(payload.getTemplateKey()) + .experience(userExperience.getExperience()); + ServerUser serverUser = ServerUser.fromAUserInAServer(userExperience.getUser()); + memberService.getMemberInServerAsync(serverUser).thenAccept(member -> { + messageModelBuilder.memberDisplay(MemberDisplay.fromMember(member)); + SendMessageToChannelLevelActionMessageModel model = messageModelBuilder.build(); + MessageToSend messageToSend = templateService.renderEmbedTemplate(LEVEL_ACTION_SEND_MESSAGE_TEMPLATE_KEY, model, serverUser.getServerId()); + GuildMessageChannel targetChannel = channelService.getMessageChannelFromServer(serverUser.getServerId(), payload.getChannelId()); + FutureUtils.toSingleFutureGeneric(channelService.sendMessageToSendToChannel(messageToSend, targetChannel)).thenAccept(unused -> { + log.info("Send message to channel action sent a message to channel {} for user {} in server {}.", payload.getChannelId(), serverUser.getUserId(), serverUser.getServerId()); + }).exceptionally(throwable -> { + log.warn("Send message to channel action failed to send a message to channel {} for user {} in server {}.", payload.getChannelId(), serverUser.getUserId(), serverUser.getServerId(), throwable); + return null; + }); + }).exceptionally(throwable -> { + log.warn("Failed to load member {} in server {} for send message level action towards channel {}.", serverUser.getUserId(), serverUser.getServerId(), payload.getChannelId()); + return null; + }); + } + + @Override + public boolean shouldExecute(AUserExperience aUserExperience, LevelAction levelAction) { + return aUserExperience.getLevelOrDefault() >= levelAction.getLevel().getLevel(); + } + + @Override + public void prepareAction(LevelAction levelAction) { + levelAction.setLoadedPayload(gson.fromJson(levelAction.getPayload(), SendMessageToChannelLevelActionPayload.class)); + } + + @Override + public LevelActionPayload createPayload(Guild guild, String input) { + if(!input.contains(";")) { + throw new InputFormatException(input, "<#channel>;template_key"); + } + String channelPart = input.substring(0, input.indexOf(";")); + GuildChannel channel = ParseUtils.parseGuildChannelFromText(channelPart, guild); + String templateKey = input.substring(input.indexOf(";") + 1); + return SendMessageToChannelLevelActionPayload + .builder() + .channelId(channel.getIdLong()) + .templateKey(templateKey) + .build(); + } +} diff --git a/abstracto-application/abstracto-modules/experience-tracking/experience-tracking-impl/src/main/java/dev/sheldan/abstracto/experience/model/SendMessageToChannelLevelActionMessageModel.java b/abstracto-application/abstracto-modules/experience-tracking/experience-tracking-impl/src/main/java/dev/sheldan/abstracto/experience/model/SendMessageToChannelLevelActionMessageModel.java new file mode 100644 index 000000000..64c6b15b7 --- /dev/null +++ b/abstracto-application/abstracto-modules/experience-tracking/experience-tracking-impl/src/main/java/dev/sheldan/abstracto/experience/model/SendMessageToChannelLevelActionMessageModel.java @@ -0,0 +1,14 @@ +package dev.sheldan.abstracto.experience.model; + +import dev.sheldan.abstracto.core.models.template.display.MemberDisplay; +import lombok.Builder; +import lombok.Getter; + +@Getter +@Builder +public class SendMessageToChannelLevelActionMessageModel implements LevelActionPayload { + private MemberDisplay memberDisplay; + private Integer level; + private Long experience; + private String templateKey; +} diff --git a/abstracto-application/abstracto-modules/experience-tracking/experience-tracking-impl/src/main/java/dev/sheldan/abstracto/experience/model/SendMessageToChannelLevelActionPayload.java b/abstracto-application/abstracto-modules/experience-tracking/experience-tracking-impl/src/main/java/dev/sheldan/abstracto/experience/model/SendMessageToChannelLevelActionPayload.java new file mode 100644 index 000000000..6b80ec895 --- /dev/null +++ b/abstracto-application/abstracto-modules/experience-tracking/experience-tracking-impl/src/main/java/dev/sheldan/abstracto/experience/model/SendMessageToChannelLevelActionPayload.java @@ -0,0 +1,11 @@ +package dev.sheldan.abstracto.experience.model; + +import lombok.Builder; +import lombok.Getter; + +@Getter +@Builder +public class SendMessageToChannelLevelActionPayload implements LevelActionPayload { + private Long channelId; + private String templateKey; +} diff --git a/abstracto-application/abstracto-modules/experience-tracking/experience-tracking-int/src/main/java/dev/sheldan/abstracto/experience/listener/LevelActionListener.java b/abstracto-application/abstracto-modules/experience-tracking/experience-tracking-int/src/main/java/dev/sheldan/abstracto/experience/listener/LevelActionListener.java index 76c6690e6..ab66aa870 100644 --- a/abstracto-application/abstracto-modules/experience-tracking/experience-tracking-int/src/main/java/dev/sheldan/abstracto/experience/listener/LevelActionListener.java +++ b/abstracto-application/abstracto-modules/experience-tracking/experience-tracking-int/src/main/java/dev/sheldan/abstracto/experience/listener/LevelActionListener.java @@ -4,9 +4,7 @@ import dev.sheldan.abstracto.experience.model.LevelActionPayload; import dev.sheldan.abstracto.experience.model.database.AUserExperience; import dev.sheldan.abstracto.experience.model.database.LevelAction; import net.dv8tion.jda.api.entities.Guild; -import org.springframework.stereotype.Component; -@Component public interface LevelActionListener { String getName(); diff --git a/abstracto-application/core/core-int/src/main/java/dev/sheldan/abstracto/core/exception/InputFormatException.java b/abstracto-application/core/core-int/src/main/java/dev/sheldan/abstracto/core/exception/InputFormatException.java new file mode 100644 index 000000000..5cc722f93 --- /dev/null +++ b/abstracto-application/core/core-int/src/main/java/dev/sheldan/abstracto/core/exception/InputFormatException.java @@ -0,0 +1,29 @@ +package dev.sheldan.abstracto.core.exception; + +import dev.sheldan.abstracto.core.models.exception.InputFormatExceptionModel; +import dev.sheldan.abstracto.core.templating.Templatable; + +public class InputFormatException extends AbstractoRunTimeException implements Templatable { + + private final InputFormatExceptionModel model; + + + public InputFormatException(String wrongFormat, String validFormat) { + super("Input format exception "); + this.model = InputFormatExceptionModel + .builder() + .invalidFormat(wrongFormat) + .validFormat(validFormat) + .build(); + } + + @Override + public String getTemplateName() { + return "input_invalid_format_exception"; + } + + @Override + public Object getTemplateModel() { + return model; + } +} diff --git a/abstracto-application/core/core-int/src/main/java/dev/sheldan/abstracto/core/models/exception/InputFormatExceptionModel.java b/abstracto-application/core/core-int/src/main/java/dev/sheldan/abstracto/core/models/exception/InputFormatExceptionModel.java new file mode 100644 index 000000000..e1ce37ef0 --- /dev/null +++ b/abstracto-application/core/core-int/src/main/java/dev/sheldan/abstracto/core/models/exception/InputFormatExceptionModel.java @@ -0,0 +1,15 @@ +package dev.sheldan.abstracto.core.models.exception; + +import lombok.Builder; +import lombok.Getter; +import lombok.Setter; + +import java.io.Serializable; + +@Setter +@Getter +@Builder +public class InputFormatExceptionModel implements Serializable { + private final String invalidFormat; + private final String validFormat; +} diff --git a/abstracto-application/core/core-int/src/main/java/dev/sheldan/abstracto/core/utils/ParseUtils.java b/abstracto-application/core/core-int/src/main/java/dev/sheldan/abstracto/core/utils/ParseUtils.java index da70ee7ea..7ba84a63a 100644 --- a/abstracto-application/core/core-int/src/main/java/dev/sheldan/abstracto/core/utils/ParseUtils.java +++ b/abstracto-application/core/core-int/src/main/java/dev/sheldan/abstracto/core/utils/ParseUtils.java @@ -102,7 +102,7 @@ public class ParseUtils { throw new AbstractoTemplatedException("No channel found with name.", "no_channel_found_by_name_exception"); } if(potentialMatches.size() > 1) { - throw new AbstractoTemplatedException("Multiple channels found..", "multiple_channels_found_by_name_exception"); + throw new AbstractoTemplatedException("Multiple channels found.", "multiple_channels_found_by_name_exception"); } return guild.getGuildChannelById(potentialMatches.get(0).getId()); }