[AB-296] adding support for buttons

adding buttons for message embed via feature mode
This commit is contained in:
Sheldan
2021-07-03 10:40:27 +02:00
parent bbc5918d88
commit 61eefd53c3
63 changed files with 1379 additions and 104 deletions

View File

@@ -3,6 +3,8 @@ package dev.sheldan.abstracto.core.command.service;
import dev.sheldan.abstracto.core.command.Command;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.listener.async.jda.ButtonClickedListener;
import dev.sheldan.abstracto.core.models.listener.ButtonClickedListenerModel;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.MessageChannel;
import net.dv8tion.jda.api.events.message.guild.GuildMessageReceivedEvent;
@@ -10,6 +12,7 @@ import net.dv8tion.jda.api.events.message.priv.PrivateMessageReceivedEvent;
public interface ExceptionService {
CommandResult reportExceptionToContext(Throwable exception, CommandContext context, Command command);
void reportExceptionToInteraction(Throwable exception, ButtonClickedListenerModel interActionContext, ButtonClickedListener executedListener);
void reportExceptionToGuildMessageReceivedContext(Throwable exception, GuildMessageReceivedEvent event);
void reportExceptionToPrivateMessageReceivedContext(Throwable exception, PrivateMessageReceivedEvent event);
void reportExceptionToChannel(Throwable exception, MessageChannel channel, Member member);

View File

@@ -0,0 +1,28 @@
package dev.sheldan.abstracto.core.interaction;
import dev.sheldan.abstracto.core.templating.Templatable;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.User;
@Getter
@Setter
@Builder
public class GenericInteractionExceptionModel {
private Member member;
private User user;
private Throwable throwable;
public Templatable getTemplate() {
Throwable current = throwable;
while(!(current instanceof Templatable) && (current.getCause() != null && !current.getCause().equals(current))) {
current = current.getCause();
}
if(current instanceof Templatable) {
return (Templatable) current;
}
return null;
}
}

View File

@@ -0,0 +1,31 @@
package dev.sheldan.abstracto.core.interaction;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
@Builder
public class InteractionResult {
private InteractionResultState result;
private String message;
private Throwable throwable;
public static InteractionResult fromSuccess() {
return InteractionResult.builder().result(InteractionResultState.SUCCESSFUL).build();
}
public static InteractionResult fromError(String message){
return InteractionResult.builder().result(InteractionResultState.ERROR).message(message).build();
}
public static InteractionResult fromError(String message, Throwable throwable) {
return InteractionResult.builder().result(InteractionResultState.ERROR).message(message).throwable(throwable).build();
}
public static InteractionResult fromIgnored() {
return InteractionResult.builder().result(InteractionResultState.IGNORED).build();
}
}

View File

@@ -0,0 +1,5 @@
package dev.sheldan.abstracto.core.interaction;
public enum InteractionResultState {
ERROR, SUCCESSFUL, IGNORED
}

View File

@@ -0,0 +1,13 @@
package dev.sheldan.abstracto.core.interaction;
import dev.sheldan.abstracto.core.templating.model.MessageToSend;
import net.dv8tion.jda.api.entities.Message;
import net.dv8tion.jda.api.interactions.InteractionHook;
import java.util.List;
import java.util.concurrent.CompletableFuture;
public interface InteractionService {
List<CompletableFuture<Message>> sendMessageToInteraction(MessageToSend messageToSend, InteractionHook interactionHook);
List<CompletableFuture<Message>> sendMessageToInteraction(String templateKey, Object model, InteractionHook interactionHook);
}

View File

@@ -0,0 +1,8 @@
package dev.sheldan.abstracto.core.interaction;
import dev.sheldan.abstracto.core.listener.async.jda.ButtonClickedListener;
import dev.sheldan.abstracto.core.models.listener.ButtonClickedListenerModel;
public interface PostInteractionExecution {
void execute(ButtonClickedListenerModel interActionContext, InteractionResult interactionResult, ButtonClickedListener executedListener);
}

View File

@@ -0,0 +1,5 @@
package dev.sheldan.abstracto.core.listener;
public enum ButtonClickedListenerResult implements ListenerExecutionResult {
ACKNOWLEDGED, IGNORED
}

View File

@@ -0,0 +1,10 @@
package dev.sheldan.abstracto.core.listener.async.jda;
import dev.sheldan.abstracto.core.Prioritized;
import dev.sheldan.abstracto.core.listener.ButtonClickedListenerResult;
import dev.sheldan.abstracto.core.listener.FeatureAwareListener;
import dev.sheldan.abstracto.core.models.listener.ButtonClickedListenerModel;
public interface ButtonClickedListener extends FeatureAwareListener<ButtonClickedListenerModel, ButtonClickedListenerResult>, Prioritized {
Boolean handlesEvent(ButtonClickedListenerModel model);
}

View File

@@ -0,0 +1,40 @@
package dev.sheldan.abstracto.core.models.database;
import lombok.*;
import javax.persistence.*;
import java.time.Instant;
@Entity
@Table(name = "component_payload")
@Getter
@Builder
@Setter
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode
public class ComponentPayload {
@Id
@Column(name = "id", nullable = false, length = 100)
private String id;
@ManyToOne(fetch = FetchType.LAZY)
@Getter
@Setter
@JoinColumn(name = "server_id", nullable = false)
private AServer server;
@Lob
@org.hibernate.annotations.Type(type = "org.hibernate.type.TextType")
@Column(name = "payload")
private String payload;
@Column(name = "payload_type", length = 255)
private String payloadType;
@Column(name = "origin", length = 128)
private String origin;
@Column(name = "created", nullable = false, insertable = false, updatable = false)
private Instant created;
}

View File

@@ -0,0 +1,24 @@
package dev.sheldan.abstracto.core.models.listener;
import dev.sheldan.abstracto.core.listener.FeatureAwareListenerModel;
import dev.sheldan.abstracto.core.models.template.button.ButtonPayload;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
import net.dv8tion.jda.api.events.interaction.ButtonClickEvent;
@Getter
@Setter
@Builder
public class ButtonClickedListenerModel implements FeatureAwareListenerModel {
private ButtonClickEvent event;
private String payload;
private String origin;
private ButtonPayload deserializedPayload;
@Override
public Long getServerId() {
return event.getGuild().getIdLong();
}
}

View File

@@ -0,0 +1,15 @@
package dev.sheldan.abstracto.core.models.template.button;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
@Builder
public class ButtonConfigModel {
private String buttonId;
private ButtonPayload buttonPayload;
private Class payloadType;
private String origin;
}

View File

@@ -0,0 +1,4 @@
package dev.sheldan.abstracto.core.models.template.button;
public interface ButtonPayload {
}

View File

@@ -1,20 +0,0 @@
package dev.sheldan.abstracto.core.models.template.listener;
import dev.sheldan.abstracto.core.models.cache.CachedMessage;
import dev.sheldan.abstracto.core.models.context.UserInitiatedServerContext;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.SuperBuilder;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.TextChannel;
import net.dv8tion.jda.api.entities.User;
@Getter
@Setter
@SuperBuilder
public class MessageEmbeddedModel extends UserInitiatedServerContext {
private CachedMessage embeddedMessage;
private User author;
private TextChannel sourceChannel;
private Member embeddingUser;
}

View File

@@ -1,7 +1,9 @@
package dev.sheldan.abstracto.core.service;
import dev.sheldan.abstracto.core.models.database.AllowedMention;
import dev.sheldan.abstracto.core.templating.model.MessageToSend;
import net.dv8tion.jda.api.entities.Message;
import net.dv8tion.jda.api.entities.MessageChannel;
import java.util.Set;
@@ -13,4 +15,5 @@ public interface AllowedMentionService {
AllowedMention getDefaultAllowedMention();
AllowedMention getEffectiveAllowedMention(Long serverId);
Message.MentionType getMentionTypeFromString(String input);
Set<Message.MentionType> getAllowedMentionsFor(MessageChannel channel, MessageToSend messageToSend);
}

View File

@@ -0,0 +1,6 @@
package dev.sheldan.abstracto.core.service;
public interface ComponentService {
String generateComponentId(Long serverId);
String generateComponentId();
}

View File

@@ -6,6 +6,7 @@ import dev.sheldan.abstracto.core.config.FeatureMode;
import dev.sheldan.abstracto.core.models.database.AFeature;
import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.models.template.commands.FeatureModeDisplay;
import net.dv8tion.jda.api.entities.Guild;
import java.util.List;
@@ -16,6 +17,7 @@ public interface FeatureModeService {
void disableFeatureModeForFeature(FeatureDefinition featureDefinition, AServer server, FeatureMode mode);
boolean featureModeActive(FeatureDefinition featureDefinition, AServer server, FeatureMode mode);
boolean featureModeActive(FeatureDefinition featureDefinition, Long serverId, FeatureMode mode);
boolean featureModeActive(FeatureDefinition featureDefinition, Guild guild, FeatureMode mode);
void validateActiveFeatureMode(Long serverId, FeatureDefinition featureDefinition, FeatureMode mode);
FeatureMode getFeatureModeForKey(String key);
List<FeatureMode> getAllAvailableFeatureModes();

View File

@@ -39,4 +39,5 @@ public interface MessageService {
MessageAction editMessage(Message message, String text, MessageEmbed messageEmbed);
AuditableRestAction<Void> deleteMessageWithAction(Message message);
CompletableFuture<Void> deleteMessage(Message message);
CompletableFuture<Void> clearButtons(Message message);
}

View File

@@ -0,0 +1,16 @@
package dev.sheldan.abstracto.core.service.management;
import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.models.database.ComponentPayload;
import dev.sheldan.abstracto.core.models.template.button.ButtonConfigModel;
import java.util.List;
import java.util.Optional;
public interface ComponentPayloadManagementService {
ComponentPayload createPayload(String id, String payload, Class payloadType, String buttonOrigin, AServer server);
ComponentPayload createPayload(ButtonConfigModel buttonConfigModel, AServer server);
Optional<ComponentPayload> findPayload(String id);
List<ComponentPayload> findPayloadsOfOriginInServer(String buttonOrigin, AServer server);
void deletePayload(String id);
}

View File

@@ -4,10 +4,13 @@ import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
import net.dv8tion.jda.api.entities.MessageEmbed;
import net.dv8tion.jda.api.interactions.components.ActionRow;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* A full message which is ready to be send. This message can contain an arbitrary amount of embeds and a string message.
@@ -32,8 +35,25 @@ public class MessageToSend {
private File fileToSend;
private MessageConfig messageConfig;
private Long referencedMessageId;
@Builder.Default
private List<ActionRow> actionRows = new ArrayList<>();
@Builder.Default
private Map<String, ComponentConfig> componentPayloads = new HashMap<>();
@Builder.Default
private Boolean ephemeral = false;
public boolean hasFileToSend() {
return fileToSend != null;
}
@Getter
@Setter
@Builder
public static class ComponentConfig {
private String payload;
private String componentOrigin;
private Class payloadType;
private Boolean persistCallback;
}
}