reworked exception handling, different exceptions whether or why it failed, all of which are unchecked

added feature flags for commands/listeners
added enable/disable command
added feature flag handling to command received handler
added boolean parameter support
fixed 1 parameter commands
fixed posttargets not working on multiple servers, removed unique constraint on posttarget names
added setup validation to suggestions
added quartz property loader
moved join/leave logger to moderation
reworked the way the message listener are handled (separate listener around)
This commit is contained in:
Sheldan
2020-04-04 12:55:01 +02:00
parent c9557fccc2
commit bf94af66d5
132 changed files with 1378 additions and 530 deletions

View File

@@ -1,11 +1,11 @@
package dev.sheldan.abstracto.moderation.command;
import dev.sheldan.abstracto.command.Command;
import dev.sheldan.abstracto.command.AbstractFeatureFlaggedCommand;
import dev.sheldan.abstracto.command.HelpInfo;
import dev.sheldan.abstracto.command.execution.*;
import dev.sheldan.abstracto.moderation.Moderation;
import dev.sheldan.abstracto.moderation.config.ModerationFeatures;
import dev.sheldan.abstracto.moderation.models.template.BanLog;
import dev.sheldan.abstracto.moderation.models.template.WarnLog;
import dev.sheldan.abstracto.moderation.service.BanService;
import dev.sheldan.abstracto.templating.TemplateService;
import lombok.extern.slf4j.Slf4j;
@@ -18,7 +18,7 @@ import java.util.List;
@Component
@Slf4j
public class Ban implements Command {
public class Ban extends AbstractFeatureFlaggedCommand {
@Autowired
private BanService banService;
@@ -27,7 +27,7 @@ public class Ban implements Command {
private TemplateService templateService;
@Override
public Result execute(CommandContext commandContext) {
public CommandResult execute(CommandContext commandContext) {
List<Object> parameters = commandContext.getParameters().getParameters();
Member member = (Member) parameters.get(0);
String defaultReason = templateService.renderTemplate("ban_default_reason", null);
@@ -38,7 +38,7 @@ public class Ban implements Command {
banLogModel.setBanningUser(commandContext.getAuthor());
banLogModel.setReason(reason);
banService.banMember(member, reason, banLogModel);
return Result.fromSuccess();
return CommandResult.fromSuccess();
}
@Override
@@ -56,4 +56,9 @@ public class Ban implements Command {
.help(helpInfo)
.build();
}
@Override
public String getFeature() {
return ModerationFeatures.MODERATION;
}
}

View File

@@ -1,19 +1,21 @@
package dev.sheldan.abstracto.moderation.command;
import dev.sheldan.abstracto.command.Command;
import dev.sheldan.abstracto.command.AbstractFeatureFlaggedCommand;
import dev.sheldan.abstracto.command.HelpInfo;
import dev.sheldan.abstracto.command.execution.*;
import dev.sheldan.abstracto.core.models.UserInitiatedServerContext;
import dev.sheldan.abstracto.moderation.Moderation;
import dev.sheldan.abstracto.moderation.config.ModerationFeatures;
import dev.sheldan.abstracto.moderation.models.template.BanIdLog;
import dev.sheldan.abstracto.moderation.service.BanService;
import dev.sheldan.abstracto.templating.TemplateService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
public class BanId implements Command {
@Component
public class BanId extends AbstractFeatureFlaggedCommand {
@Autowired
private TemplateService templateService;
@@ -22,7 +24,7 @@ public class BanId implements Command {
private BanService banService;
@Override
public Result execute(CommandContext commandContext) {
public CommandResult execute(CommandContext commandContext) {
List<Object> parameters = commandContext.getParameters().getParameters();
Long userId = (Long) parameters.get(0);
String defaultReason = templateService.renderTemplate("ban_default_reason", null);
@@ -33,7 +35,7 @@ public class BanId implements Command {
banLogModel.setReason(reason);
banService.banMember(userId, commandContext.getGuild().getIdLong(), reason, banLogModel);
return Result.fromSuccess();
return CommandResult.fromSuccess();
}
@Override
@@ -51,4 +53,9 @@ public class BanId implements Command {
.help(helpInfo)
.build();
}
@Override
public String getFeature() {
return ModerationFeatures.MODERATION;
}
}

View File

@@ -1,10 +1,10 @@
package dev.sheldan.abstracto.moderation.command;
import dev.sheldan.abstracto.command.Command;
import dev.sheldan.abstracto.command.AbstractFeatureFlaggedCommand;
import dev.sheldan.abstracto.command.HelpInfo;
import dev.sheldan.abstracto.command.execution.*;
import dev.sheldan.abstracto.moderation.Moderation;
import dev.sheldan.abstracto.moderation.models.template.BanIdLog;
import dev.sheldan.abstracto.moderation.config.ModerationFeatures;
import dev.sheldan.abstracto.moderation.models.template.KickLogModel;
import dev.sheldan.abstracto.moderation.service.KickServiceBean;
import dev.sheldan.abstracto.templating.TemplateService;
@@ -16,15 +16,16 @@ import java.util.ArrayList;
import java.util.List;
@Component
public class Kick implements Command {
public class Kick extends AbstractFeatureFlaggedCommand {
@Autowired
private TemplateService templateService;
@Autowired
private KickServiceBean kickService;
@Override
public Result execute(CommandContext commandContext) {
public CommandResult execute(CommandContext commandContext) {
List<Object> parameters = commandContext.getParameters().getParameters();
Member member = (Member) parameters.get(0);
@@ -36,7 +37,7 @@ public class Kick implements Command {
kickLogModel.setKickingUser(commandContext.getAuthor());
kickLogModel.setReason(reason);
kickService.kickMember(member, reason, kickLogModel);
return Result.fromSuccess();
return CommandResult.fromSuccess();
}
@Override
@@ -54,4 +55,9 @@ public class Kick implements Command {
.help(helpInfo)
.build();
}
@Override
public String getFeature() {
return ModerationFeatures.MODERATION;
}
}

View File

@@ -1,12 +1,13 @@
package dev.sheldan.abstracto.moderation.command;
import dev.sheldan.abstracto.command.Command;
import dev.sheldan.abstracto.command.HelpInfo;
import dev.sheldan.abstracto.command.*;
import dev.sheldan.abstracto.command.execution.CommandConfiguration;
import dev.sheldan.abstracto.command.execution.CommandContext;
import dev.sheldan.abstracto.command.execution.Parameter;
import dev.sheldan.abstracto.command.execution.Result;
import dev.sheldan.abstracto.command.execution.CommandResult;
import dev.sheldan.abstracto.core.service.Bot;
import dev.sheldan.abstracto.moderation.Moderation;
import dev.sheldan.abstracto.moderation.config.ModerationFeatures;
import dev.sheldan.abstracto.moderation.service.SlowModeService;
import net.dv8tion.jda.api.entities.TextChannel;
import org.springframework.beans.factory.annotation.Autowired;
@@ -17,25 +18,22 @@ import java.util.ArrayList;
import java.util.List;
@Component
public class SlowMode implements Command {
public class SlowMode extends AbstractFeatureFlaggedCommand {
@Autowired
private SlowModeService slowModeService;
@Override
public Result execute(CommandContext commandContext) {
public CommandResult execute(CommandContext commandContext) {
TextChannel channel;
long seconds = (Long) commandContext.getParameters().getParameters().get(0);
if(commandContext.getParameters().getParameters().size() == 2) {
channel = (TextChannel) commandContext.getParameters().getParameters().get(1);
if(commandContext.getGuild().getGuildChannelById(channel.getIdLong()) == null) {
throw new IllegalArgumentException("Given channel was not part of the current guild.");
}
} else {
channel = commandContext.getChannel();
}
slowModeService.setSlowMode(channel, Duration.ofSeconds(seconds));
return Result.fromSuccess();
return CommandResult.fromSuccess();
}
@Override
@@ -53,4 +51,9 @@ public class SlowMode implements Command {
.help(helpInfo)
.build();
}
@Override
public String getFeature() {
return ModerationFeatures.MODERATION;
}
}

View File

@@ -1,12 +1,13 @@
package dev.sheldan.abstracto.moderation.command;
import dev.sheldan.abstracto.command.AbstractFeatureFlaggedCommand;
import dev.sheldan.abstracto.command.HelpInfo;
import dev.sheldan.abstracto.command.execution.*;
import dev.sheldan.abstracto.core.service.management.UserManagementService;
import dev.sheldan.abstracto.moderation.Moderation;
import dev.sheldan.abstracto.moderation.config.ModerationFeatures;
import dev.sheldan.abstracto.moderation.models.template.WarnLog;
import dev.sheldan.abstracto.moderation.service.WarnService;
import dev.sheldan.abstracto.command.Command;
import dev.sheldan.abstracto.command.HelpInfo;
import dev.sheldan.abstracto.core.management.UserManagementService;
import dev.sheldan.abstracto.templating.TemplateService;
import lombok.extern.slf4j.Slf4j;
import net.dv8tion.jda.api.entities.Member;
@@ -18,7 +19,7 @@ import java.util.List;
@Component
@Slf4j
public class Warn implements Command {
public class Warn extends AbstractFeatureFlaggedCommand {
@Autowired
private UserManagementService userManagementService;
@@ -30,7 +31,7 @@ public class Warn implements Command {
private TemplateService templateService;
@Override
public Result execute(CommandContext commandContext) {
public CommandResult execute(CommandContext commandContext) {
List<Object> parameters = commandContext.getParameters().getParameters();
Member member = (Member) parameters.get(0);
String defaultReason = templateService.renderTemplate("warn_default_reason", null);
@@ -41,7 +42,7 @@ public class Warn implements Command {
warnLogModel.setReason(reason);
warnLogModel.setWarningUser(commandContext.getAuthor());
warnService.warnUser(member, commandContext.getAuthor(), reason, warnLogModel);
return Result.fromSuccess();
return CommandResult.fromSuccess();
}
@Override
@@ -59,4 +60,9 @@ public class Warn implements Command {
.help(helpInfo)
.build();
}
@Override
public String getFeature() {
return ModerationFeatures.WARNINGS;
}
}

View File

@@ -0,0 +1,7 @@
package dev.sheldan.abstracto.moderation.config;
public class ModerationFeatures {
public static String MODERATION = "moderation";
public static String WARNINGS = "warnings";
public static String LOGGING = "logging";
}

View File

@@ -0,0 +1,54 @@
package dev.sheldan.abstracto.moderation.listener;
import dev.sheldan.abstracto.core.listener.JoinListener;
import dev.sheldan.abstracto.core.service.PostTargetService;
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
import dev.sheldan.abstracto.moderation.config.ModerationFeatures;
import dev.sheldan.abstracto.templating.TemplateService;
import lombok.extern.slf4j.Slf4j;
import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.User;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.annotation.Nonnull;
import java.util.HashMap;
@Service
@Slf4j
public class JoinLogger implements JoinListener {
private static final String USER_JOIN_TEMPLATE = "user_join";
private static final String JOIN_LOG_TARGET = "joinLog";
@Autowired
private ServerManagementService serverManagementService;
@Autowired
private TemplateService templateService;
@Autowired
private PostTargetService postTargetService;
@NotNull
private HashMap<String, Object> getUserParameter(@Nonnull User user) {
HashMap<String, Object> parameters = new HashMap<>();
parameters.put("user", user);
return parameters;
}
@Override
public void execute(Member member, Guild guild) {
HashMap<String, Object> parameters = getUserParameter(member.getUser());
String text = templateService.renderTemplate(USER_JOIN_TEMPLATE, parameters);;
postTargetService.sendTextInPostTarget(text, JOIN_LOG_TARGET, guild.getIdLong());
}
@Override
public String getFeature() {
return ModerationFeatures.LOGGING;
}
}

View File

@@ -0,0 +1,54 @@
package dev.sheldan.abstracto.moderation.listener;
import dev.sheldan.abstracto.core.listener.LeaveListener;
import dev.sheldan.abstracto.core.service.PostTargetService;
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
import dev.sheldan.abstracto.moderation.config.ModerationFeatures;
import dev.sheldan.abstracto.templating.TemplateService;
import lombok.extern.slf4j.Slf4j;
import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.User;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.annotation.Nonnull;
import java.util.HashMap;
@Service
@Slf4j
public class LeaveLogger implements LeaveListener {
private static final String USER_LEAVE_TEMPLATE = "user_leave";
private static final String LEAVE_LOG_TARGET = "leaveLog";
@Autowired
private ServerManagementService serverManagementService;
@Autowired
private TemplateService templateService;
@Autowired
private PostTargetService postTargetService;
@NotNull
private HashMap<String, Object> getUserParameter(@Nonnull User user) {
HashMap<String, Object> parameters = new HashMap<>();
parameters.put("user", user);
parameters.put("userMention", user.getAsMention());
return parameters;
}
@Override
public void execute(Member member, Guild guild) {
String text = templateService.renderTemplate(USER_LEAVE_TEMPLATE, getUserParameter(member.getUser()));
postTargetService.sendTextInPostTarget(text, LEAVE_LOG_TARGET, guild.getIdLong());
}
@Override
public String getFeature() {
return ModerationFeatures.LOGGING;
}
}

View File

@@ -2,12 +2,13 @@ package dev.sheldan.abstracto.moderation.listener;
import dev.sheldan.abstracto.core.listener.MessageDeletedListener;
import dev.sheldan.abstracto.core.models.CachedMessage;
import dev.sheldan.abstracto.core.utils.ContextUtils;
import dev.sheldan.abstracto.core.models.embed.MessageToSend;
import dev.sheldan.abstracto.core.service.MessageCache;
import dev.sheldan.abstracto.core.service.PostTargetService;
import dev.sheldan.abstracto.core.utils.ContextUtils;
import dev.sheldan.abstracto.moderation.config.ModerationFeatures;
import dev.sheldan.abstracto.moderation.models.template.listener.MessageDeletedAttachmentLog;
import dev.sheldan.abstracto.moderation.models.template.listener.MessageDeletedLog;
import dev.sheldan.abstracto.core.models.embed.MessageToSend;
import dev.sheldan.abstracto.templating.TemplateService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
@@ -49,4 +50,9 @@ public class MessageDeleteLogListener implements MessageDeletedListener {
postTargetService.sendEmbedInPostTarget(attachmentEmbed, DELETE_LOG_TARGET, messageFromCache.getServerId());
}
}
@Override
public String getFeature() {
return ModerationFeatures.LOGGING;
}
}

View File

@@ -5,6 +5,7 @@ import dev.sheldan.abstracto.core.models.CachedMessage;
import dev.sheldan.abstracto.core.models.embed.MessageToSend;
import dev.sheldan.abstracto.core.service.MessageCache;
import dev.sheldan.abstracto.core.service.PostTargetService;
import dev.sheldan.abstracto.moderation.config.ModerationFeatures;
import dev.sheldan.abstracto.moderation.models.template.listener.MessageEditedLog;
import dev.sheldan.abstracto.templating.TemplateService;
import lombok.extern.slf4j.Slf4j;
@@ -40,13 +41,17 @@ public class MessageEditedListener implements MessageTextUpdatedListener {
builder().
messageAfter(messageAfter)
.messageBefore(messageBefore)
.textChannel(messageAfter.getTextChannel())
.messageChannel(messageAfter.getTextChannel())
.guild(messageAfter.getGuild())
.member(messageAfter.getMember()).build();
String simpleMessageUpdatedMessage = templateService.renderTemplate(MESSAGE_EDITED_TEMPLATE, log);
postTargetService.sendTextInPostTarget(simpleMessageUpdatedMessage, EDIT_LOG_TARGET, messageAfter.getGuild().getIdLong());
MessageToSend message = templateService.renderEmbedTemplate(MESSAGE_EDITED_TEMPLATE, log);
postTargetService.sendEmbedInPostTarget(message, EDIT_LOG_TARGET, messageBefore.getServerId());
}
@Override
public String getFeature() {
return ModerationFeatures.LOGGING;
}
}

View File

@@ -1,6 +1,6 @@
package dev.sheldan.abstracto.moderation.service;
import dev.sheldan.abstracto.core.exception.NotFoundException;
import dev.sheldan.abstracto.core.exception.GuildException;
import dev.sheldan.abstracto.core.models.ServerContext;
import dev.sheldan.abstracto.core.service.Bot;
import dev.sheldan.abstracto.core.service.PostTargetService;
@@ -50,7 +50,7 @@ public class BanServiceBean implements BanService {
guildByIdOptional.get().ban(userId.toString(), 0, reason).queue();
} else {
log.warn("Guild {} not found. Not able to ban user {}", guildId, userId);
throw new NotFoundException(String.format("Guild %s not found. Not able to ban user %s", guildId, userId));
throw new GuildException(String.format("Guild %s not found. Not able to ban user %s", guildId, userId));
}
}
}

View File

@@ -1,6 +1,7 @@
package dev.sheldan.abstracto.moderation.service;
import dev.sheldan.abstracto.core.exception.NotFoundException;
import dev.sheldan.abstracto.core.exception.ChannelException;
import dev.sheldan.abstracto.core.exception.GuildException;
import dev.sheldan.abstracto.core.service.Bot;
import dev.sheldan.abstracto.core.service.PostTargetService;
import dev.sheldan.abstracto.moderation.models.template.KickLogModel;
@@ -29,18 +30,18 @@ public class KickServiceBean implements KickService {
private PostTargetService postTargetService;
@Override
public void kickMember(Member member, String reason, KickLogModel kickLogModel) {
public void kickMember(Member member, String reason, KickLogModel kickLogModel) {
Optional<Guild> guildById = bot.getGuildById(kickLogModel.getGuild().getIdLong());
if(guildById.isPresent()) {
guildById.get().kick(member, reason).queue();
this.sendKickLog(kickLogModel);
} else {
log.warn("Not able to kick. Guild {} not found.", kickLogModel.getGuild().getIdLong());
throw new NotFoundException(String.format("Not able to kick %s. Guild %s not found", kickLogModel.getMember().getIdLong(), kickLogModel.getGuild().getIdLong()));
throw new GuildException(String.format("Not able to kick %s. Guild %s not found", kickLogModel.getMember().getIdLong(), kickLogModel.getGuild().getIdLong()));
}
}
private void sendKickLog(KickLogModel kickLogModel) {
private void sendKickLog(KickLogModel kickLogModel) {
String warnLogMessage = templateService.renderContextAwareTemplate(KICK_LOG_TEMPLATE, kickLogModel);
postTargetService.sendTextInPostTarget(warnLogMessage, WARN_LOG_TARGET, kickLogModel.getServer().getId());
}

View File

@@ -1,6 +1,6 @@
package dev.sheldan.abstracto.moderation.service;
import dev.sheldan.abstracto.core.exception.NotFoundException;
import dev.sheldan.abstracto.core.exception.ChannelException;
import dev.sheldan.abstracto.core.models.database.AChannel;
import dev.sheldan.abstracto.core.service.Bot;
import lombok.extern.slf4j.Slf4j;
@@ -28,13 +28,13 @@ public class SlowModeServiceBean implements SlowModeService {
}
@Override
public void setSlowMode(AChannel channel, Duration duration) {
public void setSlowMode(AChannel channel, Duration duration) {
Optional<TextChannel> textChannelOptional = bot.getTextChannelFromServer(channel.getServer().getId(), channel.getId());
if(textChannelOptional.isPresent()) {
TextChannel textChannel = textChannelOptional.get();
this.setSlowMode(textChannel, duration);
} else {
throw new NotFoundException(String.format("Channel %s not found in guild %s", channel.getId(), channel.getServer().getId()));
throw new ChannelException(String.format("Channel %s not found in guild %s", channel.getId(), channel.getServer().getId()));
}
}
}

View File

@@ -1,5 +1,6 @@
package dev.sheldan.abstracto.moderation.service;
import dev.sheldan.abstracto.core.exception.UserException;
import dev.sheldan.abstracto.core.models.ServerContext;
import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.models.database.AUser;
@@ -8,8 +9,8 @@ import dev.sheldan.abstracto.moderation.models.template.WarnLog;
import dev.sheldan.abstracto.moderation.models.template.WarnNotification;
import dev.sheldan.abstracto.moderation.models.Warning;
import dev.sheldan.abstracto.moderation.service.management.WarnManagementService;
import dev.sheldan.abstracto.core.management.ServerManagementService;
import dev.sheldan.abstracto.core.management.UserManagementService;
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
import dev.sheldan.abstracto.core.service.management.UserManagementService;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.core.service.Bot;
import dev.sheldan.abstracto.core.service.PostTargetService;
@@ -18,11 +19,13 @@ import lombok.extern.slf4j.Slf4j;
import net.dv8tion.jda.api.JDA;
import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.Message;
import net.dv8tion.jda.api.entities.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
@Slf4j
@Component
@@ -51,7 +54,7 @@ public class WarnServiceBean implements WarnService {
private static final String WARN_NOTIFICATION_TEMPLATE = "warn_notification";
@Override
public void warnUser(AUserInAServer warnedAUserInAServer, AUserInAServer warningAUserInAServer, String reason, WarnLog warnLog) {
public void warnUser(AUserInAServer warnedAUserInAServer, AUserInAServer warningAUserInAServer, String reason, WarnLog warnLog) {
AUser warningAUser = warningAUserInAServer.getUserReference();
AUser warnedAUser = warnedAUserInAServer.getUserReference();
AServer serverOfWarning = warnedAUserInAServer.getServerReference();
@@ -64,28 +67,37 @@ public class WarnServiceBean implements WarnService {
if(guildById.isPresent()) {
guildName = guildById.get().getName();
}
warnLog.setWarning(warning);
this.sendWarnLog(warnLog);
WarnNotification warnNotification = WarnNotification.builder().warning(warning).serverName(guildName).build();
if(userBeingWarned != null) {
String warnLogMessage = templateService.renderTemplate(WARN_NOTIFICATION_TEMPLATE, warnNotification);
CompletableFuture<Message> messageFuture = new CompletableFuture<>();
// TODO the person executing this, is unaware that the message failed
userBeingWarned.openPrivateChannel().queue(privateChannel -> {
log.info("Messaging user {} about warn {}", warnedAUser.getId(), warning.getId());
privateChannel.sendMessage(warnLogMessage).queue();
privateChannel.sendMessage(warnLogMessage).queue(messageFuture::complete, messageFuture::completeExceptionally);
});
messageFuture.exceptionally(e -> {
log.warn("Failed to send message. ", e);
return null;
});
} else {
log.warn("Unable to find user {} in guild {} to warn.", warnedAUser.getId(), serverOfWarning.getId());
throw new UserException(String.format("Unable to find user %s.", warnedAUser.getId()));
}
warnLog.setWarning(warning);
this.sendWarnLog(warnLog);
}
@Override
public void warnUser(Member warnedMember, Member warningMember, String reason, WarnLog warnLog) {
public void warnUser(Member warnedMember, Member warningMember, String reason, WarnLog warnLog) {
AUserInAServer warnedAUser = userManagementService.loadUser(warnedMember);
AUserInAServer warningAUser = userManagementService.loadUser(warningMember);
this.warnUser(warnedAUser, warningAUser, reason, warnLog);
}
private void sendWarnLog(ServerContext warnLogModel) {
private void sendWarnLog(ServerContext warnLogModel) {
String warnLogMessage = templateService.renderContextAwareTemplate(WARN_LOG_TEMPLATE, warnLogModel);
postTargetService.sendTextInPostTarget(warnLogMessage, WARN_LOG_TARGET, warnLogModel.getServer().getId());
MessageToSend message = templateService.renderEmbedTemplate("warn_log", warnLogModel);

View File

@@ -1 +1,4 @@
abstracto.postTargets.moderation=joinLog,leaveLog,warnLog,kickLog,banLog,editLog,deleteLog
abstracto.postTargets.moderation=joinLog,leaveLog,warnLog,kickLog,banLog,editLog,deleteLog
abstracto.features.moderation=false
abstracto.features.warnings=false
abstracto.features.logging=true

View File

@@ -3,7 +3,7 @@
"name": "${member.effectiveName}#${member.user.discriminator}",
"avatar": "${member.user.effectiveAvatarUrl}"
},
"description": "Message from ${member.effectiveName}#${member.user.discriminator} (${member.idLong?c}) removed in ${textChannel.asMention}",
"description": "Message from ${member.effectiveName}#${member.user.discriminator} (${member.idLong?c}) removed in ${messageChannel.asMention}",
"color" : {
"r": 200,
"g": 0,
@@ -16,7 +16,7 @@
},
{
"name": "Link",
"value": "[${textChannel.name}](${message.messageUrl})"
"value": "[${messageChannel.name}](${message.messageUrl})"
}
]
}

View File

@@ -1,2 +1,2 @@
Message from ${member.effectiveName} (${member.idLong?c}) deleted in ${textChannel.asMention}.
Message from ${member.effectiveName} (${member.idLong?c}) deleted in ${messageChannel.asMention}.
Message: ${message.content}

View File

@@ -3,7 +3,7 @@
"name": "${member.effectiveName}#${member.user.discriminator}",
"avatar": "${member.user.effectiveAvatarUrl}"
},
"description": "Message from ${member.effectiveName}#${member.user.discriminator} (${member.idLong?c}) edited in ${textChannel.asMention}",
"description": "Message from ${member.effectiveName}#${member.user.discriminator} (${member.idLong?c}) edited in ${messageChannel.asMention}",
"color" : {
"r": 200,
"g": 0,
@@ -12,7 +12,7 @@
"fields": [
{
"name": "Original Message: ",
"value": "${messageBefore.contentRaw}"
"value": "${messageBefore.content}"
},
{
"name": "New Message: ",
@@ -20,7 +20,7 @@
},
{
"name": "Jump link",
"value": "[${textChannel.name}](${messageBefore.jumpUrl})"
"value": "[${messageChannel.name}](${messageBefore.messageUrl})"
}
]
}

View File

@@ -1,3 +1,3 @@
Message from ${member.effectiveName} (${member.idLong?c}) edited in ${textChannel.asMention}.
Before: ${messageBefore.contentRaw}
Message from ${member.effectiveName} (${member.idLong?c}) edited in ${messageChannel.asMention}.
Before: ${messageBefore.content}
After: ${messageAfter.contentRaw}

View File

@@ -25,7 +25,7 @@
<#if warning?has_content>
{
"name": "Location of the incident",
"value": "[${textChannel.name}](${message.jumpUrl})"
"value": "[${messageChannel.name}](${message.jumpUrl})"
},
</#if>
{

View File

@@ -1,10 +1,10 @@
package dev.sheldan.abstracto.utility.command;
import dev.sheldan.abstracto.command.Command;
import dev.sheldan.abstracto.command.HelpInfo;
import dev.sheldan.abstracto.command.*;
import dev.sheldan.abstracto.command.execution.*;
import dev.sheldan.abstracto.templating.TemplateService;
import dev.sheldan.abstracto.utility.Utility;
import dev.sheldan.abstracto.utility.config.UtilityFeatures;
import dev.sheldan.abstracto.utility.models.template.ShowEmoteLog;
import net.dv8tion.jda.api.entities.Emote;
import org.springframework.beans.factory.annotation.Autowired;
@@ -14,7 +14,7 @@ import java.util.ArrayList;
import java.util.List;
@Component
public class ShowEmote implements Command {
public class ShowEmote extends AbstractFeatureFlaggedCommand {
private static final String SHOW_EMOTE_RESPONSE_TEMPLATE = "showEmote_response";
@@ -22,18 +22,18 @@ public class ShowEmote implements Command {
private TemplateService templateService;
@Override
public Result execute(CommandContext commandContext) {
public CommandResult execute(CommandContext commandContext) {
List<Object> parameters = commandContext.getParameters().getParameters();
Object emoteParameter = parameters.get(0);
if(!(emoteParameter instanceof Emote)) {
return Result.fromError("No custom emote found.");
return CommandResult.fromError("No custom emote found.");
}
Emote emote = (Emote) emoteParameter;
ShowEmoteLog emoteLog = (ShowEmoteLog) ContextConverter.fromCommandContext(commandContext, ShowEmoteLog.class);
emoteLog.setEmote(emote);
String message = templateService.renderTemplate(SHOW_EMOTE_RESPONSE_TEMPLATE, emoteLog);
commandContext.getChannel().sendMessage(message).queue();
return Result.fromSuccess();
return CommandResult.fromSuccess();
}
@Override
@@ -50,4 +50,9 @@ public class ShowEmote implements Command {
.help(helpInfo)
.build();
}
@Override
public String getFeature() {
return UtilityFeatures.UTILITY;
}
}

View File

@@ -1,14 +1,15 @@
package dev.sheldan.abstracto.utility.command;
import dev.sheldan.abstracto.command.Command;
import dev.sheldan.abstracto.command.AbstractFeatureFlaggedCommand;
import dev.sheldan.abstracto.command.HelpInfo;
import dev.sheldan.abstracto.command.execution.CommandConfiguration;
import dev.sheldan.abstracto.command.execution.CommandContext;
import dev.sheldan.abstracto.command.execution.CommandResult;
import dev.sheldan.abstracto.command.execution.Parameter;
import dev.sheldan.abstracto.command.execution.Result;
import dev.sheldan.abstracto.core.models.embed.MessageToSend;
import dev.sheldan.abstracto.templating.TemplateService;
import dev.sheldan.abstracto.utility.Utility;
import dev.sheldan.abstracto.utility.config.UtilityFeatures;
import dev.sheldan.abstracto.utility.models.template.starboard.StarStatsModel;
import dev.sheldan.abstracto.utility.service.StarboardService;
import org.springframework.beans.factory.annotation.Autowired;
@@ -18,7 +19,7 @@ import java.util.ArrayList;
import java.util.List;
@Component
public class StarStats implements Command {
public class StarStats extends AbstractFeatureFlaggedCommand {
public static final String STARSTATS_RESPONSE_TEMPLATE = "starStats_response";
@Autowired
@@ -28,11 +29,11 @@ public class StarStats implements Command {
private TemplateService templateService;
@Override
public Result execute(CommandContext commandContext) {
public CommandResult execute(CommandContext commandContext) {
StarStatsModel result = starboardService.retrieveStarStats(commandContext.getGuild().getIdLong());
MessageToSend messageToSend = templateService.renderEmbedTemplate(STARSTATS_RESPONSE_TEMPLATE, result);
commandContext.getChannel().sendMessage(messageToSend.getEmbed()).queue();
return Result.fromSuccess();
return CommandResult.fromSuccess();
}
@Override
@@ -48,4 +49,9 @@ public class StarStats implements Command {
.help(helpInfo)
.build();
}
@Override
public String getFeature() {
return UtilityFeatures.STARBOARD;
}
}

View File

@@ -1,9 +1,9 @@
package dev.sheldan.abstracto.utility.command.remind;
import dev.sheldan.abstracto.command.Command;
import dev.sheldan.abstracto.command.HelpInfo;
import dev.sheldan.abstracto.command.*;
import dev.sheldan.abstracto.command.execution.*;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.utility.config.UtilityFeatures;
import dev.sheldan.abstracto.utility.Utility;
import dev.sheldan.abstracto.utility.models.template.ReminderModel;
import dev.sheldan.abstracto.utility.service.ReminderService;
@@ -16,13 +16,13 @@ import java.util.ArrayList;
import java.util.List;
@Component
public class Remind implements Command {
public class Remind extends AbstractFeatureFlaggedCommand {
@Autowired
private ReminderService remindService;
@Override
public Result execute(CommandContext commandContext) {
public CommandResult execute(CommandContext commandContext) {
List<Object> parameters = commandContext.getParameters().getParameters();
Duration remindTime = (Duration) parameters.get(0);
String text = (String) parameters.get(1);
@@ -31,7 +31,7 @@ public class Remind implements Command {
remindModel.setMessage(commandContext.getMessage());
remindModel.setRemindText(text);
remindService.createReminderInForUser(aUserInAServer, text, remindTime, remindModel);
return Result.fromSuccess();
return CommandResult.fromSuccess();
}
@Override
@@ -49,4 +49,9 @@ public class Remind implements Command {
.help(helpInfo)
.build();
}
@Override
public String getFeature() {
return UtilityFeatures.REMIND;
}
}

View File

@@ -1,9 +1,10 @@
package dev.sheldan.abstracto.utility.command.suggest;
import dev.sheldan.abstracto.command.Command;
import dev.sheldan.abstracto.command.AbstractFeatureFlaggedCommand;
import dev.sheldan.abstracto.command.HelpInfo;
import dev.sheldan.abstracto.command.execution.*;
import dev.sheldan.abstracto.utility.Utility;
import dev.sheldan.abstracto.utility.config.UtilityFeatures;
import dev.sheldan.abstracto.utility.models.template.SuggestionLog;
import dev.sheldan.abstracto.utility.service.SuggestionService;
import org.springframework.beans.factory.annotation.Autowired;
@@ -13,19 +14,20 @@ import java.util.ArrayList;
import java.util.List;
@Component
public class Accept implements Command {
public class Accept extends AbstractFeatureFlaggedCommand {
@Autowired
private SuggestionService suggestionService;
@Override
public Result execute(CommandContext commandContext) {
public CommandResult execute(CommandContext commandContext) {
suggestionService.validateSetup(commandContext.getGuild().getIdLong());
List<Object> parameters = commandContext.getParameters().getParameters();
Long suggestionId = (Long) parameters.get(0);
String text = parameters.size() == 2 ? (String) parameters.get(1) : "";
SuggestionLog suggestionModel = (SuggestionLog) ContextConverter.fromCommandContext(commandContext, SuggestionLog.class);
suggestionService.acceptSuggestion(suggestionId, text, suggestionModel);
return Result.fromSuccess();
return CommandResult.fromSuccess();
}
@Override
@@ -43,4 +45,9 @@ public class Accept implements Command {
.help(helpInfo)
.build();
}
@Override
public String getFeature() {
return UtilityFeatures.SUGGEST;
}
}

View File

@@ -1,9 +1,10 @@
package dev.sheldan.abstracto.utility.command.suggest;
import dev.sheldan.abstracto.command.Command;
import dev.sheldan.abstracto.command.AbstractFeatureFlaggedCommand;
import dev.sheldan.abstracto.command.HelpInfo;
import dev.sheldan.abstracto.command.execution.*;
import dev.sheldan.abstracto.utility.Utility;
import dev.sheldan.abstracto.utility.config.UtilityFeatures;
import dev.sheldan.abstracto.utility.models.template.SuggestionLog;
import dev.sheldan.abstracto.utility.service.SuggestionService;
import org.springframework.beans.factory.annotation.Autowired;
@@ -13,18 +14,20 @@ import java.util.ArrayList;
import java.util.List;
@Component
public class Reject implements Command {
public class Reject extends AbstractFeatureFlaggedCommand {
@Autowired
private SuggestionService suggestionService;
@Override
public Result execute(CommandContext commandContext) {
public CommandResult execute(CommandContext commandContext) {
suggestionService.validateSetup(commandContext.getGuild().getIdLong());
List<Object> parameters = commandContext.getParameters().getParameters();
Long suggestionId = (Long) parameters.get(0);
String text = parameters.size() == 2 ? (String) parameters.get(1) : "";
SuggestionLog suggestionModel = (SuggestionLog) ContextConverter.fromCommandContext(commandContext, SuggestionLog.class);
suggestionService.rejectSuggestion(suggestionId, text, suggestionModel);
return Result.fromSuccess();
return CommandResult.fromSuccess();
}
@Override
@@ -42,4 +45,9 @@ public class Reject implements Command {
.help(helpInfo)
.build();
}
@Override
public String getFeature() {
return UtilityFeatures.SUGGEST;
}
}

View File

@@ -1,32 +1,33 @@
package dev.sheldan.abstracto.utility.command.suggest;
import dev.sheldan.abstracto.command.Command;
import dev.sheldan.abstracto.command.AbstractFeatureFlaggedCommand;
import dev.sheldan.abstracto.command.HelpInfo;
import dev.sheldan.abstracto.command.execution.*;
import dev.sheldan.abstracto.utility.Utility;
import dev.sheldan.abstracto.utility.config.UtilityFeatures;
import dev.sheldan.abstracto.utility.models.template.SuggestionLog;
import dev.sheldan.abstracto.utility.service.SuggestionService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.List;
@Component
public class Suggest implements Command {
public class Suggest extends AbstractFeatureFlaggedCommand {
@Autowired
private SuggestionService suggestionService;
@Override
public Result execute(CommandContext commandContext) {
public CommandResult execute(CommandContext commandContext) {
suggestionService.validateSetup(commandContext.getGuild().getIdLong());
List<Object> parameters = commandContext.getParameters().getParameters();
String text = (String) parameters.get(0);
SuggestionLog suggestLogModel = (SuggestionLog) ContextConverter.fromCommandContext(commandContext, SuggestionLog.class);
suggestLogModel.setSuggester(commandContext.getAuthor());
suggestionService.createSuggestion(commandContext.getAuthor(), text, suggestLogModel);
return Result.fromSuccess();
return CommandResult.fromSuccess();
}
@Override
@@ -43,4 +44,9 @@ public class Suggest implements Command {
.help(helpInfo)
.build();
}
@Override
public String getFeature() {
return UtilityFeatures.SUGGEST;
}
}

View File

@@ -1,15 +1,11 @@
package dev.sheldan.abstracto.utility.config;
import dev.sheldan.abstracto.core.listener.ServerConfigListener;
import dev.sheldan.abstracto.core.management.ServerManagementService;
import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.management.ConfigManagementService;
import dev.sheldan.abstracto.core.service.management.ConfigManagementService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
@Component
@Slf4j

View File

@@ -0,0 +1,9 @@
package dev.sheldan.abstracto.utility.config;
public class UtilityFeatures {
public static String REMIND = "remind";
public static String STARBOARD = "starboard";
public static String SUGGEST = "suggestion";
public static String UTILITY = "utility";
public static String LINK_EMBEDS = "embeds";
}

View File

@@ -0,0 +1,124 @@
package dev.sheldan.abstracto.utility.listener;
import dev.sheldan.abstracto.core.listener.MessageReceivedListener;
import dev.sheldan.abstracto.core.service.management.ChannelManagementService;
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
import dev.sheldan.abstracto.core.service.management.UserManagementService;
import dev.sheldan.abstracto.core.models.CachedMessage;
import dev.sheldan.abstracto.core.models.database.AChannel;
import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.core.models.listener.MessageEmbeddedModel;
import dev.sheldan.abstracto.core.service.Bot;
import dev.sheldan.abstracto.core.service.MessageCache;
import dev.sheldan.abstracto.core.models.embed.MessageToSend;
import dev.sheldan.abstracto.templating.TemplateService;
import dev.sheldan.abstracto.utility.config.UtilityFeatures;
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.TextChannel;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Nonnull;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@Component
@Slf4j
public class MessageEmbedListener implements MessageReceivedListener {
@Autowired
private MessageCache messageCache;
public static final String MESSAGE_EMBED_TEMPLATE = "message";
private Pattern messageRegex = Pattern.compile("(?<whole>https://discordapp.com/channels/(?<server>\\d+)/(?<channel>\\d+)/(?<message>\\d+)(?:.*?))+");
@Autowired
private MessageEmbedListener self;
@Autowired
private ChannelManagementService channelManagementService;
@Autowired
private ServerManagementService serverManagementService;
@Autowired
private UserManagementService userManagementService;
@Autowired
private Bot bot;
@Autowired
private TemplateService templateService;
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void createEmbedAndPostEmbed(@Nonnull Message postedMessage, CachedMessage message) {
MessageEmbeddedModel messageEmbeddedModel = buildTemplateParameter(postedMessage, message);
MessageToSend embed = templateService.renderEmbedTemplate(MESSAGE_EMBED_TEMPLATE, messageEmbeddedModel);
if(StringUtils.isBlank(embed.getMessage())) {
postedMessage.getChannel().sendMessage(embed.getEmbed()).queue();
} else {
postedMessage.getChannel().sendMessage(embed.getMessage()).embed(embed.getEmbed()).queue();
}
}
private MessageEmbeddedModel buildTemplateParameter(Message message, CachedMessage embeddedMessage) {
AChannel channel = channelManagementService.loadChannel(message.getChannel().getIdLong());
AServer server = serverManagementService.loadOrCreate(message.getGuild().getIdLong());
AUserInAServer user = userManagementService.loadUser(message.getMember());
Member author = bot.getMemberInServer(embeddedMessage.getServerId(), embeddedMessage.getAuthorId());
TextChannel sourceChannel = bot.getTextChannelFromServer(embeddedMessage.getServerId(), embeddedMessage.getChannelId()).get();
return MessageEmbeddedModel
.builder()
.channel(channel)
.server(server)
.member(message.getMember())
.aUserInAServer(user)
.author(author)
.sourceChannel(sourceChannel)
.embeddingUser(message.getMember())
.user(user.getUserReference())
.messageChannel(message.getChannel())
.guild(message.getGuild())
.embeddedMessage(embeddedMessage)
.build();
}
@Override
public void execute(Message message) {
String messageRaw = message.getContentRaw();
Matcher matcher = messageRegex.matcher(messageRaw);
boolean matched = false;
while(matcher.find()) {
matched = true;
String serverId = matcher.group("server");
String channelId = matcher.group("channel");
String messageId = matcher.group("message");
String wholeLink = matcher.group("whole");
if(message.getGuild().getId().equals(serverId)) {
Long serverIdLong = Long.parseLong(serverId);
Long channelIdLong = Long.parseLong(channelId);
Long messageIdLong = Long.parseLong(messageId);
messageRaw = messageRaw.replace(wholeLink, "");
messageCache.getMessageFromCache(serverIdLong, channelIdLong, messageIdLong).thenAccept(cachedMessage -> {
self.createEmbedAndPostEmbed(message, cachedMessage);
});
}
}
if(StringUtils.isBlank(messageRaw) && matched) {
message.delete().queue();
}
}
@Override
public String getFeature() {
return UtilityFeatures.LINK_EMBEDS;
}
}

View File

@@ -2,17 +2,18 @@ package dev.sheldan.abstracto.utility.listener;
import dev.sheldan.abstracto.core.listener.ReactedAddedListener;
import dev.sheldan.abstracto.core.listener.ReactedRemovedListener;
import dev.sheldan.abstracto.core.management.EmoteManagementService;
import dev.sheldan.abstracto.core.management.UserManagementService;
import dev.sheldan.abstracto.core.models.CachedMessage;
import dev.sheldan.abstracto.core.models.CachedReaction;
import dev.sheldan.abstracto.core.models.database.AEmote;
import dev.sheldan.abstracto.core.models.database.AUser;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.core.service.Bot;
import dev.sheldan.abstracto.core.management.ConfigManagementService;
import dev.sheldan.abstracto.core.service.MessageCache;
import dev.sheldan.abstracto.core.service.management.ConfigManagementService;
import dev.sheldan.abstracto.core.service.management.EmoteManagementService;
import dev.sheldan.abstracto.core.service.management.UserManagementService;
import dev.sheldan.abstracto.core.utils.EmoteUtils;
import dev.sheldan.abstracto.utility.config.UtilityFeatures;
import dev.sheldan.abstracto.utility.models.StarboardPost;
import dev.sheldan.abstracto.utility.service.StarboardService;
import dev.sheldan.abstracto.utility.service.management.StarboardPostManagementService;
@@ -69,17 +70,18 @@ public class StarboardListener implements ReactedAddedListener, ReactedRemovedLi
if(aEmote.isPresent()) {
AEmote emote = aEmote.get();
MessageReaction.ReactionEmote reactionEmote = addedReaction.getReactionEmote();
Optional<Emote> emoteInGuild = bot.getEmote(guildId, emote);
Optional<Emote> emoteInGuild = null;
emoteInGuild = bot.getEmote(guildId, emote);
if(EmoteUtils.isReactionEmoteAEmote(reactionEmote, emote, emoteInGuild.orElse(null))) {
Optional<CachedReaction> reactionOptional = EmoteUtils.getReactionFromMessageByEmote(message, emote);
updateStarboardPost(message, reactionOptional.orElse(null), userAdding, true);
updateStarboardPost(message, reactionOptional.orElse(null), userAdding, true);
}
} else {
log.warn("Emote {} is not defined for guild {}. Starboard not functional.", STAR_EMOTE, guildId);
}
}
private void updateStarboardPost(CachedMessage message, CachedReaction reaction, AUserInAServer userReacting, boolean adding) {
private void updateStarboardPost(CachedMessage message, CachedReaction reaction, AUserInAServer userReacting, boolean adding) {
Optional<StarboardPost> starboardPostOptional = starboardPostManagementService.findByMessageId(message.getMessageId());
if(reaction != null) {
List<AUser> userExceptAuthor = getUsersExcept(reaction.getUsers(), message.getAuthorId());
@@ -99,14 +101,18 @@ public class StarboardListener implements ReactedAddedListener, ReactedRemovedLi
starboardService.createStarboardPost(message, userExceptAuthor, userReacting, author);
}
} else {
starboardPostOptional.ifPresent(this::completelyRemoveStarboardPost);
if(starboardPostOptional.isPresent()) {
this.completelyRemoveStarboardPost(starboardPostOptional.get());
}
}
} else {
starboardPostOptional.ifPresent(this::completelyRemoveStarboardPost);
if(starboardPostOptional.isPresent()) {
this.completelyRemoveStarboardPost(starboardPostOptional.get());
}
}
}
private void completelyRemoveStarboardPost(StarboardPost starboardPost) {
private void completelyRemoveStarboardPost(StarboardPost starboardPost) {
starboardPostReactorManagementService.removeReactors(starboardPost);
starboardService.removeStarboardPost(starboardPost);
starboardPostManagementService.removePost(starboardPost);
@@ -126,7 +132,7 @@ public class StarboardListener implements ReactedAddedListener, ReactedRemovedLi
Optional<Emote> emoteInGuild = bot.getEmote(guildId, emote);
if(EmoteUtils.isReactionEmoteAEmote(reactionEmote, emote, emoteInGuild.orElse(null))) {
Optional<CachedReaction> reactionOptional = EmoteUtils.getReactionFromMessageByEmote(message, emote);
updateStarboardPost(message, reactionOptional.orElse(null), userRemoving, false);
updateStarboardPost(message, reactionOptional.orElse(null), userRemoving, false);
}
} else {
log.warn("Emote {} is not defined for guild {}. Starboard not functional.", STAR_EMOTE, guildId);
@@ -140,4 +146,9 @@ public class StarboardListener implements ReactedAddedListener, ReactedRemovedLi
private List<AUser> getUsersExcept(List<AUser> users, Long userId) {
return users.stream().filter(user -> !user.getId().equals(userId)).collect(Collectors.toList());
}
@Override
public String getFeature() {
return UtilityFeatures.STARBOARD;
}
}

View File

@@ -2,6 +2,7 @@ package dev.sheldan.abstracto.utility.listener;
import dev.sheldan.abstracto.core.listener.MessageDeletedListener;
import dev.sheldan.abstracto.core.models.CachedMessage;
import dev.sheldan.abstracto.utility.config.UtilityFeatures;
import dev.sheldan.abstracto.utility.models.StarboardPost;
import dev.sheldan.abstracto.utility.service.management.StarboardPostManagementService;
import org.springframework.beans.factory.annotation.Autowired;
@@ -22,4 +23,9 @@ public class StarboardPostDeletedListener implements MessageDeletedListener {
starboardPostManagementService.setStarboardPostIgnored(messageBefore.getMessageId(), true);
}
}
@Override
public String getFeature() {
return UtilityFeatures.STARBOARD;
}
}

View File

@@ -1,6 +1,6 @@
package dev.sheldan.abstracto.utility.repository.converter;
import dev.sheldan.abstracto.core.management.UserManagementService;
import dev.sheldan.abstracto.core.service.management.UserManagementService;
import dev.sheldan.abstracto.core.models.database.AUser;
import dev.sheldan.abstracto.core.service.Bot;
import dev.sheldan.abstracto.utility.models.template.starboard.StarStatsUser;

View File

@@ -1,6 +1,6 @@
package dev.sheldan.abstracto.utility.service;
import dev.sheldan.abstracto.core.management.ChannelManagementService;
import dev.sheldan.abstracto.core.service.management.ChannelManagementService;
import dev.sheldan.abstracto.core.models.AServerAChannelAUser;
import dev.sheldan.abstracto.core.models.database.AChannel;
import dev.sheldan.abstracto.core.models.database.AServer;
@@ -15,6 +15,7 @@ import dev.sheldan.abstracto.utility.models.template.ExecutedReminderModel;
import dev.sheldan.abstracto.utility.models.template.ReminderModel;
import dev.sheldan.abstracto.utility.service.management.ReminderManagementService;
import lombok.extern.slf4j.Slf4j;
import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.TextChannel;
import org.apache.commons.lang3.StringUtils;
@@ -70,9 +71,9 @@ public class RemindServiceBean implements ReminderService {
MessageToSend message = templateService.renderEmbedTemplate(REMINDER_EMBED_KEY, reminderModel);
String messageText = message.getMessage();
if(StringUtils.isBlank(messageText)) {
reminderModel.getTextChannel().sendMessage(message.getEmbed()).queue();
reminderModel.getMessageChannel().sendMessage(message.getEmbed()).queue();
} else {
reminderModel.getTextChannel().sendMessage(messageText).embed(message.getEmbed()).queue();
reminderModel.getMessageChannel().sendMessage(messageText).embed(message.getEmbed()).queue();
}
if(remindIn.getSeconds() < 60) {
@@ -89,24 +90,29 @@ public class RemindServiceBean implements ReminderService {
@Override
@Transactional
public void executeReminder(Long reminderId) {
public void executeReminder(Long reminderId) {
Reminder reminderToRemindFor = reminderManagementService.loadReminder(reminderId);
AServer server = reminderToRemindFor.getServer();
AChannel channel = reminderToRemindFor.getChannel();
Optional<TextChannel> channelToAnswerIn = bot.getTextChannelFromServer(server.getId(), channel.getId());
// only send the message if the channel still exists, if not, only set the reminder to reminded.
if(channelToAnswerIn.isPresent()) {
AUser userReference = reminderToRemindFor.getToBeReminded().getUserReference();
Member memberInServer = bot.getMemberInServer(server.getId(), userReference.getId());
ExecutedReminderModel build = ExecutedReminderModel
.builder()
.reminder(reminderToRemindFor)
.member(memberInServer)
.build();
MessageToSend messageToSend = templateService.renderEmbedTemplate("remind_reminder", build);
channelToAnswerIn.get().sendMessage(messageToSend.getMessage()).embed(messageToSend.getEmbed()).queue();
Optional<Guild> guildToAnswerIn = bot.getGuildById(server.getId());
if(guildToAnswerIn.isPresent()) {
Optional<TextChannel> channelToAnswerIn = bot.getTextChannelFromServer(server.getId(), channel.getId());
// only send the message if the channel still exists, if not, only set the reminder to reminded.
if(channelToAnswerIn.isPresent()) {
AUser userReference = reminderToRemindFor.getToBeReminded().getUserReference();
Member memberInServer = bot.getMemberInServer(server.getId(), userReference.getId());
ExecutedReminderModel build = ExecutedReminderModel
.builder()
.reminder(reminderToRemindFor)
.member(memberInServer)
.build();
MessageToSend messageToSend = templateService.renderEmbedTemplate("remind_reminder", build);
channelToAnswerIn.get().sendMessage(messageToSend.getMessage()).embed(messageToSend.getEmbed()).queue();
} else {
log.warn("Channel {} in server {} to remind user did not exist anymore. Ignoring reminder {}", channel.getId(), server.getId(), reminderId);
}
} else {
log.warn("Channel {} in server {} to remind user did not exist anymore. Ignoring.", channel.getId(), server.getId());
log.warn("Guild {} to remind user in did not exist anymore. Ignoring reminder {}.", server.getId(), reminderId);
}
reminderManagementService.setReminded(reminderToRemindFor);
}

View File

@@ -1,8 +1,10 @@
package dev.sheldan.abstracto.utility.service;
import dev.sheldan.abstracto.core.management.EmoteManagementService;
import dev.sheldan.abstracto.core.management.PostTargetManagement;
import dev.sheldan.abstracto.core.management.UserManagementService;
import dev.sheldan.abstracto.core.exception.ChannelException;
import dev.sheldan.abstracto.core.exception.GuildException;
import dev.sheldan.abstracto.core.service.management.EmoteManagementService;
import dev.sheldan.abstracto.core.service.management.PostTargetManagement;
import dev.sheldan.abstracto.core.service.management.UserManagementService;
import dev.sheldan.abstracto.core.models.AServerChannelMessage;
import dev.sheldan.abstracto.core.models.CachedMessage;
import dev.sheldan.abstracto.core.models.database.*;
@@ -36,6 +38,8 @@ import java.util.stream.Collectors;
@Slf4j
public class StarboardServiceBean implements StarboardService {
public static final String STARBOARD_POSTTARGET = "starboard";
public static final String STARBOARD_POST_TEMPLATE = "starboard_post";
@Autowired
private Bot bot;
@@ -70,11 +74,11 @@ public class StarboardServiceBean implements StarboardService {
private EmoteService emoteService;
@Override
public void createStarboardPost(CachedMessage message, List<AUser> userExceptAuthor, AUserInAServer userReacting, AUserInAServer starredUser) {
public void createStarboardPost(CachedMessage message, List<AUser> userExceptAuthor, AUserInAServer userReacting, AUserInAServer starredUser) {
StarboardPostModel starboardPostModel = buildStarboardPostModel(message, userExceptAuthor.size());
MessageToSend messageToSend = templateService.renderEmbedTemplate("starboard_post", starboardPostModel);
PostTarget starboard = postTargetManagement.getPostTarget("starboard", message.getServerId());
postTargetService.sendEmbedInPostTarget(messageToSend, "starboard", message.getServerId()).thenAccept(message1 -> {
MessageToSend messageToSend = templateService.renderEmbedTemplate(STARBOARD_POST_TEMPLATE, starboardPostModel);
PostTarget starboard = postTargetManagement.getPostTarget(STARBOARD_POSTTARGET, message.getServerId());
postTargetService.sendEmbedInPostTarget(messageToSend, STARBOARD_POSTTARGET, message.getServerId()).thenAccept(message1 -> {
AServerChannelMessage aServerChannelMessage = AServerChannelMessage
.builder()
.messageId(message1.getIdLong())
@@ -90,7 +94,7 @@ public class StarboardServiceBean implements StarboardService {
}
private StarboardPostModel buildStarboardPostModel(CachedMessage message, Integer starCount) {
private StarboardPostModel buildStarboardPostModel(CachedMessage message, Integer starCount) {
Member member = bot.getMemberInServer(message.getServerId(), message.getAuthorId());
Optional<TextChannel> channel = bot.getTextChannelFromServer(message.getServerId(), message.getChannelId());
Optional<Guild> guild = bot.getGuildById(message.getServerId());
@@ -121,7 +125,7 @@ public class StarboardServiceBean implements StarboardService {
}
@Override
public void updateStarboardPost(StarboardPost post, CachedMessage message, List<AUser> userExceptAuthor) {
public void updateStarboardPost(StarboardPost post, CachedMessage message, List<AUser> userExceptAuthor) {
StarboardPostModel starboardPostModel = buildStarboardPostModel(message, userExceptAuthor.size());
MessageToSend messageToSend = templateService.renderEmbedTemplate("starboard_post", starboardPostModel);
CompletableFuture<Message> future = new CompletableFuture<>();
@@ -132,13 +136,13 @@ public class StarboardServiceBean implements StarboardService {
}
@Override
public void removeStarboardPost(StarboardPost message) {
public void removeStarboardPost(StarboardPost message) {
AChannel starboardChannel = message.getStarboardChannel();
bot.deleteMessage(starboardChannel.getServer().getId(), starboardChannel.getId(), message.getStarboardMessageId());
}
@Override
public StarStatsModel retrieveStarStats(Long serverId) {
public StarStatsModel retrieveStarStats(Long serverId) {
int count = 3;
List<StarboardPost> starboardPosts = starboardPostManagementService.retrieveTopPosts(serverId, count);
List<StarStatsUser> topStarGivers = starboardPostReactorManagementService.retrieveTopStarGiver(serverId, count);

View File

@@ -1,6 +1,7 @@
package dev.sheldan.abstracto.utility.service;
import dev.sheldan.abstracto.core.management.EmoteManagementService;
import dev.sheldan.abstracto.core.service.EmoteService;
import dev.sheldan.abstracto.core.service.management.EmoteManagementService;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.core.models.embed.MessageToSend;
import dev.sheldan.abstracto.core.service.Bot;
@@ -45,6 +46,9 @@ public class SuggestionServiceBean implements SuggestionService {
@Autowired
private EmoteManagementService emoteManagementService;
@Autowired
private EmoteService emoteService;
@Autowired
private MessageService messageService;
@@ -52,7 +56,7 @@ public class SuggestionServiceBean implements SuggestionService {
private SuggestionServiceBean self;
@Override
public void createSuggestion(Member member, String text, SuggestionLog suggestionLog) {
public void createSuggestion(Member member, String text, SuggestionLog suggestionLog) {
Suggestion suggestion = suggestionManagementService.createSuggestion(member, text);
suggestionLog.setSuggestion(suggestion);
suggestionLog.setText(text);
@@ -62,9 +66,9 @@ public class SuggestionServiceBean implements SuggestionService {
Guild guildById = instance.getGuildById(guildId);
if(guildById != null) {
postTargetService.sendEmbedInPostTarget(messageToSend, SUGGESTIONS_TARGET, guildId).thenAccept(message -> {
suggestionManagementService.setPostedMessage(suggestion, message);
messageService.addReactionToMessage(SUGGESTION_YES_EMOTE, guildId, message);
messageService.addReactionToMessage(SUGGESTION_NO_EMOTE, guildId, message);
suggestionManagementService.setPostedMessage(suggestion, message);
});
} else {
log.warn("Guild {} or member {} was not found when creating suggestion.", member.getGuild().getIdLong(), member.getIdLong());
@@ -105,7 +109,7 @@ public class SuggestionServiceBean implements SuggestionService {
}
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void updateSuggestionMessageText(String text, SuggestionLog suggestionLog, Message message) {
public void updateSuggestionMessageText(String text, SuggestionLog suggestionLog, Message message) {
Optional<MessageEmbed> embedOptional = message.getEmbeds().stream().filter(embed -> embed.getDescription() != null).findFirst();
if(embedOptional.isPresent()) {
MessageEmbed suggestionEmbed = embedOptional.get();
@@ -122,4 +126,11 @@ public class SuggestionServiceBean implements SuggestionService {
suggestionManagementService.setSuggestionState(suggestion, SuggestionState.REJECTED);
updateSuggestion(text, log, suggestion);
}
@Override
public void validateSetup(Long serverId) {
emoteService.throwIfEmoteDoesNotExist(SUGGESTION_YES_EMOTE, serverId);
emoteService.throwIfEmoteDoesNotExist(SUGGESTION_NO_EMOTE, serverId);
postTargetService.throwIfPostTargetIsNotDefined(SUGGESTION_YES_EMOTE, serverId);
}
}

View File

@@ -1,8 +1,8 @@
package dev.sheldan.abstracto.utility.service.management;
import dev.sheldan.abstracto.core.management.ChannelManagementService;
import dev.sheldan.abstracto.core.management.ServerManagementService;
import dev.sheldan.abstracto.core.management.UserManagementService;
import dev.sheldan.abstracto.core.service.management.ChannelManagementService;
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
import dev.sheldan.abstracto.core.service.management.UserManagementService;
import dev.sheldan.abstracto.core.models.database.AChannel;
import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;

View File

@@ -14,3 +14,9 @@ abstracto.scheduling.jobs.reminderJob.group=utility
abstracto.scheduling.jobs.reminderJob.clazz=dev.sheldan.abstracto.utility.jobs.ReminderJob
abstracto.scheduling.jobs.reminderJob.standAlone=false
abstracto.scheduling.jobs.reminderJob.active=true
abstracto.features.starboard=false
abstracto.features.reminder=false
abstracto.features.suggestion=false
abstracto.features.utility=false
abstracto.features.embeds=true

View File

@@ -7,4 +7,5 @@ public interface SuggestionService {
void createSuggestion(Member member, String text, SuggestionLog log);
void acceptSuggestion(Long suggestionId, String text, SuggestionLog log);
void rejectSuggestion(Long suggestionId, String text, SuggestionLog log);
void validateSetup(Long serverId);
}