[AB-365] introducing slash commands for a selection of commands

adding method for pinning a message
moving suggestion to correct deployment
This commit is contained in:
Sheldan
2022-05-17 00:39:06 +02:00
parent 1913bc930d
commit 1d6de3f1e8
286 changed files with 8021 additions and 3065 deletions

View File

@@ -5,16 +5,22 @@ import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand
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.config.SlashCommandConfig;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.command.execution.ContextConverter;
import dev.sheldan.abstracto.core.config.FeatureDefinition;
import dev.sheldan.abstracto.core.interaction.InteractionService;
import dev.sheldan.abstracto.core.models.template.display.EmoteDisplay;
import dev.sheldan.abstracto.core.service.ChannelService;
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.utility.config.UtilityFeatureDefinition;
import dev.sheldan.abstracto.utility.config.UtilitySlashCommandNames;
import dev.sheldan.abstracto.utility.model.ServerInfoModel;
import lombok.extern.slf4j.Slf4j;
import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@@ -27,25 +33,44 @@ import java.util.concurrent.CompletableFuture;
public class ServerInfo extends AbstractConditionableCommand {
public static final String SERVERINFO_RESPONSE_TEMPLATE_KEY = "serverinfo_response";
private static final String SERVER_INFO_COMMAND = "serverInfo";
@Autowired
private ChannelService channelService;
@Autowired
private TemplateService templateService;
@Autowired
private InteractionService interactionService;
@Override
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
log.info("Displaying serverinfo for server {}", commandContext.getGuild().getId());
ServerInfoModel model = buildModel(commandContext);
return FutureUtils.toSingleFutureGeneric(
channelService.sendEmbedTemplateInTextChannelList(SERVERINFO_RESPONSE_TEMPLATE_KEY, model, commandContext.getChannel()))
channelService.sendMessageToSendToChannel(getMessageToSend(commandContext.getGuild()), commandContext.getChannel()))
.thenApply(aVoid -> CommandResult.fromIgnored());
}
private ServerInfoModel buildModel(CommandContext commandContext) {
ServerInfoModel model = (ServerInfoModel) ContextConverter.fromCommandContext(commandContext, ServerInfoModel.class);
model.setGuild(commandContext.getGuild());
model.setTimeCreated(commandContext.getGuild().getTimeCreated().toInstant());
@Override
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
return interactionService.replyMessageToSend(getMessageToSend(event.getGuild()), event)
.thenApply(interactionHook -> CommandResult.fromSuccess());
}
private MessageToSend getMessageToSend(Guild guild) {
return templateService.renderEmbedTemplate(SERVERINFO_RESPONSE_TEMPLATE_KEY, buildModel(guild), guild.getIdLong());
}
private ServerInfoModel buildModel(Guild guild) {
ServerInfoModel model = ServerInfoModel
.builder()
.guild(guild)
.timeCreated(guild.getTimeCreated().toInstant())
.build();
List<EmoteDisplay> staticEmotes = new ArrayList<>();
List<EmoteDisplay> animatedEmotes = new ArrayList<>();
commandContext.getGuild().getEmotes().forEach(emote -> {
guild.getEmotes().forEach(emote -> {
EmoteDisplay emoteDisplay = EmoteDisplay.fromEmote(emote);
if(emote.isAnimated()) {
animatedEmotes.add(emoteDisplay);
@@ -61,9 +86,21 @@ public class ServerInfo extends AbstractConditionableCommand {
@Override
public CommandConfiguration getConfiguration() {
List<Parameter> parameters = new ArrayList<>();
HelpInfo helpInfo = HelpInfo.builder().templated(true).build();
HelpInfo helpInfo = HelpInfo
.builder()
.templated(true)
.build();
SlashCommandConfig slashCommandConfig = SlashCommandConfig
.builder()
.enabled(true)
.rootCommandName(UtilitySlashCommandNames.UTILITY)
.commandName(SERVER_INFO_COMMAND)
.build();
return CommandConfiguration.builder()
.name("serverInfo")
.name(SERVER_INFO_COMMAND)
.slashCommandConfig(slashCommandConfig)
.module(UtilityModuleDefinition.UTILITY)
.templated(true)
.async(true)

View File

@@ -5,17 +5,21 @@ import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand
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.config.SlashCommandConfig;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.command.execution.ContextConverter;
import dev.sheldan.abstracto.core.command.slash.parameter.SlashCommandParameterService;
import dev.sheldan.abstracto.core.config.FeatureDefinition;
import dev.sheldan.abstracto.core.exception.EntityGuildMismatchException;
import dev.sheldan.abstracto.core.interaction.InteractionService;
import dev.sheldan.abstracto.core.service.ChannelService;
import dev.sheldan.abstracto.core.utils.FutureUtils;
import dev.sheldan.abstracto.utility.config.UtilityFeatureDefinition;
import dev.sheldan.abstracto.utility.config.UtilitySlashCommandNames;
import dev.sheldan.abstracto.utility.model.ShowAvatarModel;
import lombok.extern.slf4j.Slf4j;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@@ -28,9 +32,18 @@ import java.util.concurrent.CompletableFuture;
public class ShowAvatar extends AbstractConditionableCommand {
public static final String SHOW_AVATAR_RESPONSE_TEMPLATE = "showAvatar_response";
private static final String MEMBER_PARAMETER = "member";
private static final String SHOW_AVATAR_COMMAND = "showAvatar";
@Autowired
private ChannelService channelService;
@Autowired
private SlashCommandParameterService slashCommandParameterService;
@Autowired
private InteractionService interactionService;
@Override
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
List<Object> parameters = commandContext.getParameters().getParameters();
@@ -38,21 +51,58 @@ public class ShowAvatar extends AbstractConditionableCommand {
if(!memberToShow.getGuild().equals(commandContext.getGuild())) {
throw new EntityGuildMismatchException();
}
ShowAvatarModel model = (ShowAvatarModel) ContextConverter.fromCommandContext(commandContext, ShowAvatarModel.class);
ShowAvatarModel model = ShowAvatarModel
.builder()
.memberInfo(memberToShow)
.build();
log.info("Showing avatar for member {} towards user {} in channel {} in server {}.",
memberToShow.getId(), commandContext.getAuthor().getId(), commandContext.getChannel().getId(), commandContext.getGuild().getId());
model.setMemberInfo(memberToShow);
return FutureUtils.toSingleFutureGeneric(channelService.sendEmbedTemplateInTextChannelList(SHOW_AVATAR_RESPONSE_TEMPLATE, model, commandContext.getChannel()))
.thenApply(aVoid -> CommandResult.fromIgnored());
}
@Override
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
Member memberToShow;
if(slashCommandParameterService.hasCommandOption(MEMBER_PARAMETER, event)) {
memberToShow = slashCommandParameterService.getCommandOption(MEMBER_PARAMETER, event, Member.class);
} else {
memberToShow = event.getMember();
}
ShowAvatarModel model = ShowAvatarModel
.builder()
.memberInfo(memberToShow)
.build();
return interactionService.replyEmbed(SHOW_AVATAR_RESPONSE_TEMPLATE, model, event.getInteraction())
.thenApply(interactionHook -> CommandResult.fromSuccess());
}
@Override
public CommandConfiguration getConfiguration() {
List<Parameter> parameters = new ArrayList<>();
parameters.add(Parameter.builder().type(Member.class).name("member").templated(true).optional(true).build());
HelpInfo helpInfo = HelpInfo.builder().templated(true).build();
Parameter memberParameter = Parameter
.builder()
.type(Member.class)
.name(MEMBER_PARAMETER)
.templated(true)
.optional(true)
.build();
parameters.add(memberParameter);
HelpInfo helpInfo = HelpInfo
.builder()
.templated(true)
.build();
SlashCommandConfig slashCommandConfig = SlashCommandConfig
.builder()
.enabled(true)
.rootCommandName(UtilitySlashCommandNames.UTILITY)
.commandName(SHOW_AVATAR_COMMAND)
.build();
return CommandConfiguration.builder()
.name("showAvatar")
.name(SHOW_AVATAR_COMMAND)
.slashCommandConfig(slashCommandConfig)
.module(UtilityModuleDefinition.UTILITY)
.templated(true)
.async(true)

View File

@@ -5,15 +5,20 @@ import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand
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.config.SlashCommandConfig;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.command.execution.ContextConverter;
import dev.sheldan.abstracto.core.command.slash.parameter.SlashCommandParameterService;
import dev.sheldan.abstracto.core.config.FeatureDefinition;
import dev.sheldan.abstracto.core.interaction.InteractionService;
import dev.sheldan.abstracto.core.service.ChannelService;
import dev.sheldan.abstracto.core.utils.FutureUtils;
import dev.sheldan.abstracto.utility.config.UtilityFeatureDefinition;
import dev.sheldan.abstracto.utility.config.UtilitySlashCommandNames;
import dev.sheldan.abstracto.utility.model.ShowEmoteLog;
import net.dv8tion.jda.api.entities.Emoji;
import net.dv8tion.jda.api.entities.Emote;
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@@ -25,27 +30,68 @@ import java.util.concurrent.CompletableFuture;
public class ShowEmote extends AbstractConditionableCommand {
public static final String SHOW_EMOTE_RESPONSE_TEMPLATE = "showEmote_response";
public static final String SHOW_EMOTE_COMMAND = "showEmote";
public static final String EMOTE_PARAMETER = "emote";
@Autowired
private ChannelService channelService;
@Autowired
private InteractionService interactionService;
@Autowired
private SlashCommandParameterService slashCommandParameterService;
@Override
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
List<Object> parameters = commandContext.getParameters().getParameters();
Emote emoteParameter = (Emote) parameters.get(0);
ShowEmoteLog emoteLog = (ShowEmoteLog) ContextConverter.fromCommandContext(commandContext, ShowEmoteLog.class);
emoteLog.setEmote(emoteParameter);
ShowEmoteLog emoteLog = ShowEmoteLog
.builder()
.emote(emoteParameter)
.build();
return FutureUtils.toSingleFutureGeneric(channelService.sendEmbedTemplateInTextChannelList(SHOW_EMOTE_RESPONSE_TEMPLATE, emoteLog, commandContext.getChannel()))
.thenApply(aVoid -> CommandResult.fromIgnored());
}
@Override
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
String emoteText = slashCommandParameterService.getCommandOption(EMOTE_PARAMETER, event, Emote.class, String.class);
Emoji emoji = Emoji.fromMarkdown(emoteText);
Emote emote = event.getJDA().getEmoteById(emoji.getId());
ShowEmoteLog emoteLog = ShowEmoteLog
.builder()
.emote(emote)
.build();
return interactionService.replyEmbed(SHOW_EMOTE_RESPONSE_TEMPLATE, emoteLog, event)
.thenApply(interactionHook -> CommandResult.fromSuccess());
}
@Override
public CommandConfiguration getConfiguration() {
List<Parameter> parameters = new ArrayList<>();
parameters.add(Parameter.builder().name("emote").type(Emote.class).templated(true).build());
HelpInfo helpInfo = HelpInfo.builder().templated(true).build();
Parameter emoteParameter = Parameter
.builder()
.name(EMOTE_PARAMETER)
.type(Emote.class)
.templated(true)
.build();
parameters.add(emoteParameter);
HelpInfo helpInfo = HelpInfo
.builder()
.templated(true)
.build();
SlashCommandConfig slashCommandConfig = SlashCommandConfig
.builder()
.enabled(true)
.rootCommandName(UtilitySlashCommandNames.UTILITY)
.commandName(SHOW_EMOTE_COMMAND)
.build();
return CommandConfiguration.builder()
.name("showEmote")
.name(SHOW_EMOTE_COMMAND)
.slashCommandConfig(slashCommandConfig)
.module(UtilityModuleDefinition.UTILITY)
.templated(true)
.async(true)

View File

@@ -5,18 +5,26 @@ import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand
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.config.SlashCommandConfig;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.command.execution.ContextConverter;
import dev.sheldan.abstracto.core.command.slash.parameter.SlashCommandParameterService;
import dev.sheldan.abstracto.core.config.FeatureDefinition;
import dev.sheldan.abstracto.core.exception.EntityGuildMismatchException;
import dev.sheldan.abstracto.core.interaction.InteractionService;
import dev.sheldan.abstracto.core.service.ChannelService;
import dev.sheldan.abstracto.core.service.MemberService;
import dev.sheldan.abstracto.core.utils.FutureUtils;
import dev.sheldan.abstracto.utility.config.UtilityFeatureDefinition;
import dev.sheldan.abstracto.utility.config.UtilitySlashCommandNames;
import dev.sheldan.abstracto.utility.model.UserInfoModel;
import lombok.extern.slf4j.Slf4j;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.Message;
import net.dv8tion.jda.api.entities.MessageChannel;
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
import net.dv8tion.jda.api.interactions.InteractionHook;
import net.dv8tion.jda.api.interactions.callbacks.IReplyCallback;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
@@ -29,6 +37,9 @@ import java.util.concurrent.CompletableFuture;
@Slf4j
public class UserInfo extends AbstractConditionableCommand {
public static final String USER_INFO_COMMAND = "userInfo";
public static final String MEMBER_PARAMETER = "member";
public static final String USER_INFO_RESPONSE = "userInfo_response";
@Autowired
private ChannelService channelService;
@@ -38,6 +49,12 @@ public class UserInfo extends AbstractConditionableCommand {
@Autowired
private UserInfo self;
@Autowired
private SlashCommandParameterService slashCommandParameterService;
@Autowired
private InteractionService interactionService;
@Override
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
List<Object> parameters = commandContext.getParameters().getParameters();
@@ -45,37 +62,95 @@ public class UserInfo extends AbstractConditionableCommand {
if(!memberToShow.getGuild().equals(commandContext.getGuild())) {
throw new EntityGuildMismatchException();
}
UserInfoModel model = (UserInfoModel) ContextConverter.slimFromCommandContext(commandContext, UserInfoModel.class);
UserInfoModel model = UserInfoModel
.builder()
.build();
if(!memberToShow.hasTimeJoined()) {
log.info("Force reloading member {} in guild {} for user info.", memberToShow.getId(), memberToShow.getGuild().getId());
return memberService.forceReloadMember(memberToShow).thenCompose(member -> {
model.setMemberInfo(member);
model.setCreationDate(member.getTimeCreated().toInstant());
model.setJoinDate(member.getTimeJoined().toInstant());
return self.sendResponse(commandContext, model)
return self.sendResponse(commandContext.getChannel(), model)
.thenApply(aVoid -> CommandResult.fromIgnored());
});
} else {
model.setMemberInfo(memberToShow);
model.setCreationDate(memberToShow.getTimeCreated().toInstant());
model.setJoinDate(memberToShow.getTimeJoined().toInstant());
return self.sendResponse(commandContext, model)
return self.sendResponse(commandContext.getChannel(), model)
.thenApply(aVoid -> CommandResult.fromIgnored());
}
}
@Transactional
public CompletableFuture<Void> sendResponse(CommandContext commandContext, UserInfoModel model) {
return FutureUtils.toSingleFutureGeneric(channelService.sendEmbedTemplateInTextChannelList("userInfo_response", model, commandContext.getChannel()));
public CompletableFuture<Void> sendResponse(MessageChannel channel, UserInfoModel model) {
return FutureUtils.toSingleFutureGeneric(channelService.sendEmbedTemplateInTextChannelList(USER_INFO_RESPONSE, model, channel));
}
@Transactional
public CompletableFuture<InteractionHook> sendResponse(IReplyCallback callback, UserInfoModel model) {
return interactionService.replyEmbed(USER_INFO_RESPONSE, model, callback);
}
@Override
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
Member memberToShow;
if(slashCommandParameterService.hasCommandOption(MEMBER_PARAMETER, event)) {
memberToShow = slashCommandParameterService.getCommandOption(MEMBER_PARAMETER, event, Member.class);
} else {
memberToShow = event.getMember();
}
if(!memberToShow.getGuild().equals(event.getGuild())) {
throw new EntityGuildMismatchException();
}
UserInfoModel model = UserInfoModel
.builder()
.build();
if(!memberToShow.hasTimeJoined()) {
log.info("Force reloading member {} in guild {} for user info.", memberToShow.getId(), memberToShow.getGuild().getId());
return memberService.forceReloadMember(memberToShow).thenCompose(member -> {
model.setMemberInfo(member);
model.setCreationDate(member.getTimeCreated().toInstant());
model.setJoinDate(member.getTimeJoined().toInstant());
return self.sendResponse(event, model)
.thenApply(aVoid -> CommandResult.fromIgnored());
});
} else {
model.setMemberInfo(memberToShow);
model.setCreationDate(memberToShow.getTimeCreated().toInstant());
model.setJoinDate(memberToShow.getTimeJoined().toInstant());
return self.sendResponse(event, model)
.thenApply(aVoid -> CommandResult.fromIgnored());
}
}
@Override
public CommandConfiguration getConfiguration() {
List<Parameter> parameters = new ArrayList<>();
parameters.add(Parameter.builder().type(Member.class).name("member").templated(true).optional(true).build());
HelpInfo helpInfo = HelpInfo.builder().templated(true).build();
Parameter memberParameter = Parameter
.builder()
.type(Member.class)
.name(MEMBER_PARAMETER)
.templated(true)
.optional(true)
.build();
parameters.add(memberParameter);
HelpInfo helpInfo = HelpInfo
.builder()
.templated(true)
.build();
SlashCommandConfig slashCommandConfig = SlashCommandConfig
.builder()
.enabled(true)
.rootCommandName(UtilitySlashCommandNames.UTILITY)
.commandName(USER_INFO_COMMAND)
.build();
return CommandConfiguration.builder()
.name("userInfo")
.name(USER_INFO_COMMAND)
.slashCommandConfig(slashCommandConfig)
.module(UtilityModuleDefinition.UTILITY)
.templated(true)
.async(true)