mirror of
https://github.com/Sheldan/abstracto.git
synced 2026-01-26 05:44:42 +00:00
[AB-296] adding support for buttons
adding buttons for message embed via feature mode
This commit is contained in:
@@ -44,6 +44,11 @@
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.google.code.gson</groupId>
|
||||
<artifactId>gson</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>dev.sheldan.abstracto.core</groupId>
|
||||
<artifactId>metrics-int</artifactId>
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
package dev.sheldan.abstracto.linkembed.listener;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.listener.ButtonClickedListenerResult;
|
||||
import dev.sheldan.abstracto.core.listener.async.jda.ButtonClickedListener;
|
||||
import dev.sheldan.abstracto.core.metric.service.MetricService;
|
||||
import dev.sheldan.abstracto.core.models.listener.ButtonClickedListenerModel;
|
||||
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
||||
import dev.sheldan.abstracto.core.service.MessageService;
|
||||
import dev.sheldan.abstracto.core.service.management.ComponentPayloadManagementService;
|
||||
import dev.sheldan.abstracto.core.templating.service.TemplateService;
|
||||
import dev.sheldan.abstracto.linkembed.config.LinkEmbedFeatureDefinition;
|
||||
import dev.sheldan.abstracto.linkembed.exception.LinkEmbedRemovalNotAllowedException;
|
||||
import dev.sheldan.abstracto.linkembed.model.template.MessageEmbedDeleteButtonPayload;
|
||||
import dev.sheldan.abstracto.linkembed.service.MessageEmbedMetricService;
|
||||
import dev.sheldan.abstracto.linkembed.service.MessageEmbedServiceBean;
|
||||
import dev.sheldan.abstracto.linkembed.service.management.MessageEmbedPostManagementService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.events.interaction.ButtonClickEvent;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class MessageEmbedDeleteButtonClickedListener implements ButtonClickedListener {
|
||||
|
||||
@Autowired
|
||||
private Gson gson;
|
||||
|
||||
@Autowired
|
||||
private MessageService messageService;
|
||||
|
||||
@Autowired
|
||||
private MetricService metricService;
|
||||
|
||||
@Autowired
|
||||
private MessageEmbedPostManagementService messageEmbedPostManagementService;
|
||||
|
||||
@Autowired
|
||||
private MessageEmbedMetricService messageEmbedMetricService;
|
||||
|
||||
@Autowired
|
||||
private InteractionService interactionService;
|
||||
|
||||
@Autowired
|
||||
private TemplateService templateService;
|
||||
|
||||
@Autowired
|
||||
private ComponentPayloadManagementService componentPayloadManagementService;
|
||||
|
||||
@Autowired
|
||||
private MessageEmbedDeleteButtonClickedListener self;
|
||||
|
||||
@Override
|
||||
public ButtonClickedListenerResult execute(ButtonClickedListenerModel model) {
|
||||
ButtonClickEvent event = model.getEvent();
|
||||
MessageEmbedDeleteButtonPayload payload = (MessageEmbedDeleteButtonPayload) model.getDeserializedPayload();
|
||||
Long clickingUserId = event.getInteraction().getUser().getIdLong();
|
||||
boolean embeddedUserRemoves = clickingUserId.equals(payload.getEmbeddedUserId());
|
||||
if(embeddedUserRemoves || clickingUserId.equals(payload.getEmbeddingUserId())) {
|
||||
messageService.deleteMessageInChannelInServer(payload.getEmbeddingServerId(), payload.getEmbeddingChannelId(), payload.getEmbeddingMessageId())
|
||||
.thenAccept(aVoid -> self.executeAfterDeletion(payload, clickingUserId, embeddedUserRemoves, event.getComponentId()));
|
||||
} else {
|
||||
log.info("Not the original author or embedding user clicked the button of component {} in server {} in channel {} on message {}.",
|
||||
event.getComponentId(), event.getGuild().getIdLong(), event.getGuildChannel().getIdLong(), event.getMessageId());
|
||||
throw new LinkEmbedRemovalNotAllowedException();
|
||||
}
|
||||
return ButtonClickedListenerResult.ACKNOWLEDGED;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void executeAfterDeletion(MessageEmbedDeleteButtonPayload payload, Long clickingUserId, boolean embeddedUserRemoves, String componentId) {
|
||||
log.info("User {} deleted embedding message {} in channel {} in server {} from embedded message {} in channel {} and server {}.",
|
||||
clickingUserId, payload.getEmbeddingMessageId(), payload.getEmbeddingChannelId(), payload.getEmbeddingServerId(),
|
||||
payload.getEmbeddedMessageId(), payload.getEmbeddedChannelId(), payload.getEmbeddedServerId());
|
||||
messageEmbedMetricService.incrementMessageEmbedDeletedMetric(embeddedUserRemoves);
|
||||
componentPayloadManagementService.deletePayload(componentId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean handlesEvent(ButtonClickedListenerModel model) {
|
||||
return model.getOrigin().equals(MessageEmbedServiceBean.MESSAGE_EMBED_DELETE_ORIGIN);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FeatureDefinition getFeature() {
|
||||
return LinkEmbedFeatureDefinition.LINK_EMBEDS;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Integer getPriority() {
|
||||
return 10;
|
||||
}
|
||||
}
|
||||
@@ -3,9 +3,6 @@ package dev.sheldan.abstracto.linkembed.listener;
|
||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.listener.DefaultListenerResult;
|
||||
import dev.sheldan.abstracto.core.listener.async.jda.AsyncReactionAddedListener;
|
||||
import dev.sheldan.abstracto.core.metric.service.CounterMetric;
|
||||
import dev.sheldan.abstracto.core.metric.service.MetricService;
|
||||
import dev.sheldan.abstracto.core.metric.service.MetricTag;
|
||||
import dev.sheldan.abstracto.core.models.database.AEmote;
|
||||
import dev.sheldan.abstracto.core.models.listener.ReactionAddedModel;
|
||||
import dev.sheldan.abstracto.core.service.BotService;
|
||||
@@ -13,18 +10,14 @@ import dev.sheldan.abstracto.core.service.EmoteService;
|
||||
import dev.sheldan.abstracto.core.service.MessageService;
|
||||
import dev.sheldan.abstracto.linkembed.config.LinkEmbedFeatureDefinition;
|
||||
import dev.sheldan.abstracto.linkembed.model.database.EmbeddedMessage;
|
||||
import dev.sheldan.abstracto.linkembed.service.MessageEmbedMetricService;
|
||||
import dev.sheldan.abstracto.linkembed.service.management.MessageEmbedPostManagementService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import java.util.Arrays;
|
||||
import java.util.Optional;
|
||||
|
||||
import static dev.sheldan.abstracto.linkembed.listener.MessageEmbedListener.MESSAGE_EMBEDDED;
|
||||
import static dev.sheldan.abstracto.linkembed.listener.MessageEmbedListener.MESSAGE_EMBED_ACTION;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class MessageEmbedRemovalReactionListener implements AsyncReactionAddedListener {
|
||||
@@ -44,19 +37,7 @@ public class MessageEmbedRemovalReactionListener implements AsyncReactionAddedLi
|
||||
private EmoteService emoteService;
|
||||
|
||||
@Autowired
|
||||
private MetricService metricService;
|
||||
|
||||
private static final CounterMetric MESSAGE_EMBED_REMOVED_CREATOR = CounterMetric
|
||||
.builder()
|
||||
.name(MESSAGE_EMBEDDED)
|
||||
.tagList(Arrays.asList(MetricTag.getTag(MESSAGE_EMBED_ACTION, "removed.creator")))
|
||||
.build();
|
||||
|
||||
private static final CounterMetric MESSAGE_EMBED_REMOVED_SOURCE = CounterMetric
|
||||
.builder()
|
||||
.name(MESSAGE_EMBEDDED)
|
||||
.tagList(Arrays.asList(MetricTag.getTag(MESSAGE_EMBED_ACTION, "removed.source")))
|
||||
.build();
|
||||
private MessageEmbedMetricService messageEmbedMetricService;
|
||||
|
||||
@Override
|
||||
public DefaultListenerResult execute(ReactionAddedModel model) {
|
||||
@@ -75,11 +56,7 @@ public class MessageEmbedRemovalReactionListener implements AsyncReactionAddedLi
|
||||
messageService.deleteMessageInChannelInServer(serverId, channelId, messageId).thenAccept(aVoid -> {
|
||||
Optional<EmbeddedMessage> innerOptional = messageEmbedPostManagementService.findEmbeddedPostByMessageId(messageId);
|
||||
innerOptional.ifPresent(value -> messageEmbedPostManagementService.deleteEmbeddedMessage(value));
|
||||
if(embeddedUserRemoves) {
|
||||
metricService.incrementCounter(MESSAGE_EMBED_REMOVED_SOURCE);
|
||||
} else {
|
||||
metricService.incrementCounter(MESSAGE_EMBED_REMOVED_CREATOR);
|
||||
}
|
||||
messageEmbedMetricService.incrementMessageEmbedDeletedMetric(embeddedUserRemoves);
|
||||
});
|
||||
} else {
|
||||
log.debug("Somebody besides the original author and the user embedding added the removal reaction to the message {} in channel {} in server {}.",
|
||||
@@ -103,10 +80,4 @@ public class MessageEmbedRemovalReactionListener implements AsyncReactionAddedLi
|
||||
return LinkEmbedFeatureDefinition.LINK_EMBEDS;
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
public void postConstruct() {
|
||||
metricService.registerCounter(MESSAGE_EMBED_REMOVED_CREATOR, "Message embeds which are created by the embedding user.");
|
||||
metricService.registerCounter(MESSAGE_EMBED_REMOVED_SOURCE, "Message embeds which are created by the embedded user.");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
package dev.sheldan.abstracto.linkembed.service;
|
||||
|
||||
import dev.sheldan.abstracto.core.metric.service.CounterMetric;
|
||||
import dev.sheldan.abstracto.core.metric.service.MetricService;
|
||||
import dev.sheldan.abstracto.core.metric.service.MetricTag;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import java.util.Arrays;
|
||||
|
||||
import static dev.sheldan.abstracto.linkembed.listener.MessageEmbedListener.MESSAGE_EMBEDDED;
|
||||
import static dev.sheldan.abstracto.linkembed.listener.MessageEmbedListener.MESSAGE_EMBED_ACTION;
|
||||
|
||||
@Component
|
||||
public class MessageEmbedMetricServiceBean implements MessageEmbedMetricService {
|
||||
|
||||
private static final CounterMetric MESSAGE_EMBED_REMOVED_CREATOR = CounterMetric
|
||||
.builder()
|
||||
.name(MESSAGE_EMBEDDED)
|
||||
.tagList(Arrays.asList(MetricTag.getTag(MESSAGE_EMBED_ACTION, "removed.creator")))
|
||||
.build();
|
||||
|
||||
private static final CounterMetric MESSAGE_EMBED_REMOVED_SOURCE = CounterMetric
|
||||
.builder()
|
||||
.name(MESSAGE_EMBEDDED)
|
||||
.tagList(Arrays.asList(MetricTag.getTag(MESSAGE_EMBED_ACTION, "removed.source")))
|
||||
.build();
|
||||
|
||||
@Autowired
|
||||
private MetricService metricService;
|
||||
|
||||
@Override
|
||||
public void incrementMessageEmbedDeletedMetric(boolean embeddedUserDeleted) {
|
||||
if(embeddedUserDeleted) {
|
||||
incrementMessageEmbedDeletedEmbeddedMetric();
|
||||
} else {
|
||||
incrementMessageEmbedDeletedEmbeddingMetric();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void incrementMessageEmbedDeletedEmbeddedMetric() {
|
||||
metricService.incrementCounter(MESSAGE_EMBED_REMOVED_SOURCE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void incrementMessageEmbedDeletedEmbeddingMetric() {
|
||||
metricService.incrementCounter(MESSAGE_EMBED_REMOVED_CREATOR);
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
public void postConstruct() {
|
||||
metricService.registerCounter(MESSAGE_EMBED_REMOVED_CREATOR, "Message embeds which are deleted by the embedding user.");
|
||||
metricService.registerCounter(MESSAGE_EMBED_REMOVED_SOURCE, "Message embeds which are deleted by the embedded user.");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2,8 +2,14 @@ package dev.sheldan.abstracto.linkembed.service;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.ServerChannelMessage;
|
||||
import dev.sheldan.abstracto.core.models.cache.CachedMessage;
|
||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||
import dev.sheldan.abstracto.core.models.template.listener.MessageEmbeddedModel;
|
||||
import dev.sheldan.abstracto.core.models.template.button.ButtonConfigModel;
|
||||
import dev.sheldan.abstracto.core.service.management.ComponentPayloadManagementService;
|
||||
import dev.sheldan.abstracto.linkembed.config.LinkEmbedFeatureDefinition;
|
||||
import dev.sheldan.abstracto.linkembed.config.LinkEmbedFeatureMode;
|
||||
import dev.sheldan.abstracto.linkembed.model.template.MessageEmbedDeleteButtonPayload;
|
||||
import dev.sheldan.abstracto.linkembed.model.template.MessageEmbeddedModel;
|
||||
import dev.sheldan.abstracto.core.service.*;
|
||||
import dev.sheldan.abstracto.core.service.management.ChannelManagementService;
|
||||
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
|
||||
@@ -26,10 +32,7 @@ import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.function.Function;
|
||||
import java.util.regex.Matcher;
|
||||
@@ -84,9 +87,20 @@ public class MessageEmbedServiceBean implements MessageEmbedService {
|
||||
@Autowired
|
||||
private EmoteService emoteService;
|
||||
|
||||
@Autowired
|
||||
private ComponentService componentServiceBean;
|
||||
|
||||
@Autowired
|
||||
private FeatureModeService featureModeService;
|
||||
|
||||
@Autowired
|
||||
private ComponentPayloadManagementService componentPayloadManagementService;
|
||||
|
||||
@Value("${abstracto.feature.linkEmbed.removalDays}")
|
||||
private Long embedRemovalDays;
|
||||
|
||||
public static final String MESSAGE_EMBED_DELETE_ORIGIN = "messageEmbedDelete";
|
||||
|
||||
@Override
|
||||
public List<MessageEmbedLink> getLinksInMessage(String message) {
|
||||
List<MessageEmbedLink> links = new ArrayList<>();
|
||||
@@ -126,8 +140,9 @@ public class MessageEmbedServiceBean implements MessageEmbedService {
|
||||
@Override
|
||||
@Transactional
|
||||
public CompletableFuture<Void> embedLink(CachedMessage cachedMessage, TextChannel target, Long userEmbeddingUserInServerId, Message embeddingMessage) {
|
||||
return buildTemplateParameter(embeddingMessage, cachedMessage).thenCompose(messageEmbeddedModel ->
|
||||
self.sendEmbeddingMessage(cachedMessage, target, userEmbeddingUserInServerId, messageEmbeddedModel)
|
||||
boolean deletionButtonEnabled = featureModeService.featureModeActive(LinkEmbedFeatureDefinition.LINK_EMBEDS, target.getGuild(), LinkEmbedFeatureMode.DELETE_BUTTON);
|
||||
return buildTemplateParameter(embeddingMessage, cachedMessage, deletionButtonEnabled).thenCompose(messageEmbeddedModel ->
|
||||
self.sendEmbeddingMessage(cachedMessage, target, userEmbeddingUserInServerId, messageEmbeddedModel, deletionButtonEnabled)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -140,25 +155,30 @@ public class MessageEmbedServiceBean implements MessageEmbedService {
|
||||
return CompletableFuture.completedFuture(null);
|
||||
}
|
||||
log.info("Cleaning up {} embedded embeddedMessages", embeddedMessages.size());
|
||||
List<ServerChannelMessage> serverChannelMessages = embeddedMessages.stream().map(embeddedMessage ->
|
||||
ServerChannelMessage
|
||||
.builder()
|
||||
.serverId(embeddedMessage.getEmbeddingServer().getId())
|
||||
.channelId(embeddedMessage.getEmbeddingChannel().getId())
|
||||
.messageId(embeddedMessage.getEmbeddingMessageId())
|
||||
.build()
|
||||
)
|
||||
List<ServerChannelMessage> reactionChannelMessages = embeddedMessages.stream()
|
||||
.filter(embeddedMessage -> embeddedMessage.getDeletionComponentId() == null)
|
||||
.map(this::convertEmbedMessageToServerChannelMessage)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
List<ServerChannelMessage> buttonChannelMessages = embeddedMessages.stream()
|
||||
.filter(embeddedMessage -> embeddedMessage.getDeletionComponentId() != null)
|
||||
.map(this::convertEmbedMessageToServerChannelMessage)
|
||||
.collect(Collectors.toList());
|
||||
List<Long> embeddedMessagesHandled = embeddedMessages
|
||||
.stream()
|
||||
.map(EmbeddedMessage::getEmbeddingMessageId)
|
||||
.collect(Collectors.toList());
|
||||
List<CompletableFuture<Message>> messageFutures = messageService.retrieveMessages(serverChannelMessages);
|
||||
CompletableFutureList<Message> future = new CompletableFutureList<>(messageFutures);
|
||||
return future.getMainFuture()
|
||||
.handle((unused, throwable) -> self.removeReactions(future.getObjects()))
|
||||
List<CompletableFuture<Message>> reactionMessageFutures = messageService.retrieveMessages(reactionChannelMessages);
|
||||
List<CompletableFuture<Message>> buttonMessageFutures = messageService.retrieveMessages(buttonChannelMessages);
|
||||
CompletableFutureList<Message> reactionFutureList = new CompletableFutureList<>(reactionMessageFutures);
|
||||
CompletableFutureList<Message> buttonFutureList = new CompletableFutureList<>(buttonMessageFutures);
|
||||
return reactionFutureList.getMainFuture()
|
||||
.handle((unused, throwable) -> self.removeReactions(reactionFutureList.getObjects()))
|
||||
.thenCompose(Function.identity())
|
||||
.thenCompose(unused -> buttonFutureList.getMainFuture())
|
||||
.handle((unused, throwable) -> self.removeButtons(buttonFutureList.getObjects()))
|
||||
// deleting the messages from db regardless of exceptions, at most the reaction remains
|
||||
.thenCompose(Function.identity())
|
||||
.whenComplete((unused, throwable) -> self.deleteEmbeddedMessages(embeddedMessagesHandled))
|
||||
.exceptionally(throwable -> {
|
||||
log.error("Failed to clean up embedded messages.", throwable);
|
||||
@@ -166,6 +186,21 @@ public class MessageEmbedServiceBean implements MessageEmbedService {
|
||||
});
|
||||
}
|
||||
|
||||
public CompletableFuture<Void> removeButtons(List<Message> messages) {
|
||||
List<CompletableFuture<Void>> removalFutures = new ArrayList<>();
|
||||
messages.forEach(message -> removalFutures.add(messageService.clearButtons(message)));
|
||||
return FutureUtils.toSingleFutureGeneric(removalFutures);
|
||||
}
|
||||
|
||||
private ServerChannelMessage convertEmbedMessageToServerChannelMessage(EmbeddedMessage embeddedMessage) {
|
||||
return ServerChannelMessage
|
||||
.builder()
|
||||
.serverId(embeddedMessage.getEmbeddingServer().getId())
|
||||
.channelId(embeddedMessage.getEmbeddingChannel().getId())
|
||||
.messageId(embeddedMessage.getEmbeddingMessageId())
|
||||
.build();
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public CompletableFuture<Void> removeReactions(List<Message> allMessages) {
|
||||
List<CompletableFuture<Void>> removalFutures = new ArrayList<>();
|
||||
@@ -186,39 +221,79 @@ public class MessageEmbedServiceBean implements MessageEmbedService {
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public CompletableFuture<Void> sendEmbeddingMessage(CachedMessage cachedMessage, TextChannel target, Long userEmbeddingUserInServerId, MessageEmbeddedModel messageEmbeddedModel) {
|
||||
public CompletableFuture<Void> sendEmbeddingMessage(CachedMessage cachedMessage, TextChannel target,
|
||||
Long userEmbeddingUserInServerId, MessageEmbeddedModel messageEmbeddedModel, Boolean deletionButtonEnabled) {
|
||||
MessageToSend embed = templateService.renderEmbedTemplate(MESSAGE_EMBED_TEMPLATE, messageEmbeddedModel, target.getGuild().getIdLong());
|
||||
AUserInAServer cause = userInServerManagementService.loadOrCreateUser(userEmbeddingUserInServerId);
|
||||
List<CompletableFuture<Message>> completableFutures = channelService.sendMessageToSendToChannel(embed, target);
|
||||
Long embeddingUserId = cause.getUserReference().getId();
|
||||
log.debug("Embedding message {} from channel {} from server {}, because of user {}", cachedMessage.getMessageId(),
|
||||
cachedMessage.getChannelId(), cachedMessage.getServerId(), cause.getUserReference().getId());
|
||||
cachedMessage.getChannelId(), cachedMessage.getServerId(), embeddingUserId);
|
||||
return CompletableFuture.allOf(completableFutures.toArray(new CompletableFuture[0])).thenCompose(aVoid -> {
|
||||
Message createdMessage = completableFutures.get(0).join();
|
||||
return reactionService.addReactionToMessageAsync(REMOVAL_EMOTE, cachedMessage.getServerId(), createdMessage).thenAccept(aVoid1 ->
|
||||
self.loadUserAndPersistMessage(cachedMessage, userEmbeddingUserInServerId, createdMessage)
|
||||
);
|
||||
return self.addDeletionPossibility(cachedMessage, messageEmbeddedModel, createdMessage, embeddingUserId, deletionButtonEnabled);
|
||||
});
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void loadUserAndPersistMessage(CachedMessage cachedMessage, Long embeddingUserId, Message createdMessage) {
|
||||
AUserInAServer innerCause = userInServerManagementService.loadOrCreateUser(embeddingUserId);
|
||||
messageEmbedPostManagementService.createMessageEmbed(cachedMessage, createdMessage, innerCause);
|
||||
public CompletableFuture<Void> addDeletionPossibility(CachedMessage cachedMessage, MessageEmbeddedModel messageEmbeddedModel,
|
||||
Message createdMessage, Long embeddingUserId, Boolean deletionButtonEnabled) {
|
||||
Long serverId = createdMessage.getGuild().getIdLong();
|
||||
AUserInAServer aUserInAServer = userInServerManagementService.loadOrCreateUser(serverId, embeddingUserId);
|
||||
Long embeddingUserInServerId = aUserInAServer.getUserInServerId();
|
||||
if(deletionButtonEnabled) {
|
||||
ButtonConfigModel buttonConfigModel = messageEmbeddedModel.getButtonConfigModel();
|
||||
buttonConfigModel.setButtonPayload(getButtonPayload(createdMessage, cachedMessage, embeddingUserId));
|
||||
buttonConfigModel.setOrigin(MESSAGE_EMBED_DELETE_ORIGIN);
|
||||
buttonConfigModel.setPayloadType(MessageEmbedDeleteButtonPayload.class);
|
||||
AServer server = serverManagementService.loadServer(serverId);
|
||||
componentPayloadManagementService.createPayload(buttonConfigModel, server);
|
||||
self.loadUserAndPersistMessage(cachedMessage, embeddingUserInServerId, createdMessage, messageEmbeddedModel.getButtonConfigModel().getButtonId());
|
||||
return CompletableFuture.completedFuture(null);
|
||||
} else {
|
||||
return reactionService.addReactionToMessageAsync(REMOVAL_EMOTE, cachedMessage.getServerId(), createdMessage).thenAccept(aVoid1 ->
|
||||
self.loadUserAndPersistMessage(cachedMessage, embeddingUserInServerId, createdMessage, null)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private CompletableFuture<MessageEmbeddedModel> buildTemplateParameter(Message message, CachedMessage embeddedMessage) {
|
||||
public MessageEmbedDeleteButtonPayload getButtonPayload(Message embeddingMessage, CachedMessage embeddedMessage, Long embeddingUserId){
|
||||
return MessageEmbedDeleteButtonPayload
|
||||
.builder()
|
||||
.embeddedMessageId(embeddedMessage.getMessageId())
|
||||
.embeddedChannelId(embeddedMessage.getChannelId())
|
||||
.embeddedServerId(embeddedMessage.getServerId())
|
||||
.embeddedUserId(embeddedMessage.getAuthor().getAuthorId())
|
||||
.embeddingMessageId(embeddingMessage.getIdLong())
|
||||
.embeddingChannelId(embeddingMessage.getChannel().getIdLong())
|
||||
.embeddingServerId(embeddingMessage.getGuild().getIdLong())
|
||||
.embeddingUserId(embeddingUserId)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void loadUserAndPersistMessage(CachedMessage cachedMessage, Long embeddingUserId, Message createdMessage, String deletionButtonId) {
|
||||
AUserInAServer innerCause = userInServerManagementService.loadOrCreateUser(embeddingUserId);
|
||||
messageEmbedPostManagementService.createMessageEmbed(cachedMessage, createdMessage, innerCause, deletionButtonId);
|
||||
}
|
||||
|
||||
private CompletableFuture<MessageEmbeddedModel> buildTemplateParameter(Message message, CachedMessage embeddedMessage, Boolean deletionButtonEnabled) {
|
||||
return userService.retrieveUserForId(embeddedMessage.getAuthor().getAuthorId()).thenApply(authorUser ->
|
||||
self.loadMessageEmbedModel(message, embeddedMessage, authorUser)
|
||||
self.loadMessageEmbedModel(message, embeddedMessage, authorUser, deletionButtonEnabled)
|
||||
).exceptionally(throwable -> {
|
||||
log.warn("Failed to retrieve author for user {}.", embeddedMessage.getAuthor().getAuthorId(), throwable);
|
||||
return self.loadMessageEmbedModel(message, embeddedMessage, null);
|
||||
return self.loadMessageEmbedModel(message, embeddedMessage, null, deletionButtonEnabled);
|
||||
});
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public MessageEmbeddedModel loadMessageEmbedModel(Message message, CachedMessage embeddedMessage, User userAuthor) {
|
||||
public MessageEmbeddedModel loadMessageEmbedModel(Message message, CachedMessage embeddedMessage, User userAuthor, Boolean deletionButtonEnabled) {
|
||||
Optional<TextChannel> textChannelFromServer = channelService.getTextChannelFromServerOptional(embeddedMessage.getServerId(), embeddedMessage.getChannelId());
|
||||
TextChannel sourceChannel = textChannelFromServer.orElse(null);
|
||||
ButtonConfigModel buttonConfigModel = ButtonConfigModel
|
||||
.builder()
|
||||
.buttonId(deletionButtonEnabled ? componentServiceBean.generateComponentId() : null)
|
||||
.build();
|
||||
return MessageEmbeddedModel
|
||||
.builder()
|
||||
.member(message.getMember())
|
||||
@@ -227,7 +302,9 @@ public class MessageEmbedServiceBean implements MessageEmbedService {
|
||||
.embeddingUser(message.getMember())
|
||||
.messageChannel(message.getChannel())
|
||||
.guild(message.getGuild())
|
||||
.useButton(deletionButtonEnabled)
|
||||
.embeddedMessage(embeddedMessage)
|
||||
.buttonConfigModel(buttonConfigModel)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ public class MessageEmbedPostManagementServiceBean implements MessageEmbedPostMa
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public void createMessageEmbed(CachedMessage embeddedMessage, Message messageContainingEmbed, AUserInAServer embeddingUser) {
|
||||
public void createMessageEmbed(CachedMessage embeddedMessage, Message messageContainingEmbed, AUserInAServer embeddingUser, String deletionComponentId) {
|
||||
AServer embeddedServer = serverManagementService.loadOrCreate(embeddedMessage.getServerId());
|
||||
AServer embeddingServer = serverManagementService.loadOrCreate(messageContainingEmbed.getGuild().getIdLong());
|
||||
if(!embeddedMessage.getServerId().equals(messageContainingEmbed.getGuild().getIdLong())) {
|
||||
@@ -52,6 +52,7 @@ public class MessageEmbedPostManagementServiceBean implements MessageEmbedPostMa
|
||||
.embeddedMessageId(embeddedMessage.getMessageId())
|
||||
.embeddedChannel(embeddedChannel)
|
||||
.embeddedServer(embeddedServer)
|
||||
.deletionComponentId(deletionComponentId)
|
||||
.embeddingServer(embeddingServer)
|
||||
.embeddingChannel(embeddingChannel)
|
||||
.embeddingMessageId(messageContainingEmbed.getIdLong())
|
||||
|
||||
@@ -2,4 +2,8 @@ abstracto.featureFlags.linkEmbeds.featureName=linkEmbeds
|
||||
abstracto.featureFlags.linkEmbeds.enabled=false
|
||||
|
||||
|
||||
abstracto.feature.linkEmbed.removalDays=1
|
||||
abstracto.feature.linkEmbed.removalDays=1
|
||||
|
||||
abstracto.featureModes.messageEmbedDeleteButton.featureName=linkEmbeds
|
||||
abstracto.featureModes.messageEmbedDeleteButton.mode=messageEmbedDeleteButton
|
||||
abstracto.featureModes.messageEmbedDeleteButton.enabled=true
|
||||
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
|
||||
xmlns:pro="http://www.liquibase.org/xml/ns/pro"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog dbchangelog.xsd
|
||||
http://www.liquibase.org/xml/ns/dbchangelog-ext dbchangelog.xsd
|
||||
http://www.liquibase.org/xml/ns/pro dbchangelog.xsd" >
|
||||
<include file="tables/tables.xml" relativeToChangelogFile="true"/>
|
||||
</databaseChangeLog>
|
||||
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
|
||||
xmlns:pro="http://www.liquibase.org/xml/ns/pro"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog dbchangelog.xsd
|
||||
http://www.liquibase.org/xml/ns/dbchangelog-ext dbchangelog.xsd
|
||||
http://www.liquibase.org/xml/ns/pro dbchangelog.xsd" >
|
||||
<changeSet author="Sheldan" id="embedded_message-notnull">
|
||||
<addColumn tableName="embedded_message">
|
||||
<column name="deletion_component_id" type="VARCHAR(100)" />
|
||||
</addColumn>
|
||||
</changeSet>
|
||||
</databaseChangeLog>
|
||||
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
|
||||
xmlns:pro="http://www.liquibase.org/xml/ns/pro"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog dbchangelog.xsd
|
||||
http://www.liquibase.org/xml/ns/dbchangelog-ext dbchangelog.xsd
|
||||
http://www.liquibase.org/xml/ns/pro dbchangelog.xsd" >
|
||||
<include file="embedded_message.xml" relativeToChangelogFile="true"/>
|
||||
</databaseChangeLog>
|
||||
@@ -9,4 +9,5 @@
|
||||
<include file="1.0-link-embed/collection.xml" relativeToChangelogFile="true"/>
|
||||
<include file="1.2.8-link-embed/collection.xml" relativeToChangelogFile="true"/>
|
||||
<include file="1.2.12/collection.xml" relativeToChangelogFile="true"/>
|
||||
<include file="1.3.0/collection.xml" relativeToChangelogFile="true"/>
|
||||
</databaseChangeLog>
|
||||
@@ -4,7 +4,9 @@ import dev.sheldan.abstracto.core.models.cache.CachedAuthor;
|
||||
import dev.sheldan.abstracto.core.models.cache.CachedMessage;
|
||||
import dev.sheldan.abstracto.core.models.database.AUser;
|
||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||
import dev.sheldan.abstracto.core.models.template.listener.MessageEmbeddedModel;
|
||||
import dev.sheldan.abstracto.linkembed.config.LinkEmbedFeatureDefinition;
|
||||
import dev.sheldan.abstracto.linkembed.config.LinkEmbedFeatureMode;
|
||||
import dev.sheldan.abstracto.linkembed.model.template.MessageEmbeddedModel;
|
||||
import dev.sheldan.abstracto.core.service.*;
|
||||
import dev.sheldan.abstracto.core.service.management.ChannelManagementService;
|
||||
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
|
||||
@@ -67,6 +69,9 @@ public class MessageEmbedServiceBeanTest {
|
||||
@Mock
|
||||
private ReactionService reactionService;
|
||||
|
||||
@Mock
|
||||
private FeatureModeService featureModeService;
|
||||
|
||||
@Mock
|
||||
private TextChannel textChannel;
|
||||
|
||||
@@ -211,8 +216,8 @@ public class MessageEmbedServiceBeanTest {
|
||||
when(cachedMessage.getAuthor()).thenReturn(cachedAuthor);
|
||||
when(userService.retrieveUserForId(USER_ID)).thenReturn(CompletableFuture.completedFuture(embeddedUser));
|
||||
MessageEmbeddedModel model = Mockito.mock(MessageEmbeddedModel.class);
|
||||
when(self.loadMessageEmbedModel(embeddingMessage, cachedMessage, embeddedUser)).thenReturn(model);
|
||||
when(self.sendEmbeddingMessage(cachedMessage, textChannel, EMBEDDING_USER_IN_SERVER_ID, model)).thenReturn(CompletableFuture.completedFuture(null));
|
||||
when(self.loadMessageEmbedModel(embeddingMessage, cachedMessage, embeddedUser, false)).thenReturn(model);
|
||||
when(self.sendEmbeddingMessage(cachedMessage, textChannel, EMBEDDING_USER_IN_SERVER_ID, model, false)).thenReturn(CompletableFuture.completedFuture(null));
|
||||
CompletableFuture<Void> embedFuture = testUnit.embedLink(cachedMessage, textChannel, EMBEDDING_USER_IN_SERVER_ID, embeddingMessage);
|
||||
Assert.assertTrue(embedFuture.isDone());
|
||||
}
|
||||
@@ -225,6 +230,8 @@ public class MessageEmbedServiceBeanTest {
|
||||
CachedAuthor cachedAuthor = Mockito.mock(CachedAuthor.class);
|
||||
when(cachedAuthor.getAuthorId()).thenReturn(USER_ID);
|
||||
when(cachedMessage.getAuthor()).thenReturn(cachedAuthor);
|
||||
when(textChannel.getGuild()).thenReturn(guild);
|
||||
when(featureModeService.featureModeActive(LinkEmbedFeatureDefinition.LINK_EMBEDS, guild, LinkEmbedFeatureMode.DELETE_BUTTON)).thenReturn(false);
|
||||
when(userService.retrieveUserForId(USER_ID)).thenReturn(CompletableFuture.completedFuture(embeddedUser));
|
||||
testUnit.embedLink(cachedMessage, textChannel, userEmbeddingUserInServerId, embeddingMessage);
|
||||
verify(messageCache, times(0)).getMessageFromCache(anyLong(), anyLong(), anyLong());
|
||||
@@ -243,18 +250,16 @@ public class MessageEmbedServiceBeanTest {
|
||||
List<CompletableFuture<Message>> messageFutures = CommandTestUtilities.messageFutureList();
|
||||
when(channelService.sendMessageToSendToChannel(messageToSend, textChannel)).thenReturn(messageFutures);
|
||||
Message createdMessage = messageFutures.get(0).join();
|
||||
when(reactionService.addReactionToMessageAsync(MessageEmbedServiceBean.REMOVAL_EMOTE, cachedMessage.getServerId(),
|
||||
createdMessage)).thenReturn(CompletableFuture.completedFuture(null));
|
||||
CompletableFuture<Void> future = testUnit.sendEmbeddingMessage(cachedMessage, textChannel, EMBEDDING_USER_IN_SERVER_ID, embeddedModel);
|
||||
when(self.addDeletionPossibility(cachedMessage, embeddedModel, createdMessage, 0L, false)).thenReturn(CompletableFuture.completedFuture(null));
|
||||
CompletableFuture<Void> future = testUnit.sendEmbeddingMessage(cachedMessage, textChannel, EMBEDDING_USER_IN_SERVER_ID, embeddedModel, false);
|
||||
Assert.assertFalse(future.isCompletedExceptionally());
|
||||
verify(self, times(1)).loadUserAndPersistMessage(cachedMessage, EMBEDDING_USER_IN_SERVER_ID, createdMessage);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLoadUserAndPersistMessage() {
|
||||
when(userInServerManagementService.loadOrCreateUser(EMBEDDING_USER_IN_SERVER_ID)).thenReturn(embeddingUser);
|
||||
testUnit.loadUserAndPersistMessage(cachedMessage, EMBEDDING_USER_IN_SERVER_ID, embeddingMessage);
|
||||
verify(messageEmbedPostManagementService, times(1)).createMessageEmbed(cachedMessage, embeddingMessage, embeddingUser);
|
||||
testUnit.loadUserAndPersistMessage(cachedMessage, EMBEDDING_USER_IN_SERVER_ID, embeddingMessage, null);
|
||||
verify(messageEmbedPostManagementService, times(1)).createMessageEmbed(cachedMessage, embeddingMessage, embeddingUser, null);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -265,7 +270,7 @@ public class MessageEmbedServiceBeanTest {
|
||||
when(embeddingMessage.getGuild()).thenReturn(guild);
|
||||
when(embeddingMessage.getChannel()).thenReturn(textChannel);
|
||||
when(embeddingMessage.getMember()).thenReturn(embeddingMember);
|
||||
MessageEmbeddedModel createdModel = testUnit.loadMessageEmbedModel(embeddingMessage, cachedMessage, embeddedUser);
|
||||
MessageEmbeddedModel createdModel = testUnit.loadMessageEmbedModel(embeddingMessage, cachedMessage, embeddedUser, false);
|
||||
Assert.assertEquals(textChannel, createdModel.getSourceChannel());
|
||||
Assert.assertEquals(guild, createdModel.getGuild());
|
||||
Assert.assertEquals(textChannel, createdModel.getMessageChannel());
|
||||
|
||||
@@ -80,7 +80,7 @@ public class MessageEmbedPostManagementServiceBeanTest {
|
||||
when(guild.getIdLong()).thenReturn(SERVER_ID);
|
||||
when(embeddingMessage.getIdLong()).thenReturn(EMBEDDING_MESSAGE_ID);
|
||||
when(userInServerManagementService.loadOrCreateUser(SERVER_ID, EMBEDDED_USER_ID)).thenReturn(embeddedUser);
|
||||
testUnit.createMessageEmbed(cachedMessage, embeddingMessage, embeddingUser);
|
||||
testUnit.createMessageEmbed(cachedMessage, embeddingMessage, embeddingUser, null);
|
||||
verify(embeddedMessageRepository, times(1)).save(messageArgumentCaptor.capture());
|
||||
EmbeddedMessage savedMessage = messageArgumentCaptor.getValue();
|
||||
Assert.assertEquals(EMBEDDED_MESSAGE_ID, savedMessage.getEmbeddedMessageId());
|
||||
@@ -108,7 +108,7 @@ public class MessageEmbedPostManagementServiceBeanTest {
|
||||
Guild guild = Mockito.mock(Guild.class);
|
||||
when(message.getGuild()).thenReturn(guild);
|
||||
when(guild.getIdLong()).thenReturn(SERVER_ID);
|
||||
testUnit.createMessageEmbed(cachedMessage, message, embeddingUser);
|
||||
testUnit.createMessageEmbed(cachedMessage, message, embeddingUser, null);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
Reference in New Issue
Block a user