mirror of
https://github.com/Sheldan/abstracto.git
synced 2026-03-25 14:06:24 +00:00
[AB-96] adding ability to edit/delete modmail messages via editing/deleting the original message causing the message,
adding featuremode to modmail to define whether or not there is a separate message posted to the mod mail thread, to see it easier, renaming modmail related tables to singular, adding some necessary methods (caching) to all entities
This commit is contained in:
@@ -18,6 +18,8 @@ import java.util.List;
|
||||
@NoArgsConstructor
|
||||
@Getter
|
||||
@Setter
|
||||
@EqualsAndHashCode
|
||||
@Cacheable
|
||||
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
|
||||
public class AssignableRole implements Serializable {
|
||||
|
||||
|
||||
@@ -18,6 +18,8 @@ import java.util.List;
|
||||
@NoArgsConstructor
|
||||
@Getter
|
||||
@Setter
|
||||
@EqualsAndHashCode
|
||||
@Cacheable
|
||||
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
|
||||
public class AssignableRolePlace implements Serializable {
|
||||
|
||||
|
||||
@@ -17,6 +17,8 @@ import java.util.List;
|
||||
@NoArgsConstructor
|
||||
@Getter
|
||||
@Setter
|
||||
@EqualsAndHashCode
|
||||
@Cacheable
|
||||
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
|
||||
public class AssignableRolePlacePost implements Serializable {
|
||||
|
||||
|
||||
@@ -17,6 +17,8 @@ import java.util.List;
|
||||
@NoArgsConstructor
|
||||
@Getter
|
||||
@Setter
|
||||
@EqualsAndHashCode
|
||||
@Cacheable
|
||||
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
|
||||
public class AssignedRoleUser implements Serializable {
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ import lombok.*;
|
||||
import org.hibernate.annotations.CacheConcurrencyStrategy;
|
||||
|
||||
import javax.persistence.*;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* A role for which the experience gain in a particular server has been disabled.
|
||||
@@ -16,9 +17,10 @@ import javax.persistence.*;
|
||||
@Table(name = "disabled_experience_roles")
|
||||
@Getter
|
||||
@Setter
|
||||
@EqualsAndHashCode
|
||||
@Cacheable
|
||||
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
|
||||
public class ADisabledExpRole {
|
||||
public class ADisabledExpRole implements Serializable {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Long id;
|
||||
|
||||
@@ -6,7 +6,6 @@ import org.hibernate.annotations.CacheConcurrencyStrategy;
|
||||
import javax.persistence.*;
|
||||
import java.io.Serializable;
|
||||
import java.time.Instant;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Represents an existing level to reach and the total necessary experience needed to reach that level.
|
||||
@@ -18,6 +17,7 @@ import java.util.Objects;
|
||||
@Table(name = "experience_level")
|
||||
@Getter
|
||||
@Setter
|
||||
@EqualsAndHashCode
|
||||
@Cacheable
|
||||
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
|
||||
public class AExperienceLevel implements Serializable {
|
||||
@@ -47,17 +47,4 @@ public class AExperienceLevel implements Serializable {
|
||||
this.updated = Instant.now();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
AExperienceLevel that = (AExperienceLevel) o;
|
||||
return Objects.equals(level, that.level) &&
|
||||
Objects.equals(experienceNeeded, that.experienceNeeded);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(level, experienceNeeded);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,6 @@ import java.io.Serializable;
|
||||
import java.time.Instant;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Represents a role which is given when the user reaches a certain level. These roles are configurable per server and
|
||||
@@ -23,6 +22,7 @@ import java.util.Objects;
|
||||
@Table(name = "experience_role")
|
||||
@Getter
|
||||
@Setter
|
||||
@EqualsAndHashCode
|
||||
@Cacheable
|
||||
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
|
||||
public class AExperienceRole implements Serializable {
|
||||
@@ -81,20 +81,5 @@ public class AExperienceRole implements Serializable {
|
||||
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
|
||||
private List<AUserExperience> users = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
AExperienceRole that = (AExperienceRole) o;
|
||||
return Objects.equals(id, that.id) &&
|
||||
Objects.equals(level, that.level) &&
|
||||
Objects.equals(roleServer, that.roleServer) &&
|
||||
Objects.equals(role, that.role) &&
|
||||
Objects.equals(users, that.users);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(id, level, roleServer, role, users);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,6 @@ import org.hibernate.annotations.CacheConcurrencyStrategy;
|
||||
import javax.persistence.*;
|
||||
import java.io.Serializable;
|
||||
import java.time.Instant;
|
||||
import java.util.Objects;
|
||||
|
||||
|
||||
/**
|
||||
@@ -21,6 +20,7 @@ import java.util.Objects;
|
||||
@Table(name = "user_experience")
|
||||
@Getter
|
||||
@Setter
|
||||
@EqualsAndHashCode
|
||||
@Cacheable
|
||||
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
|
||||
public class AUserExperience implements Serializable {
|
||||
@@ -83,22 +83,4 @@ public class AUserExperience implements Serializable {
|
||||
public Integer getLevelOrDefault() {
|
||||
return currentLevel != null ? currentLevel.getLevel() : 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
AUserExperience that = (AUserExperience) o;
|
||||
return Objects.equals(id, that.id) &&
|
||||
Objects.equals(user, that.user) &&
|
||||
Objects.equals(experience, that.experience) &&
|
||||
Objects.equals(messageCount, that.messageCount) &&
|
||||
Objects.equals(currentLevel, that.currentLevel) &&
|
||||
Objects.equals(currentExperienceRole, that.currentExperienceRole);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(id, user, experience, messageCount, currentLevel, currentExperienceRole);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,10 +5,11 @@ import dev.sheldan.abstracto.core.models.database.AServer;
|
||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||
import dev.sheldan.abstracto.core.models.ServerSpecificId;
|
||||
import lombok.*;
|
||||
import org.hibernate.annotations.CacheConcurrencyStrategy;
|
||||
|
||||
import javax.persistence.*;
|
||||
import java.io.Serializable;
|
||||
import java.time.Instant;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Table used to store mutes in order to track when the mute was cast and when it ended.
|
||||
@@ -20,7 +21,10 @@ import java.util.Objects;
|
||||
@NoArgsConstructor
|
||||
@Getter
|
||||
@Setter
|
||||
public class Mute {
|
||||
@EqualsAndHashCode
|
||||
@Cacheable
|
||||
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
|
||||
public class Mute implements Serializable {
|
||||
|
||||
/**
|
||||
* The globally unique id of the mute.
|
||||
@@ -102,26 +106,4 @@ public class Mute {
|
||||
this.updated = Instant.now();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
Mute mute = (Mute) o;
|
||||
return Objects.equals(muteId, mute.muteId) &&
|
||||
Objects.equals(mutedUser, mute.mutedUser) &&
|
||||
Objects.equals(mutingUser, mute.mutingUser) &&
|
||||
Objects.equals(reason, mute.reason) &&
|
||||
Objects.equals(muteDate, mute.muteDate) &&
|
||||
Objects.equals(muteTargetDate, mute.muteTargetDate) &&
|
||||
Objects.equals(muteEnded, mute.muteEnded) &&
|
||||
Objects.equals(messageId, mute.messageId) &&
|
||||
Objects.equals(server, mute.server) &&
|
||||
Objects.equals(mutingChannel, mute.mutingChannel) &&
|
||||
Objects.equals(triggerKey, mute.triggerKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(muteId, mutedUser, mutingUser, reason, muteDate, muteTargetDate, muteEnded, messageId, server, mutingChannel, triggerKey);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,10 +3,11 @@ package dev.sheldan.abstracto.moderation.models.database;
|
||||
import dev.sheldan.abstracto.core.models.database.ARole;
|
||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||
import lombok.*;
|
||||
import org.hibernate.annotations.CacheConcurrencyStrategy;
|
||||
|
||||
import javax.persistence.*;
|
||||
import java.io.Serializable;
|
||||
import java.time.Instant;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Represents a role to be used for muting users on a certain server
|
||||
@@ -18,7 +19,10 @@ import java.util.Objects;
|
||||
@Table(name = "mute_role")
|
||||
@Getter
|
||||
@Setter
|
||||
public class MuteRole {
|
||||
@EqualsAndHashCode
|
||||
@Cacheable
|
||||
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
|
||||
public class MuteRole implements Serializable {
|
||||
|
||||
/**
|
||||
* The abstracto unique id of this mute role.
|
||||
@@ -59,18 +63,4 @@ public class MuteRole {
|
||||
this.updated = Instant.now();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
MuteRole muteRole = (MuteRole) o;
|
||||
return Objects.equals(id, muteRole.id) &&
|
||||
Objects.equals(roleServer, muteRole.roleServer) &&
|
||||
Objects.equals(role, muteRole.role);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(id, roleServer, role);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,8 +4,10 @@ import dev.sheldan.abstracto.core.models.ServerSpecificId;
|
||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||
import lombok.*;
|
||||
import org.hibernate.annotations.CacheConcurrencyStrategy;
|
||||
|
||||
import javax.persistence.*;
|
||||
import java.io.Serializable;
|
||||
import java.time.Instant;
|
||||
|
||||
@Entity
|
||||
@@ -15,7 +17,10 @@ import java.time.Instant;
|
||||
@NoArgsConstructor
|
||||
@Getter
|
||||
@Setter
|
||||
public class UserNote {
|
||||
@EqualsAndHashCode
|
||||
@Cacheable
|
||||
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
|
||||
public class UserNote implements Serializable {
|
||||
|
||||
@EmbeddedId
|
||||
private ServerSpecificId userNoteId;
|
||||
|
||||
@@ -4,10 +4,11 @@ import dev.sheldan.abstracto.core.models.ServerSpecificId;
|
||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||
import lombok.*;
|
||||
import org.hibernate.annotations.CacheConcurrencyStrategy;
|
||||
|
||||
import javax.persistence.*;
|
||||
import java.io.Serializable;
|
||||
import java.time.Instant;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* A warning which was given a member with a special reason by a moderating member. This warning is bound to a server.
|
||||
@@ -17,7 +18,10 @@ import java.util.Objects;
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class Warning {
|
||||
@EqualsAndHashCode
|
||||
@Cacheable
|
||||
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
|
||||
public class Warning implements Serializable {
|
||||
|
||||
/**
|
||||
* The globally unique id of this warning
|
||||
@@ -94,23 +98,4 @@ public class Warning {
|
||||
this.updated = Instant.now();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
Warning warning = (Warning) o;
|
||||
return Objects.equals(warnId, warning.warnId) &&
|
||||
Objects.equals(warnedUser, warning.warnedUser) &&
|
||||
Objects.equals(warningUser, warning.warningUser) &&
|
||||
Objects.equals(reason, warning.reason) &&
|
||||
Objects.equals(warnDate, warning.warnDate) &&
|
||||
Objects.equals(decayed, warning.decayed) &&
|
||||
Objects.equals(decayDate, warning.decayDate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(warnId, warnedUser, warningUser, reason, warnDate, decayed, decayDate);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
package dev.sheldan.abstracto.modmail.listener;
|
||||
|
||||
import dev.sheldan.abstracto.core.config.FeatureEnum;
|
||||
import dev.sheldan.abstracto.core.listener.MessageDeletedListener;
|
||||
import dev.sheldan.abstracto.core.models.AServerAChannelAUser;
|
||||
import dev.sheldan.abstracto.core.models.GuildChannelMember;
|
||||
import dev.sheldan.abstracto.core.models.cache.CachedMessage;
|
||||
import dev.sheldan.abstracto.core.service.BotService;
|
||||
import dev.sheldan.abstracto.core.service.MessageService;
|
||||
import dev.sheldan.abstracto.modmail.config.ModMailFeatures;
|
||||
import dev.sheldan.abstracto.modmail.models.database.ModMailMessage;
|
||||
import dev.sheldan.abstracto.modmail.models.database.ModMailThread;
|
||||
import dev.sheldan.abstracto.modmail.service.management.ModMailMessageManagementService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class ModMailMessageDeletedListener implements MessageDeletedListener {
|
||||
|
||||
@Autowired
|
||||
private ModMailMessageManagementService modMailMessageManagementService;
|
||||
|
||||
@Autowired
|
||||
private MessageService messageService;
|
||||
|
||||
@Autowired
|
||||
private ModMailMessageDeletedListener self;
|
||||
|
||||
@Autowired
|
||||
private BotService botService;
|
||||
|
||||
@Override
|
||||
public void execute(CachedMessage messageBefore, AServerAChannelAUser authorUser, GuildChannelMember authorMember) {
|
||||
Optional<ModMailMessage> messageOptional = modMailMessageManagementService.getByMessageIdOptional(messageBefore.getMessageId());
|
||||
messageOptional.ifPresent(modMailMessage -> {
|
||||
ModMailThread thread = modMailMessage.getThreadReference();
|
||||
Long dmMessageId = modMailMessage.getCreatedMessageInDM();
|
||||
boolean hasMessageInChannel = modMailMessage.getCreatedMessageInChannel() != null;
|
||||
Long channelMessage = modMailMessage.getCreatedMessageInChannel();
|
||||
Long channelId = thread.getChannel().getId();
|
||||
Long serverId = thread.getServer().getId();
|
||||
log.info("Deleting message for mod mail thread {} in channel {} in server {}.", thread.getId(), channelId, serverId);
|
||||
botService.getMemberInServerAsync(messageBefore.getServerId(), modMailMessage.getThreadReference().getUser().getUserReference().getId()).thenAccept(member -> {
|
||||
CompletableFuture<Void> dmDeletePromise = messageService.deleteMessageInChannelWithUser(member.getUser(), dmMessageId);
|
||||
CompletableFuture<Void> channelDeletePromise;
|
||||
if(hasMessageInChannel) {
|
||||
channelDeletePromise = messageService.deleteMessageInChannelInServer(serverId, channelId, channelMessage);
|
||||
} else {
|
||||
channelDeletePromise = CompletableFuture.completedFuture(null);
|
||||
}
|
||||
CompletableFuture.allOf(dmDeletePromise, channelDeletePromise).thenAccept(unused ->
|
||||
self.removeMessageFromThread(messageBefore.getMessageId())
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void removeMessageFromThread(Long messageId) {
|
||||
Optional<ModMailMessage> messageOptional = modMailMessageManagementService.getByMessageIdOptional(messageId);
|
||||
messageOptional.ifPresent(modMailMessage ->
|
||||
modMailMessageManagementService.deleteMessageFromThread(modMailMessage)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FeatureEnum getFeature() {
|
||||
return ModMailFeatures.MOD_MAIL;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,132 @@
|
||||
package dev.sheldan.abstracto.modmail.listener;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.config.Parameters;
|
||||
import dev.sheldan.abstracto.core.command.service.CommandRegistry;
|
||||
import dev.sheldan.abstracto.core.command.service.CommandService;
|
||||
import dev.sheldan.abstracto.core.config.FeatureEnum;
|
||||
import dev.sheldan.abstracto.core.listener.MessageTextUpdatedListener;
|
||||
import dev.sheldan.abstracto.core.models.FullUserInServer;
|
||||
import dev.sheldan.abstracto.core.models.cache.CachedMessage;
|
||||
import dev.sheldan.abstracto.core.models.database.AChannel;
|
||||
import dev.sheldan.abstracto.core.service.BotService;
|
||||
import dev.sheldan.abstracto.core.service.ChannelService;
|
||||
import dev.sheldan.abstracto.core.service.MessageService;
|
||||
import dev.sheldan.abstracto.modmail.config.ModMailFeatures;
|
||||
import dev.sheldan.abstracto.modmail.models.database.ModMailMessage;
|
||||
import dev.sheldan.abstracto.modmail.models.template.ModMailModeratorReplyModel;
|
||||
import dev.sheldan.abstracto.modmail.service.ModMailThreadService;
|
||||
import dev.sheldan.abstracto.modmail.service.ModMailThreadServiceBean;
|
||||
import dev.sheldan.abstracto.modmail.service.management.ModMailMessageManagementService;
|
||||
import dev.sheldan.abstracto.templating.model.MessageToSend;
|
||||
import dev.sheldan.abstracto.templating.service.TemplateService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.entities.Member;
|
||||
import net.dv8tion.jda.api.entities.Message;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class ModMailMessageEditedListener implements MessageTextUpdatedListener {
|
||||
|
||||
public static final String DEFAULT_COMMAND_FOR_MODMAIL_EDIT = "reply";
|
||||
@Autowired
|
||||
private ModMailMessageManagementService modMailMessageManagementService;
|
||||
|
||||
@Autowired
|
||||
private CommandService commandService;
|
||||
|
||||
@Autowired
|
||||
private BotService botService;
|
||||
|
||||
@Autowired
|
||||
private TemplateService templateService;
|
||||
|
||||
@Autowired
|
||||
private ModMailMessageEditedListener self;
|
||||
|
||||
@Autowired
|
||||
private ChannelService channelService;
|
||||
|
||||
@Autowired
|
||||
private MessageService messageService;
|
||||
|
||||
@Autowired
|
||||
private CommandRegistry commandRegistry;
|
||||
|
||||
@Autowired
|
||||
private ModMailThreadService modMailThreadService;
|
||||
|
||||
@Override
|
||||
public void execute(CachedMessage messageBefore, Message messageAfter) {
|
||||
if(!modMailThreadService.isModMailThread(messageBefore.getChannelId())) {
|
||||
return;
|
||||
}
|
||||
Optional<ModMailMessage> messageOptional = modMailMessageManagementService.getByMessageIdOptional(messageBefore.getMessageId());
|
||||
messageOptional.ifPresent(modMailMessage -> {
|
||||
log.info("Editing send message {} in channel {} in mod mail thread {} in server {}.", messageBefore.getMessageId(), messageBefore.getChannelId(), modMailMessage.getThreadReference().getId(), messageBefore.getServerId());
|
||||
String contentStripped = messageAfter.getContentRaw();
|
||||
String commandName = commandRegistry.getCommandName(contentStripped.substring(0, contentStripped.indexOf(" ")), messageBefore.getServerId());
|
||||
if(!commandService.doesCommandExist(commandName)) {
|
||||
commandName = DEFAULT_COMMAND_FOR_MODMAIL_EDIT;
|
||||
log.info("Edit did not contain the original command to retrieve the parameters for. Resulting to {}.", DEFAULT_COMMAND_FOR_MODMAIL_EDIT);
|
||||
}
|
||||
CompletableFuture<Parameters> parameterParseFuture = commandService.getParametersForCommand(commandName, messageAfter);
|
||||
CompletableFuture<Member> loadTargetUser = botService.getMemberInServerAsync(messageBefore.getServerId(), modMailMessage.getThreadReference().getUser().getUserReference().getId());
|
||||
CompletableFuture<Member> loadEditingUser = botService.getMemberInServerAsync(messageBefore.getServerId(), modMailMessage.getAuthor().getUserReference().getId());
|
||||
CompletableFuture.allOf(parameterParseFuture, loadTargetUser, loadEditingUser).thenAccept(unused ->
|
||||
self.updateMessageInThread(messageAfter, parameterParseFuture.join(), loadTargetUser.join(), loadEditingUser.join())
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void updateMessageInThread(Message messageAfter, Parameters parameters, Member targetMember, Member editingUser) {
|
||||
String newText = (String) parameters.getParameters().get(0);
|
||||
Optional<ModMailMessage> messageOptional = modMailMessageManagementService.getByMessageIdOptional(messageAfter.getIdLong());
|
||||
messageOptional.ifPresent(modMailMessage -> {
|
||||
FullUserInServer fullThreadUser = FullUserInServer
|
||||
.builder()
|
||||
.aUserInAServer(modMailMessage.getThreadReference().getUser())
|
||||
.member(targetMember)
|
||||
.build();
|
||||
ModMailModeratorReplyModel.ModMailModeratorReplyModelBuilder modMailModeratorReplyModelBuilder = ModMailModeratorReplyModel
|
||||
.builder()
|
||||
.text(newText)
|
||||
.modMailThread(modMailMessage.getThreadReference())
|
||||
.postedMessage(messageAfter)
|
||||
.anonymous(modMailMessage.getAnonymous())
|
||||
.threadUser(fullThreadUser);
|
||||
if(modMailMessage.getAnonymous()) {
|
||||
modMailModeratorReplyModelBuilder.moderator(botService.getBotInGuild(modMailMessage.getThreadReference().getServer()));
|
||||
} else {
|
||||
modMailModeratorReplyModelBuilder.moderator(editingUser);
|
||||
}
|
||||
ModMailModeratorReplyModel modMailUserReplyModel = modMailModeratorReplyModelBuilder.build();
|
||||
MessageToSend messageToSend = templateService.renderEmbedTemplate(ModMailThreadServiceBean.MODMAIL_STAFF_MESSAGE_TEMPLATE_KEY, modMailUserReplyModel);
|
||||
Long threadId = modMailMessage.getThreadReference().getId();
|
||||
long serverId = editingUser.getGuild().getIdLong();
|
||||
if(modMailMessage.getCreatedMessageInChannel() != null) {
|
||||
AChannel channel = modMailMessage.getThreadReference().getChannel();
|
||||
log.trace("Editing message {} in mod mail channel {} for thread {} in server {} as well.", modMailMessage.getCreatedMessageInChannel(), channel.getId(), threadId, serverId);
|
||||
channelService.editMessageInAChannel(messageToSend, channel, modMailMessage.getCreatedMessageInChannel());
|
||||
}
|
||||
log.trace("Editing message {} in DM channel with user {} for thread {} in server {}.", modMailMessage.getCreatedMessageInDM(), targetMember.getUser().getIdLong(), threadId, serverId);
|
||||
messageService.editMessageInDMChannel(targetMember.getUser(), messageToSend, modMailMessage.getCreatedMessageInDM());
|
||||
});
|
||||
|
||||
if(!messageOptional.isPresent()) {
|
||||
log.warn("Message {} of user {} in channel {} for server {} for thread about user {} could not be found in the mod mail messages when updating the text.",
|
||||
messageAfter.getIdLong(), editingUser.getIdLong(), messageAfter.getChannel().getIdLong(), messageAfter.getGuild().getIdLong(), targetMember.getIdLong());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public FeatureEnum getFeature() {
|
||||
return ModMailFeatures.MOD_MAIL;
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,7 @@ import org.springframework.stereotype.Repository;
|
||||
|
||||
import javax.persistence.QueryHint;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* Repository to manage the stored {@link ModMailMessage} instances
|
||||
@@ -16,4 +17,7 @@ import java.util.List;
|
||||
public interface ModMailMessageRepository extends JpaRepository<ModMailMessage, Long> {
|
||||
@QueryHints(@QueryHint(name = org.hibernate.annotations.QueryHints.CACHEABLE, value = "true"))
|
||||
List<ModMailMessage> findByThreadReference(ModMailThread modMailThread);
|
||||
|
||||
@QueryHints(@QueryHint(name = org.hibernate.annotations.QueryHints.CACHEABLE, value = "true"))
|
||||
Optional<ModMailMessage> findByMessageId(Long messageId);
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ import java.util.Optional;
|
||||
public interface ModMailThreadRepository extends JpaRepository<ModMailThread, Long> {
|
||||
|
||||
@QueryHints(@QueryHint(name = org.hibernate.annotations.QueryHints.CACHEABLE, value = "true"))
|
||||
ModMailThread findByChannel(AChannel channel);
|
||||
Optional<ModMailThread> findByChannel(AChannel channel);
|
||||
|
||||
@QueryHints(@QueryHint(name = org.hibernate.annotations.QueryHints.CACHEABLE, value = "true"))
|
||||
List<ModMailThread> findByUser(AUserInAServer aUserInAServer);
|
||||
|
||||
@@ -38,7 +38,6 @@ public class ModMailMessageServiceBean implements ModMailMessageService {
|
||||
modMailMessages.forEach(modMailMessage -> {
|
||||
ServerChannelMessageUser.ServerChannelMessageUserBuilder serverChannelMessageBuilder = ServerChannelMessageUser
|
||||
.builder()
|
||||
.messageId(modMailMessage.getMessageId())
|
||||
.userId(modMailMessage.getAuthor().getUserReference().getId())
|
||||
.serverId(thread.getServer().getId());
|
||||
// if its not from a private chat, we need to set channel ID in order to fetch the data
|
||||
@@ -46,6 +45,9 @@ public class ModMailMessageServiceBean implements ModMailMessageService {
|
||||
log.trace("Message {} was from DM.", modMailMessage.getMessageId());
|
||||
serverChannelMessageBuilder
|
||||
.channelId(modMailMessage.getThreadReference().getChannel().getId());
|
||||
serverChannelMessageBuilder.messageId(modMailMessage.getCreatedMessageInChannel());
|
||||
} else {
|
||||
serverChannelMessageBuilder.messageId(modMailMessage.getCreatedMessageInDM());
|
||||
}
|
||||
messageIds.add(serverChannelMessageBuilder.build());
|
||||
});
|
||||
|
||||
@@ -17,6 +17,7 @@ import dev.sheldan.abstracto.core.utils.CompletableFutureList;
|
||||
import dev.sheldan.abstracto.core.utils.FutureUtils;
|
||||
import dev.sheldan.abstracto.modmail.config.*;
|
||||
import dev.sheldan.abstracto.modmail.exception.ModMailCategoryIdException;
|
||||
import dev.sheldan.abstracto.modmail.exception.ModMailThreadChannelNotFound;
|
||||
import dev.sheldan.abstracto.modmail.exception.ModMailThreadNotFoundException;
|
||||
import dev.sheldan.abstracto.modmail.models.dto.LoadedModmailThreadMessageList;
|
||||
import dev.sheldan.abstracto.modmail.models.database.*;
|
||||
@@ -57,6 +58,7 @@ public class ModMailThreadServiceBean implements ModMailThreadService {
|
||||
* The template key used for default mod mail exceptions
|
||||
*/
|
||||
public static final String MODMAIL_EXCEPTION_GENERIC_TEMPLATE = "modmail_exception_generic";
|
||||
public static final String MODMAIL_STAFF_MESSAGE_TEMPLATE_KEY = "modmail_staff_message";
|
||||
|
||||
@Autowired
|
||||
private ModMailThreadManagementService modMailThreadManagementService;
|
||||
@@ -184,7 +186,7 @@ public class ModMailThreadServiceBean implements ModMailThreadService {
|
||||
ModMailThread thread = createThreadObject(channel, aUserInAServer);
|
||||
if(initialMessage != null) {
|
||||
log.trace("Adding initial message {} to modmail thread in channel {}.", initialMessage.getId(), channel.getId());
|
||||
modMailMessageManagementService.addMessageToThread(thread, sendMessage, aUserInAServer, false, false);
|
||||
modMailMessageManagementService.addMessageToThread(thread, null, sendMessage, initialMessage, aUserInAServer, false, false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -327,22 +329,22 @@ public class ModMailThreadServiceBean implements ModMailThreadService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Message> relayMessageToModMailThread(ModMailThread modMailThread, Message message, List<UndoActionInstance> undoActions) {
|
||||
public CompletableFuture<Message> relayMessageToModMailThread(ModMailThread modMailThread, Message messageFromUser, List<UndoActionInstance> undoActions) {
|
||||
Long serverId = modMailThread.getServer().getId();
|
||||
Long channelId = modMailThread.getChannel().getId();
|
||||
Long modmailThreadId = modMailThread.getId();
|
||||
log.trace("Relaying message {} to modmail thread {} for user {} to server {}.", message.getId(), modMailThread.getId(), message.getAuthor().getIdLong(), modMailThread.getServer().getId());
|
||||
return botService.getMemberInServerAsync(modMailThread.getServer().getId(), message.getAuthor().getIdLong()).thenCompose(member -> {
|
||||
log.trace("Relaying message {} to modmail thread {} for user {} to server {}.", messageFromUser.getId(), modMailThread.getId(), messageFromUser.getAuthor().getIdLong(), modMailThread.getServer().getId());
|
||||
return botService.getMemberInServerAsync(modMailThread.getServer().getId(), messageFromUser.getAuthor().getIdLong()).thenCompose(member -> {
|
||||
Optional<TextChannel> textChannelFromServer = botService.getTextChannelFromServerOptional(serverId, channelId);
|
||||
if(textChannelFromServer.isPresent()) {
|
||||
TextChannel textChannel = textChannelFromServer.get();
|
||||
return self.sendUserReply(textChannel, modmailThreadId, message, member, true);
|
||||
return self.sendUserReply(textChannel, modmailThreadId, messageFromUser, member, true);
|
||||
} else {
|
||||
log.warn("Closing modmail thread {}, because it seems the channel {} in server {} got deleted.", modmailThreadId, channelId, serverId);
|
||||
log.warn("Closing mod mail thread {}, because it seems the channel {} in server {} got deleted.", modmailThreadId, channelId, serverId);
|
||||
// in this case there was no text channel on the server associated with the mod mail thread
|
||||
// close the existing one, so the user can start a new one
|
||||
self.closeModMailThreadInDb(modmailThreadId);
|
||||
return message.getChannel().sendMessage(templateService.renderTemplate("modmail_failed_to_forward_message", new Object())).submit();
|
||||
return messageFromUser.getChannel().sendMessage(templateService.renderTemplate("modmail_failed_to_forward_message", new Object())).submit();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -354,12 +356,12 @@ public class ModMailThreadServiceBean implements ModMailThreadService {
|
||||
* side.
|
||||
* @param textChannel The {@link TextChannel} in which the {@link ModMailThread} is being handled
|
||||
* @param modMailThreadId The id of the modmail thread to which the received {@link Message} is a reply to, can be null, if it is null, its the initial message
|
||||
* @param message The received message from the user
|
||||
* @param messageFromUser The received message from the user
|
||||
* @param member The {@link Member} instance from the user the thread is about. It is used as author
|
||||
* @param modMailThreadExists Whether or not the modmail thread already exists and is persisted.
|
||||
* @return A {@link CompletableFuture} which resolves when the post processing of the message is completed (adding read notification, and storing messageIDs)
|
||||
*/
|
||||
public CompletableFuture<Message> sendUserReply(TextChannel textChannel, Long modMailThreadId, Message message, Member member, boolean modMailThreadExists) {
|
||||
public CompletableFuture<Message> sendUserReply(TextChannel textChannel, Long modMailThreadId, Message messageFromUser, Member member, boolean modMailThreadExists) {
|
||||
List<CompletableFuture<Member>> subscriberMemberFutures = new ArrayList<>();
|
||||
if(modMailThreadExists) {
|
||||
ModMailThread modMailThread = modMailThreadManagementService.getById(modMailThreadId);
|
||||
@@ -378,7 +380,7 @@ public class ModMailThreadServiceBean implements ModMailThreadService {
|
||||
List<FullUserInServer> subscribers = new ArrayList<>();
|
||||
ModMailUserReplyModel modMailUserReplyModel = ModMailUserReplyModel
|
||||
.builder()
|
||||
.postedMessage(message)
|
||||
.postedMessage(messageFromUser)
|
||||
.member(member)
|
||||
.subscribers(subscribers)
|
||||
.build();
|
||||
@@ -387,11 +389,11 @@ public class ModMailThreadServiceBean implements ModMailThreadService {
|
||||
return CompletableFuture.allOf(completableFutures.toArray(new CompletableFuture[0]))
|
||||
.thenCompose(aVoid -> {
|
||||
log.trace("Adding read reaction to initial message for mod mail thread in channel {}.", textChannel.getGuild().getId());
|
||||
return messageService.addReactionToMessageWithFuture("readReaction", textChannel.getGuild().getIdLong(), message);
|
||||
return messageService.addReactionToMessageWithFuture("readReaction", textChannel.getGuild().getIdLong(), messageFromUser);
|
||||
})
|
||||
.thenApply(aVoid -> {
|
||||
if(modMailThreadExists) {
|
||||
self.postProcessSendMessages(textChannel, completableFutures.get(0).join());
|
||||
self.postProcessSendMessages(textChannel, completableFutures.get(0).join(), messageFromUser);
|
||||
}
|
||||
return completableFutures.get(0).join();
|
||||
});
|
||||
@@ -403,26 +405,28 @@ public class ModMailThreadServiceBean implements ModMailThreadService {
|
||||
/**
|
||||
* This message handles the post processing of the messages received by the user. This includes: saving the messageIDs
|
||||
* in the database, updating the state of the {@link ModMailThread} and adding the read reaction to the user message
|
||||
* @param message The actual {@link Message} instance received from the user.
|
||||
* @param textChannel The channel in which the message
|
||||
* @param messageInModMailThread The actual {@link Message} instance which was sent to the mod mail thread
|
||||
* @param messageFromUser The {@link Message} object which was sent from the user
|
||||
*/
|
||||
@Transactional
|
||||
public void postProcessSendMessages(TextChannel textChannel, Message message) {
|
||||
Optional<ModMailThread> modMailThreadOpt = modMailThreadManagementService.getByIdOptional(textChannel.getIdLong());
|
||||
public void postProcessSendMessages(TextChannel textChannel, Message messageInModMailThread, Message messageFromUser) {
|
||||
Optional<ModMailThread> modMailThreadOpt = modMailThreadManagementService.getByChannelIdOptional(textChannel.getIdLong());
|
||||
if(modMailThreadOpt.isPresent()) {
|
||||
ModMailThread modMailThread = modMailThreadOpt.get();
|
||||
log.trace("Adding message {} sent from user to modmail thread {} and setting status to {}.", message.getId(), modMailThread.getId(), ModMailThreadState.USER_REPLIED);
|
||||
modMailMessageManagementService.addMessageToThread(modMailThread, message, modMailThread.getUser(), false, false);
|
||||
log.trace("Adding created message {} based on messeage {} sent from user to modmail thread {} and setting status to {}.", messageInModMailThread.getId(), messageFromUser.getId(), modMailThread.getId(), ModMailThreadState.USER_REPLIED);
|
||||
modMailMessageManagementService.addMessageToThread(modMailThread, null, messageInModMailThread, messageFromUser, modMailThread.getUser(), false, false);
|
||||
// update the state of the thread
|
||||
modMailThreadManagementService.setModMailThreadState(modMailThread, ModMailThreadState.USER_REPLIED);
|
||||
} else {
|
||||
throw new ModMailThreadNotFoundException(textChannel.getIdLong());
|
||||
throw new ModMailThreadChannelNotFound();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> relayMessageToDm(Long modmailThreadId, String text, Message message, boolean anonymous, MessageChannel feedBack, List<UndoActionInstance> undoActions, Member targetMember) {
|
||||
log.info("Relaying message {} to user {} in modmail thread {} on server {}.", message.getId(), targetMember.getId(), modmailThreadId, targetMember.getGuild().getId());
|
||||
AUserInAServer moderator = userInServerManagementService.loadUser(message.getMember());
|
||||
public CompletableFuture<Void> relayMessageToDm(Long modmailThreadId, String text, Message replyCommandMessage, boolean anonymous, MessageChannel feedBack, List<UndoActionInstance> undoActions, Member targetMember) {
|
||||
log.info("Relaying message {} to user {} in modmail thread {} on server {}.", replyCommandMessage.getId(), targetMember.getId(), modmailThreadId, targetMember.getGuild().getId());
|
||||
AUserInAServer moderator = userInServerManagementService.loadUser(replyCommandMessage.getMember());
|
||||
ModMailThread modMailThread = modMailThreadManagementService.getById(modmailThreadId);
|
||||
FullUserInServer fullThreadUser = FullUserInServer
|
||||
.builder()
|
||||
@@ -433,7 +437,7 @@ public class ModMailThreadServiceBean implements ModMailThreadService {
|
||||
.builder()
|
||||
.text(text)
|
||||
.modMailThread(modMailThread)
|
||||
.postedMessage(message)
|
||||
.postedMessage(replyCommandMessage)
|
||||
.anonymous(anonymous)
|
||||
.threadUser(fullThreadUser);
|
||||
if(anonymous) {
|
||||
@@ -445,9 +449,16 @@ public class ModMailThreadServiceBean implements ModMailThreadService {
|
||||
modMailModeratorReplyModelBuilder.moderator(moderatorMember);
|
||||
}
|
||||
ModMailModeratorReplyModel modMailUserReplyModel = modMailModeratorReplyModelBuilder.build();
|
||||
CompletableFuture<Message> future = messageService.sendEmbedToUserWithMessage(targetMember.getUser(), "modmail_staff_message", modMailUserReplyModel);
|
||||
return future.thenAccept(sendMessage ->
|
||||
self.saveSendMessagesAndUpdateState(modmailThreadId, anonymous, moderator, sendMessage)
|
||||
MessageToSend messageToSend = templateService.renderEmbedTemplate(MODMAIL_STAFF_MESSAGE_TEMPLATE_KEY, modMailUserReplyModel);
|
||||
CompletableFuture<Message> future = messageService.sendMessageToSendToUser(targetMember.getUser(), messageToSend);
|
||||
CompletableFuture<Message> sameThreadMessageFuture;
|
||||
if(featureModeService.featureModeActive(ModMailFeatures.MOD_MAIL, modMailThread.getServer(), ModMailMode.SEPARATE_MESSAGE)) {
|
||||
sameThreadMessageFuture = channelService.sendMessageToSendToAChannel(messageToSend, modMailThread.getChannel()).get(0);
|
||||
} else {
|
||||
sameThreadMessageFuture = CompletableFuture.completedFuture(null);
|
||||
}
|
||||
return CompletableFuture.allOf(future, sameThreadMessageFuture).thenAccept(avoid ->
|
||||
self.saveSendMessagesAndUpdateState(modmailThreadId, anonymous, moderator, future.join(), replyCommandMessage, sameThreadMessageFuture.join())
|
||||
);
|
||||
}
|
||||
|
||||
@@ -481,6 +492,17 @@ public class ModMailThreadServiceBean implements ModMailThreadService {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isModMailThread(AChannel channel) {
|
||||
return modMailThreadManagementService.getByChannelOptional(channel).isPresent();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isModMailThread(Long channelId) {
|
||||
AChannel channel = channelManagementService.loadChannel(channelId);
|
||||
return modMailThreadManagementService.getByChannelOptional(channel).isPresent();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method takes the actively loaded futures, calls the method responsible for logging the messages, and calls the method
|
||||
* after the logging has been done.
|
||||
@@ -603,7 +625,13 @@ public class ModMailThreadServiceBean implements ModMailThreadService {
|
||||
log.info("Logging message {} in modmail thread {}.", loadedMessage.getId(), modMailThreadId);
|
||||
ModMailMessage modmailMessage = modMailThread.getMessages()
|
||||
.stream()
|
||||
.filter(modMailMessage -> modMailMessage.getMessageId().equals(loadedMessage.getIdLong()))
|
||||
.filter(modMailMessage -> {
|
||||
if(modMailMessage.getDmChannel()) {
|
||||
return modMailMessage.getCreatedMessageInDM().equals(loadedMessage.getIdLong());
|
||||
} else {
|
||||
return modMailMessage.getCreatedMessageInChannel().equals(loadedMessage.getIdLong());
|
||||
}
|
||||
})
|
||||
.findFirst().orElseThrow(() -> new AbstractoRunTimeException("Could not find desired message in list of messages in thread. This should not happen, as we just retrieved them from the same place."));
|
||||
Member author = futures.getMemberFuture().join();
|
||||
ModMailLoggedMessageModel modMailLoggedMessageModel =
|
||||
@@ -688,12 +716,12 @@ public class ModMailThreadServiceBean implements ModMailThreadService {
|
||||
* @throws ModMailThreadNotFoundException in case the {@link ModMailThread} is not found by the ID
|
||||
*/
|
||||
@Transactional
|
||||
public void saveSendMessagesAndUpdateState(Long modMailThreadId, Boolean anonymous, AUserInAServer moderator, Message message) {
|
||||
public void saveSendMessagesAndUpdateState(Long modMailThreadId, Boolean anonymous, AUserInAServer moderator, Message createdMessageInDM, Message replyCommandMessage, Message modMailThreadMessage) {
|
||||
Optional<ModMailThread> modMailThreadOpt = modMailThreadManagementService.getByIdOptional(modMailThreadId);
|
||||
if(modMailThreadOpt.isPresent()) {
|
||||
ModMailThread modMailThread = modMailThreadOpt.get();
|
||||
log.trace("Adding (anonymous: {}) message {} of moderator to modmail thread {} and setting state to {}.", anonymous, message.getId(), modMailThreadId, ModMailThreadState.MOD_REPLIED);
|
||||
modMailMessageManagementService.addMessageToThread(modMailThread, message, moderator, anonymous, true);
|
||||
log.trace("Adding (anonymous: {}) message {} of moderator to modmail thread {} and setting state to {}.", anonymous, createdMessageInDM.getId(), modMailThreadId, ModMailThreadState.MOD_REPLIED);
|
||||
modMailMessageManagementService.addMessageToThread(modMailThread, createdMessageInDM, modMailThreadMessage, replyCommandMessage, moderator, anonymous, true);
|
||||
modMailThreadManagementService.setModMailThreadState(modMailThread, ModMailThreadState.MOD_REPLIED);
|
||||
} else {
|
||||
throw new ModMailThreadNotFoundException(modMailThreadId);
|
||||
|
||||
@@ -10,6 +10,7 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
@@ -19,17 +20,21 @@ public class ModMailMessageManagementServiceBean implements ModMailMessageManage
|
||||
private ModMailMessageRepository modMailMessageRepository;
|
||||
|
||||
@Override
|
||||
public ModMailMessage addMessageToThread(ModMailThread modMailThread, Message message, AUserInAServer author, Boolean anonymous, Boolean dmChannel) {
|
||||
public ModMailMessage addMessageToThread(ModMailThread modMailThread, Message createdMessageInDM, Message createdMessageInChannel, Message userPostedMessage, AUserInAServer author, Boolean anonymous, Boolean dmChannel) {
|
||||
Long dmId = createdMessageInDM != null ? createdMessageInDM.getIdLong() : null;
|
||||
Long channelMessageId = createdMessageInChannel != null ? createdMessageInChannel.getIdLong() : null;
|
||||
ModMailMessage modMailMessage = ModMailMessage
|
||||
.builder()
|
||||
.author(author)
|
||||
.messageId(message.getIdLong())
|
||||
.messageId(userPostedMessage.getIdLong())
|
||||
.createdMessageInDM(dmId)
|
||||
.createdMessageInChannel(channelMessageId)
|
||||
.dmChannel(dmChannel)
|
||||
.threadReference(modMailThread)
|
||||
.anonymous(anonymous)
|
||||
.build();
|
||||
log.info("Storing modmail thread message {} to modmail thread {} of user {} in server {}.",
|
||||
message.getId(), modMailThread.getId(), author.getUserReference().getId(), author.getServerReference().getId());
|
||||
log.info("Storing created message in DM {} with created message in channel {} caused by message {} to modmail thread {} of user {} in server {}.",
|
||||
dmId, channelMessageId, userPostedMessage.getId(), modMailThread.getId(), author.getUserReference().getId(), author.getServerReference().getId());
|
||||
|
||||
modMailMessageRepository.save(modMailMessage);
|
||||
return modMailMessage;
|
||||
@@ -39,4 +44,14 @@ public class ModMailMessageManagementServiceBean implements ModMailMessageManage
|
||||
public List<ModMailMessage> getMessagesOfThread(ModMailThread modMailThread) {
|
||||
return modMailMessageRepository.findByThreadReference(modMailThread);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<ModMailMessage> getByMessageIdOptional(Long messageId) {
|
||||
return modMailMessageRepository.findByMessageId(messageId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteMessageFromThread(ModMailMessage modMailMessage) {
|
||||
modMailMessageRepository.delete(modMailMessage);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import dev.sheldan.abstracto.core.models.database.AChannel;
|
||||
import dev.sheldan.abstracto.core.models.database.AUser;
|
||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||
import dev.sheldan.abstracto.core.service.management.ChannelManagementService;
|
||||
import dev.sheldan.abstracto.modmail.exception.ModMailThreadChannelNotFound;
|
||||
import dev.sheldan.abstracto.modmail.exception.ModMailThreadNotFoundException;
|
||||
import dev.sheldan.abstracto.modmail.models.database.ModMailThread;
|
||||
import dev.sheldan.abstracto.modmail.models.database.ModMailThreadState;
|
||||
@@ -44,9 +45,20 @@ public class ModMailThreadManagementServiceBean implements ModMailThreadManageme
|
||||
|
||||
@Override
|
||||
public ModMailThread getByChannel(AChannel channel) {
|
||||
return modMailThreadRepository.findByChannel(channel).orElseThrow(ModMailThreadChannelNotFound::new);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<ModMailThread> getByChannelOptional(AChannel channel) {
|
||||
return modMailThreadRepository.findByChannel(channel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<ModMailThread> getByChannelIdOptional(Long channelId) {
|
||||
AChannel channel = channelManagementService.loadChannel(channelId);
|
||||
return getByChannelOptional(channel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ModMailThread> getThreadByUserAndState(AUserInAServer userInAServer, ModMailThreadState state) {
|
||||
return modMailThreadRepository.findByUserAndState(userInAServer, state);
|
||||
|
||||
@@ -10,10 +10,16 @@
|
||||
<property name="today" value="(SELECT NOW())"/>
|
||||
<changeSet author="Sheldan" id="modmail_default_feature_mode-insertion">
|
||||
<insert tableName="default_feature_mode">
|
||||
<column name="enabled" value="false"/>
|
||||
<column name="enabled" value="true"/>
|
||||
<column name="mode" value="log"/>
|
||||
<column name="feature_id" valueComputed="${modmailFeature}" />
|
||||
<column name="created" valueComputed="${today}"/>
|
||||
</insert>
|
||||
<insert tableName="default_feature_mode">
|
||||
<column name="enabled" value="true"/>
|
||||
<column name="mode" value="threadMessage"/>
|
||||
<column name="feature_id" valueComputed="${modmailFeature}" />
|
||||
<column name="created" valueComputed="${today}"/>
|
||||
</insert>
|
||||
</changeSet>
|
||||
</databaseChangeLog>
|
||||
@@ -6,10 +6,10 @@
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog ../../dbchangelog-3.8.xsd
|
||||
http://www.liquibase.org/xml/ns/dbchangelog-ext ../../dbchangelog-3.8.xsd
|
||||
http://www.liquibase.org/xml/ns/pro ../../dbchangelog-3.8.xsd" >
|
||||
<changeSet author="Sheldan" id="modmail_messages-table">
|
||||
<createTable tableName="modmail_messages">
|
||||
<changeSet author="Sheldan" id="modmail_message-table">
|
||||
<createTable tableName="modmail_message">
|
||||
<column name="message_id" type="BIGINT">
|
||||
<constraints nullable="false" primaryKey="true" primaryKeyName="modmail_messages_pkey"/>
|
||||
<constraints nullable="false" primaryKey="true" primaryKeyName="modmail_message_pkey"/>
|
||||
</column>
|
||||
<column name="anonymous" type="BOOLEAN"/>
|
||||
<column name="created" type="TIMESTAMP WITHOUT TIME ZONE"/>
|
||||
@@ -22,10 +22,10 @@
|
||||
</column>
|
||||
</createTable>
|
||||
</changeSet>
|
||||
<changeSet author="Sheldan" id="modmail_messages-fk_modmail_message_thread">
|
||||
<addForeignKeyConstraint baseColumnNames="thread_reference" baseTableName="modmail_messages" constraintName="fk_modmail_message_thread" deferrable="false" initiallyDeferred="false" onDelete="NO ACTION" onUpdate="NO ACTION" referencedColumnNames="id" referencedTableName="modmail_thread" validate="true"/>
|
||||
<changeSet author="Sheldan" id="modmail_message-fk_modmail_message_thread">
|
||||
<addForeignKeyConstraint baseColumnNames="thread_reference" baseTableName="modmail_message" constraintName="fk_modmail_message_thread" deferrable="false" initiallyDeferred="false" onDelete="NO ACTION" onUpdate="NO ACTION" referencedColumnNames="id" referencedTableName="modmail_thread" validate="true"/>
|
||||
</changeSet>
|
||||
<changeSet author="Sheldan" id="modmail_messages-fk_modmail_message_author">
|
||||
<addForeignKeyConstraint baseColumnNames="modmail_message_author" baseTableName="modmail_messages" constraintName="fk_modmail_message_author" deferrable="false" initiallyDeferred="false" onDelete="NO ACTION" onUpdate="NO ACTION" referencedColumnNames="user_in_server_id" referencedTableName="user_in_server" validate="true"/>
|
||||
<changeSet author="Sheldan" id="modmail_message-fk_modmail_message_author">
|
||||
<addForeignKeyConstraint baseColumnNames="modmail_message_author" baseTableName="modmail_message" constraintName="fk_modmail_message_author" deferrable="false" initiallyDeferred="false" onDelete="NO ACTION" onUpdate="NO ACTION" referencedColumnNames="user_in_server_id" referencedTableName="user_in_server" validate="true"/>
|
||||
</changeSet>
|
||||
</databaseChangeLog>
|
||||
@@ -6,10 +6,10 @@
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog ../../dbchangelog-3.8.xsd
|
||||
http://www.liquibase.org/xml/ns/dbchangelog-ext ../../dbchangelog-3.8.xsd
|
||||
http://www.liquibase.org/xml/ns/pro ../../dbchangelog-3.8.xsd" >
|
||||
<changeSet author="Sheldan" id="modmail_roles-table">
|
||||
<createTable tableName="modmail_roles">
|
||||
<changeSet author="Sheldan" id="modmail_role-table">
|
||||
<createTable tableName="modmail_role">
|
||||
<column autoIncrement="true" name="mod_mail_role_id" type="BIGINT">
|
||||
<constraints nullable="false" primaryKey="true" primaryKeyName="modmail_roles_pkey"/>
|
||||
<constraints nullable="false" primaryKey="true" primaryKeyName="modmail_role_pkey"/>
|
||||
</column>
|
||||
<column name="created" type="TIMESTAMP WITHOUT TIME ZONE"/>
|
||||
<column name="updated" type="TIMESTAMP WITHOUT TIME ZONE"/>
|
||||
@@ -21,10 +21,10 @@
|
||||
</column>
|
||||
</createTable>
|
||||
</changeSet>
|
||||
<changeSet author="Sheldan" id="modmail_roles-fk_modmail_role_role">
|
||||
<addForeignKeyConstraint baseColumnNames="modmail_role" baseTableName="modmail_roles" constraintName="fk_modmail_role_role" deferrable="false" initiallyDeferred="false" onDelete="NO ACTION" onUpdate="NO ACTION" referencedColumnNames="id" referencedTableName="role" validate="true"/>
|
||||
<changeSet author="Sheldan" id="modmail_role-fk_modmail_role_role">
|
||||
<addForeignKeyConstraint baseColumnNames="modmail_role" baseTableName="modmail_role" constraintName="fk_modmail_role_role" deferrable="false" initiallyDeferred="false" onDelete="NO ACTION" onUpdate="NO ACTION" referencedColumnNames="id" referencedTableName="role" validate="true"/>
|
||||
</changeSet>
|
||||
<changeSet author="Sheldan" id="modmail_roles-fk_modmail_role_server">
|
||||
<addForeignKeyConstraint baseColumnNames="modmail_role_server" baseTableName="modmail_roles" constraintName="fk_modmail_role_server" deferrable="false" initiallyDeferred="false" onDelete="NO ACTION" onUpdate="NO ACTION" referencedColumnNames="id" referencedTableName="server" validate="true"/>
|
||||
<changeSet author="Sheldan" id="modmail_role-fk_modmail_role_server">
|
||||
<addForeignKeyConstraint baseColumnNames="modmail_role_server" baseTableName="modmail_role" constraintName="fk_modmail_role_server" deferrable="false" initiallyDeferred="false" onDelete="NO ACTION" onUpdate="NO ACTION" referencedColumnNames="id" referencedTableName="server" validate="true"/>
|
||||
</changeSet>
|
||||
</databaseChangeLog>
|
||||
@@ -6,8 +6,8 @@
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog ../../dbchangelog-3.8.xsd
|
||||
http://www.liquibase.org/xml/ns/dbchangelog-ext ../../dbchangelog-3.8.xsd
|
||||
http://www.liquibase.org/xml/ns/pro ../../dbchangelog-3.8.xsd" >
|
||||
<include file="modmail_threads.xml" relativeToChangelogFile="true"/>
|
||||
<include file="modmail_messages.xml" relativeToChangelogFile="true"/>
|
||||
<include file="modmail_thread.xml" relativeToChangelogFile="true"/>
|
||||
<include file="modmail_message.xml" relativeToChangelogFile="true"/>
|
||||
<include file="modmail_subscriber.xml" relativeToChangelogFile="true"/>
|
||||
<include file="modmail_roles.xml" relativeToChangelogFile="true"/>
|
||||
<include file="modmail_role.xml" relativeToChangelogFile="true"/>
|
||||
</databaseChangeLog>
|
||||
@@ -0,0 +1,142 @@
|
||||
package dev.sheldan.abstracto.modmail.listener;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.AServerAChannelAUser;
|
||||
import dev.sheldan.abstracto.core.models.GuildChannelMember;
|
||||
import dev.sheldan.abstracto.core.models.cache.CachedMessage;
|
||||
import dev.sheldan.abstracto.core.models.database.AChannel;
|
||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||
import dev.sheldan.abstracto.core.models.database.AUser;
|
||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||
import dev.sheldan.abstracto.core.service.BotService;
|
||||
import dev.sheldan.abstracto.core.service.MessageService;
|
||||
import dev.sheldan.abstracto.modmail.models.database.ModMailMessage;
|
||||
import dev.sheldan.abstracto.modmail.models.database.ModMailThread;
|
||||
import dev.sheldan.abstracto.modmail.service.management.ModMailMessageManagementService;
|
||||
import net.dv8tion.jda.api.entities.Member;
|
||||
import net.dv8tion.jda.api.entities.User;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class ModMailMessageDeletedListenerTest {
|
||||
|
||||
@InjectMocks
|
||||
private ModMailMessageDeletedListener testUnit;
|
||||
|
||||
@Mock
|
||||
private ModMailMessageManagementService modMailMessageManagementService;
|
||||
|
||||
@Mock
|
||||
private MessageService messageService;
|
||||
|
||||
@Mock
|
||||
private ModMailMessageDeletedListener self;
|
||||
|
||||
@Mock
|
||||
private BotService botService;
|
||||
|
||||
@Mock
|
||||
private CachedMessage deletedMessage;
|
||||
|
||||
@Mock
|
||||
private AServerAChannelAUser origin;
|
||||
|
||||
@Mock
|
||||
private GuildChannelMember jdaOrigin;
|
||||
|
||||
@Mock
|
||||
private ModMailMessage modMailMessage;
|
||||
|
||||
@Mock
|
||||
private Member targetMember;
|
||||
|
||||
@Mock
|
||||
private User targetUser;
|
||||
|
||||
@Mock
|
||||
private AServer server;
|
||||
|
||||
@Mock
|
||||
private AChannel channel;
|
||||
|
||||
private static final Long DELETED_MESSAGE_ID = 4L;
|
||||
private static final Long CREATED_MESSAGE_ID_1 = 3L;
|
||||
private static final Long CREATED_MESSAGE_ID_2 = 5L;
|
||||
private static final Long USER_ID = 5L;
|
||||
private static final Long SERVER_ID = 6L;
|
||||
private static final Long CHANNEL_ID = 9L;
|
||||
|
||||
@Test
|
||||
public void testDeleteOutSideOfThread() {
|
||||
when(deletedMessage.getMessageId()).thenReturn(DELETED_MESSAGE_ID);
|
||||
when(modMailMessageManagementService.getByMessageIdOptional(DELETED_MESSAGE_ID)).thenReturn(Optional.empty());
|
||||
testUnit.execute(deletedMessage, origin, jdaOrigin);
|
||||
verify(botService, times(0)).getMemberInServerAsync(anyLong(), anyLong());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteNonDuplicatedMessage() {
|
||||
when(deletedMessage.getMessageId()).thenReturn(DELETED_MESSAGE_ID);
|
||||
when(deletedMessage.getServerId()).thenReturn(SERVER_ID);
|
||||
when(modMailMessageManagementService.getByMessageIdOptional(DELETED_MESSAGE_ID)).thenReturn(Optional.of(modMailMessage));
|
||||
ModMailThread thread = Mockito.mock(ModMailThread.class);
|
||||
AUserInAServer targetUsInAServer = Mockito.mock(AUserInAServer.class);
|
||||
when(thread.getUser()).thenReturn(targetUsInAServer);
|
||||
when(thread.getChannel()).thenReturn(channel);
|
||||
when(thread.getServer()).thenReturn(server);
|
||||
AUser targetAUser = Mockito.mock(AUser.class);
|
||||
when(targetUsInAServer.getUserReference()).thenReturn(targetAUser);
|
||||
when(modMailMessage.getCreatedMessageInChannel()).thenReturn(null);
|
||||
when(modMailMessage.getCreatedMessageInDM()).thenReturn(CREATED_MESSAGE_ID_2);
|
||||
when(targetAUser.getId()).thenReturn(USER_ID);
|
||||
when(modMailMessage.getThreadReference()).thenReturn(thread);
|
||||
when(targetMember.getUser()).thenReturn(targetUser);
|
||||
when(botService.getMemberInServerAsync(SERVER_ID, USER_ID)).thenReturn(CompletableFuture.completedFuture(targetMember));
|
||||
when(messageService.deleteMessageInChannelWithUser(targetUser, CREATED_MESSAGE_ID_2)).thenReturn(CompletableFuture.completedFuture(null));
|
||||
testUnit.execute(deletedMessage, origin, jdaOrigin);
|
||||
verify(messageService, times(0)).deleteMessageInChannelInServer(eq(SERVER_ID), anyLong(), any());
|
||||
verify(self, times(1)).removeMessageFromThread(DELETED_MESSAGE_ID);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteDuplicatedMessage() {
|
||||
when(deletedMessage.getMessageId()).thenReturn(DELETED_MESSAGE_ID);
|
||||
when(deletedMessage.getServerId()).thenReturn(SERVER_ID);
|
||||
when(modMailMessageManagementService.getByMessageIdOptional(DELETED_MESSAGE_ID)).thenReturn(Optional.of(modMailMessage));
|
||||
ModMailThread thread = Mockito.mock(ModMailThread.class);
|
||||
AUserInAServer targetUsInAServer = Mockito.mock(AUserInAServer.class);
|
||||
when(thread.getUser()).thenReturn(targetUsInAServer);
|
||||
when(thread.getChannel()).thenReturn(channel);
|
||||
when(thread.getServer()).thenReturn(server);
|
||||
when(server.getId()).thenReturn(SERVER_ID);
|
||||
when(channel.getId()).thenReturn(CHANNEL_ID);
|
||||
AUser targetAUser = Mockito.mock(AUser.class);
|
||||
when(targetUsInAServer.getUserReference()).thenReturn(targetAUser);
|
||||
when(modMailMessage.getCreatedMessageInChannel()).thenReturn(CREATED_MESSAGE_ID_1);
|
||||
when(modMailMessage.getCreatedMessageInDM()).thenReturn(CREATED_MESSAGE_ID_2);
|
||||
when(targetAUser.getId()).thenReturn(USER_ID);
|
||||
when(modMailMessage.getThreadReference()).thenReturn(thread);
|
||||
when(targetMember.getUser()).thenReturn(targetUser);
|
||||
when(botService.getMemberInServerAsync(SERVER_ID, USER_ID)).thenReturn(CompletableFuture.completedFuture(targetMember));
|
||||
when(messageService.deleteMessageInChannelWithUser(targetUser, CREATED_MESSAGE_ID_2)).thenReturn(CompletableFuture.completedFuture(null));
|
||||
when(messageService.deleteMessageInChannelInServer(SERVER_ID, CHANNEL_ID, CREATED_MESSAGE_ID_1)).thenReturn(CompletableFuture.completedFuture(null));
|
||||
testUnit.execute(deletedMessage, origin, jdaOrigin);
|
||||
verify(self, times(1)).removeMessageFromThread(DELETED_MESSAGE_ID);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void removeMessageFromThread() {
|
||||
when(modMailMessageManagementService.getByMessageIdOptional(DELETED_MESSAGE_ID)).thenReturn(Optional.of(modMailMessage));
|
||||
testUnit.removeMessageFromThread(DELETED_MESSAGE_ID);
|
||||
verify(modMailMessageManagementService, times(1)).deleteMessageFromThread(modMailMessage);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,273 @@
|
||||
package dev.sheldan.abstracto.modmail.listener;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.config.Parameters;
|
||||
import dev.sheldan.abstracto.core.command.service.CommandRegistry;
|
||||
import dev.sheldan.abstracto.core.command.service.CommandService;
|
||||
import dev.sheldan.abstracto.core.models.cache.CachedMessage;
|
||||
import dev.sheldan.abstracto.core.models.database.AChannel;
|
||||
import dev.sheldan.abstracto.core.models.database.AUser;
|
||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||
import dev.sheldan.abstracto.core.service.BotService;
|
||||
import dev.sheldan.abstracto.core.service.ChannelService;
|
||||
import dev.sheldan.abstracto.core.service.MessageService;
|
||||
import dev.sheldan.abstracto.modmail.models.database.ModMailMessage;
|
||||
import dev.sheldan.abstracto.modmail.models.database.ModMailThread;
|
||||
import dev.sheldan.abstracto.modmail.models.template.ModMailModeratorReplyModel;
|
||||
import dev.sheldan.abstracto.modmail.service.ModMailThreadService;
|
||||
import dev.sheldan.abstracto.modmail.service.ModMailThreadServiceBean;
|
||||
import dev.sheldan.abstracto.modmail.service.management.ModMailMessageManagementService;
|
||||
import dev.sheldan.abstracto.templating.model.MessageToSend;
|
||||
import dev.sheldan.abstracto.templating.service.TemplateService;
|
||||
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.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.*;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import static dev.sheldan.abstracto.modmail.listener.ModMailMessageEditedListener.DEFAULT_COMMAND_FOR_MODMAIL_EDIT;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class ModMailMessageEditedListenerTest {
|
||||
|
||||
@InjectMocks
|
||||
private ModMailMessageEditedListener testUnit;
|
||||
|
||||
@Mock
|
||||
private ModMailThreadService modMailThreadService;
|
||||
|
||||
@Mock
|
||||
private ModMailMessageManagementService modMailMessageManagementService;
|
||||
|
||||
@Mock
|
||||
private CommandRegistry commandRegistry;
|
||||
|
||||
@Mock
|
||||
private CommandService commandService;
|
||||
|
||||
@Mock
|
||||
private BotService botService;
|
||||
|
||||
@Mock
|
||||
private TemplateService templateService;
|
||||
|
||||
@Mock
|
||||
private ChannelService channelService;
|
||||
|
||||
@Mock
|
||||
private MessageService messageService;
|
||||
|
||||
@Mock
|
||||
private ModMailMessageEditedListener self;
|
||||
|
||||
@Mock
|
||||
private CachedMessage messageBefore;
|
||||
|
||||
@Mock
|
||||
private Message messageAfter;
|
||||
|
||||
@Mock
|
||||
private ModMailMessage modMailMessage;
|
||||
|
||||
@Mock
|
||||
private Parameters parsedParameters;
|
||||
|
||||
@Mock
|
||||
private Member targetMember;
|
||||
|
||||
@Mock
|
||||
private User targetUser;
|
||||
|
||||
@Mock
|
||||
private MessageToSend messageToSend;
|
||||
|
||||
@Mock
|
||||
private Member authorMember;
|
||||
|
||||
@Mock
|
||||
private Guild guild;
|
||||
|
||||
@Captor
|
||||
private ArgumentCaptor<ModMailModeratorReplyModel> replyModelArgumentCaptor;
|
||||
|
||||
private static final Long CHANNEL_ID = 5L;
|
||||
private static final Long MESSAGE_ID = 6L;
|
||||
private static final Long CREATED_MESSAGE_ID = 10L;
|
||||
private static final String NEW_COMMAND_PART = "editedText";
|
||||
private static final String NEW_PARAM = "param";
|
||||
private static final String NEW_CONTENT = NEW_COMMAND_PART + " " + NEW_PARAM;
|
||||
private static final Long SERVER_ID = 4L;
|
||||
private static final Long USER_ID = 3L;
|
||||
private static final Long AUTHOR_USER_ID = 9L;
|
||||
|
||||
@Test
|
||||
public void testEditOutsideModMailThread() {
|
||||
when(modMailThreadService.isModMailThread(CHANNEL_ID)).thenReturn(false);
|
||||
when(messageBefore.getChannelId()).thenReturn(CHANNEL_ID);
|
||||
testUnit.execute(messageBefore, messageAfter);
|
||||
verify(modMailMessageManagementService, times(0)).getByMessageIdOptional(anyLong());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEditNotTrackedMessage() {
|
||||
when(modMailThreadService.isModMailThread(CHANNEL_ID)).thenReturn(true);
|
||||
when(messageBefore.getChannelId()).thenReturn(CHANNEL_ID);
|
||||
when(messageBefore.getMessageId()).thenReturn(MESSAGE_ID);
|
||||
when(modMailMessageManagementService.getByMessageIdOptional(MESSAGE_ID)).thenReturn(Optional.empty());
|
||||
testUnit.execute(messageBefore, messageAfter);
|
||||
verify(commandRegistry, times(0)).getCommandName(anyString(), anyLong());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEditMessageWithCorrectCommand() {
|
||||
when(modMailThreadService.isModMailThread(CHANNEL_ID)).thenReturn(true);
|
||||
when(messageBefore.getChannelId()).thenReturn(CHANNEL_ID);
|
||||
when(messageBefore.getMessageId()).thenReturn(MESSAGE_ID);
|
||||
when(messageBefore.getServerId()).thenReturn(SERVER_ID);
|
||||
when(modMailMessageManagementService.getByMessageIdOptional(MESSAGE_ID)).thenReturn(Optional.of(modMailMessage));
|
||||
ModMailThread thread = Mockito.mock(ModMailThread.class);
|
||||
when(modMailMessage.getThreadReference()).thenReturn(thread);
|
||||
AUserInAServer targetUsInAServer = Mockito.mock(AUserInAServer.class);
|
||||
when(thread.getUser()).thenReturn(targetUsInAServer);
|
||||
AUser targetUser = Mockito.mock(AUser.class);
|
||||
when(targetUsInAServer.getUserReference()).thenReturn(targetUser);
|
||||
when(targetUser.getId()).thenReturn(USER_ID);
|
||||
AUserInAServer authorUserInAServer = Mockito.mock(AUserInAServer.class);
|
||||
when(modMailMessage.getAuthor()).thenReturn(authorUserInAServer);
|
||||
AUser authorUser = Mockito.mock(AUser.class);
|
||||
when(authorUser.getId()).thenReturn(AUTHOR_USER_ID);
|
||||
when(authorUserInAServer.getUserReference()).thenReturn(authorUser);
|
||||
when(messageAfter.getContentRaw()).thenReturn(NEW_CONTENT);
|
||||
when(commandRegistry.getCommandName(NEW_COMMAND_PART, SERVER_ID)).thenReturn(NEW_COMMAND_PART);
|
||||
when(commandService.doesCommandExist(NEW_COMMAND_PART)).thenReturn(true);
|
||||
when(commandService.getParametersForCommand(NEW_COMMAND_PART, messageAfter)).thenReturn(CompletableFuture.completedFuture(parsedParameters));
|
||||
when(botService.getMemberInServerAsync(SERVER_ID, USER_ID)).thenReturn(CompletableFuture.completedFuture(targetMember));
|
||||
when(botService.getMemberInServerAsync(SERVER_ID, AUTHOR_USER_ID)).thenReturn(CompletableFuture.completedFuture(authorMember));
|
||||
testUnit.execute(messageBefore, messageAfter);
|
||||
verify(self, times(1)).updateMessageInThread(messageAfter, parsedParameters, targetMember, authorMember);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEditMessageWithInCorrectCommand() {
|
||||
when(modMailThreadService.isModMailThread(CHANNEL_ID)).thenReturn(true);
|
||||
when(messageBefore.getChannelId()).thenReturn(CHANNEL_ID);
|
||||
when(messageBefore.getMessageId()).thenReturn(MESSAGE_ID);
|
||||
when(messageBefore.getServerId()).thenReturn(SERVER_ID);
|
||||
when(modMailMessageManagementService.getByMessageIdOptional(MESSAGE_ID)).thenReturn(Optional.of(modMailMessage));
|
||||
ModMailThread thread = Mockito.mock(ModMailThread.class);
|
||||
when(modMailMessage.getThreadReference()).thenReturn(thread);
|
||||
AUserInAServer aUserInAServer = Mockito.mock(AUserInAServer.class);
|
||||
when(thread.getUser()).thenReturn(aUserInAServer);
|
||||
AUser user = Mockito.mock(AUser.class);
|
||||
when(aUserInAServer.getUserReference()).thenReturn(user);
|
||||
when(user.getId()).thenReturn(USER_ID);
|
||||
AUserInAServer authorUserInAServer = Mockito.mock(AUserInAServer.class);
|
||||
when(modMailMessage.getAuthor()).thenReturn(authorUserInAServer);
|
||||
AUser authorUser = Mockito.mock(AUser.class);
|
||||
when(authorUser.getId()).thenReturn(AUTHOR_USER_ID);
|
||||
when(authorUserInAServer.getUserReference()).thenReturn(authorUser);
|
||||
when(messageAfter.getContentRaw()).thenReturn(NEW_CONTENT);
|
||||
when(commandRegistry.getCommandName(NEW_COMMAND_PART, SERVER_ID)).thenReturn(NEW_COMMAND_PART);
|
||||
when(commandService.doesCommandExist(NEW_COMMAND_PART)).thenReturn(false);
|
||||
when(commandService.getParametersForCommand(DEFAULT_COMMAND_FOR_MODMAIL_EDIT, messageAfter)).thenReturn(CompletableFuture.completedFuture(parsedParameters));
|
||||
when(botService.getMemberInServerAsync(SERVER_ID, USER_ID)).thenReturn(CompletableFuture.completedFuture(targetMember));
|
||||
when(botService.getMemberInServerAsync(SERVER_ID, AUTHOR_USER_ID)).thenReturn(CompletableFuture.completedFuture(authorMember));
|
||||
testUnit.execute(messageBefore, messageAfter);
|
||||
verify(self, times(1)).updateMessageInThread(messageAfter, parsedParameters, targetMember, authorMember);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateAnonymousMessageInThreadNotDuplicated() {
|
||||
when(messageAfter.getIdLong()).thenReturn(MESSAGE_ID);
|
||||
when(modMailMessageManagementService.getByMessageIdOptional(MESSAGE_ID)).thenReturn(Optional.of(modMailMessage));
|
||||
when(modMailMessage.getAnonymous()).thenReturn(true);
|
||||
when(modMailMessage.getCreatedMessageInChannel()).thenReturn(null);
|
||||
when(modMailMessage.getCreatedMessageInDM()).thenReturn(CREATED_MESSAGE_ID);
|
||||
ModMailThread thread = Mockito.mock(ModMailThread.class);
|
||||
when(modMailMessage.getThreadReference()).thenReturn(thread);
|
||||
when(targetMember.getUser()).thenReturn(targetUser);
|
||||
when(authorMember.getGuild()).thenReturn(guild);
|
||||
when(guild.getIdLong()).thenReturn(SERVER_ID);
|
||||
when(parsedParameters.getParameters()).thenReturn(Arrays.asList(NEW_PARAM));
|
||||
when(templateService.renderEmbedTemplate(eq(ModMailThreadServiceBean.MODMAIL_STAFF_MESSAGE_TEMPLATE_KEY), replyModelArgumentCaptor.capture())).thenReturn(messageToSend);
|
||||
testUnit.updateMessageInThread(messageAfter, parsedParameters, targetMember, authorMember);
|
||||
verify(channelService, times(0)).editMessageInAChannel(eq(messageToSend), any(AChannel.class), anyLong());
|
||||
verify(messageService, times(1)).editMessageInDMChannel(targetUser, messageToSend, CREATED_MESSAGE_ID);
|
||||
Assert.assertTrue(replyModelArgumentCaptor.getValue().getAnonymous());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateAnonymousMessageInThreadDuplicated() {
|
||||
when(messageAfter.getIdLong()).thenReturn(MESSAGE_ID);
|
||||
when(modMailMessageManagementService.getByMessageIdOptional(MESSAGE_ID)).thenReturn(Optional.of(modMailMessage));
|
||||
when(modMailMessage.getAnonymous()).thenReturn(true);
|
||||
when(modMailMessage.getCreatedMessageInChannel()).thenReturn(CREATED_MESSAGE_ID);
|
||||
when(modMailMessage.getCreatedMessageInDM()).thenReturn(CREATED_MESSAGE_ID);
|
||||
ModMailThread thread = Mockito.mock(ModMailThread.class);
|
||||
when(modMailMessage.getThreadReference()).thenReturn(thread);
|
||||
when(targetMember.getUser()).thenReturn(targetUser);
|
||||
when(authorMember.getGuild()).thenReturn(guild);
|
||||
when(guild.getIdLong()).thenReturn(SERVER_ID);
|
||||
AChannel channel = Mockito.mock(AChannel.class);
|
||||
when(thread.getChannel()).thenReturn(channel);
|
||||
when(channel.getId()).thenReturn(CHANNEL_ID);
|
||||
when(parsedParameters.getParameters()).thenReturn(Arrays.asList(NEW_PARAM));
|
||||
when(templateService.renderEmbedTemplate(eq(ModMailThreadServiceBean.MODMAIL_STAFF_MESSAGE_TEMPLATE_KEY), replyModelArgumentCaptor.capture())).thenReturn(messageToSend);
|
||||
testUnit.updateMessageInThread(messageAfter, parsedParameters, targetMember, authorMember);
|
||||
verify(channelService, times(1)).editMessageInAChannel(eq(messageToSend), eq(channel), eq(CREATED_MESSAGE_ID));
|
||||
verify(messageService, times(1)).editMessageInDMChannel(targetUser, messageToSend, CREATED_MESSAGE_ID);
|
||||
Assert.assertTrue(replyModelArgumentCaptor.getValue().getAnonymous());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateMessageInThreadNotDuplicated() {
|
||||
when(messageAfter.getIdLong()).thenReturn(MESSAGE_ID);
|
||||
when(modMailMessageManagementService.getByMessageIdOptional(MESSAGE_ID)).thenReturn(Optional.of(modMailMessage));
|
||||
when(modMailMessage.getAnonymous()).thenReturn(false);
|
||||
when(modMailMessage.getCreatedMessageInChannel()).thenReturn(null);
|
||||
when(modMailMessage.getCreatedMessageInDM()).thenReturn(CREATED_MESSAGE_ID);
|
||||
ModMailThread thread = Mockito.mock(ModMailThread.class);
|
||||
when(modMailMessage.getThreadReference()).thenReturn(thread);
|
||||
when(targetMember.getUser()).thenReturn(targetUser);
|
||||
when(authorMember.getGuild()).thenReturn(guild);
|
||||
when(guild.getIdLong()).thenReturn(SERVER_ID);
|
||||
when(parsedParameters.getParameters()).thenReturn(Arrays.asList(NEW_PARAM));
|
||||
when(templateService.renderEmbedTemplate(eq(ModMailThreadServiceBean.MODMAIL_STAFF_MESSAGE_TEMPLATE_KEY), replyModelArgumentCaptor.capture())).thenReturn(messageToSend);
|
||||
testUnit.updateMessageInThread(messageAfter, parsedParameters, targetMember, authorMember);
|
||||
verify(channelService, times(0)).editMessageInAChannel(eq(messageToSend), any(AChannel.class), anyLong());
|
||||
verify(messageService, times(1)).editMessageInDMChannel(targetUser, messageToSend, CREATED_MESSAGE_ID);
|
||||
Assert.assertFalse(replyModelArgumentCaptor.getValue().getAnonymous());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateMessageInThreadDuplicated() {
|
||||
when(messageAfter.getIdLong()).thenReturn(MESSAGE_ID);
|
||||
when(modMailMessageManagementService.getByMessageIdOptional(MESSAGE_ID)).thenReturn(Optional.of(modMailMessage));
|
||||
when(modMailMessage.getAnonymous()).thenReturn(false);
|
||||
when(modMailMessage.getCreatedMessageInChannel()).thenReturn(CREATED_MESSAGE_ID);
|
||||
when(modMailMessage.getCreatedMessageInDM()).thenReturn(CREATED_MESSAGE_ID);
|
||||
ModMailThread thread = Mockito.mock(ModMailThread.class);
|
||||
when(modMailMessage.getThreadReference()).thenReturn(thread);
|
||||
when(targetMember.getUser()).thenReturn(targetUser);
|
||||
when(authorMember.getGuild()).thenReturn(guild);
|
||||
when(guild.getIdLong()).thenReturn(SERVER_ID);
|
||||
AChannel channel = Mockito.mock(AChannel.class);
|
||||
when(thread.getChannel()).thenReturn(channel);
|
||||
when(channel.getId()).thenReturn(CHANNEL_ID);
|
||||
when(parsedParameters.getParameters()).thenReturn(Arrays.asList(NEW_PARAM));
|
||||
when(templateService.renderEmbedTemplate(eq(ModMailThreadServiceBean.MODMAIL_STAFF_MESSAGE_TEMPLATE_KEY), replyModelArgumentCaptor.capture())).thenReturn(messageToSend);
|
||||
testUnit.updateMessageInThread(messageAfter, parsedParameters, targetMember, authorMember);
|
||||
verify(channelService, times(1)).editMessageInAChannel(eq(messageToSend), eq(channel), eq(CREATED_MESSAGE_ID));
|
||||
verify(messageService, times(1)).editMessageInDMChannel(targetUser, messageToSend, CREATED_MESSAGE_ID);
|
||||
Assert.assertFalse(replyModelArgumentCaptor.getValue().getAnonymous());
|
||||
}
|
||||
}
|
||||
@@ -48,7 +48,7 @@ public class ModMailFeature implements FeatureConfig {
|
||||
|
||||
@Override
|
||||
public List<FeatureMode> getAvailableModes() {
|
||||
return Arrays.asList(ModMailMode.LOGGING);
|
||||
return Arrays.asList(ModMailMode.LOGGING, ModMailMode.SEPARATE_MESSAGE);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -9,7 +9,7 @@ import lombok.Getter;
|
||||
*/
|
||||
@Getter
|
||||
public enum ModMailMode implements FeatureMode {
|
||||
LOGGING("log");
|
||||
LOGGING("log"), SEPARATE_MESSAGE("threadMessage");
|
||||
|
||||
private final String key;
|
||||
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
package dev.sheldan.abstracto.modmail.exception;
|
||||
|
||||
import dev.sheldan.abstracto.core.exception.AbstractoRunTimeException;
|
||||
|
||||
public class ModMailThreadChannelNotFound extends AbstractoRunTimeException {
|
||||
}
|
||||
@@ -5,6 +5,7 @@ import lombok.*;
|
||||
import org.hibernate.annotations.CacheConcurrencyStrategy;
|
||||
|
||||
import javax.persistence.*;
|
||||
import java.io.Serializable;
|
||||
import java.time.Instant;
|
||||
|
||||
/**
|
||||
@@ -16,19 +17,30 @@ import java.time.Instant;
|
||||
@Entity
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Table(name = "modmail_messages")
|
||||
@Cacheable
|
||||
@Table(name = "modmail_message")
|
||||
@Getter
|
||||
@Setter
|
||||
@EqualsAndHashCode
|
||||
@Cacheable
|
||||
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
|
||||
public class ModMailMessage {
|
||||
public class ModMailMessage implements Serializable {
|
||||
|
||||
/**
|
||||
* The globally unique message ID which was send in the mod mail thread, either by a user of by the staff handling the thread
|
||||
* The ID of the message which caused this message to be created, either the message containing the command or the message received from the user
|
||||
*/
|
||||
@Id
|
||||
private Long messageId;
|
||||
|
||||
/**
|
||||
* The message which got created:
|
||||
* for a message from the user, the messageId of the message in the thread
|
||||
* for a message from staff, the messageId of the message in the DM channel
|
||||
*/
|
||||
@Column(name = "created_message_in_dm")
|
||||
private Long createdMessageInDM;
|
||||
@Column
|
||||
private Long createdMessageInChannel;
|
||||
|
||||
/**
|
||||
* The {@link AUserInAServer} which authored this message
|
||||
*/
|
||||
@@ -39,18 +51,21 @@ public class ModMailMessage {
|
||||
/**
|
||||
* The {@link ModMailThread} in whose context this message was sent and this message is related to
|
||||
*/
|
||||
@ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
|
||||
@ManyToOne(fetch = FetchType.LAZY, cascade = {CascadeType.PERSIST, CascadeType.MERGE})
|
||||
@JoinColumn(name = "threadReference", nullable = false)
|
||||
private ModMailThread threadReference;
|
||||
|
||||
/**
|
||||
* Whether or not this message was from the user or a staff member, for convenience
|
||||
* true: message was send via command, false: message was send from the user
|
||||
* This is used to decide where to get the message from in case of logging, because the user might delete the message and we do not want to re-parse the command message
|
||||
*/
|
||||
@Column
|
||||
private Boolean dmChannel;
|
||||
|
||||
/**
|
||||
* Staff only: Whether or not this message meant to be sent anonymous
|
||||
*/
|
||||
@Column
|
||||
private Boolean anonymous;
|
||||
|
||||
@Column(name = "created")
|
||||
|
||||
@@ -6,6 +6,7 @@ import lombok.*;
|
||||
import org.hibernate.annotations.CacheConcurrencyStrategy;
|
||||
|
||||
import javax.persistence.*;
|
||||
import java.io.Serializable;
|
||||
import java.time.Instant;
|
||||
|
||||
/**
|
||||
@@ -16,12 +17,13 @@ import java.time.Instant;
|
||||
@Entity
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Table(name = "modmail_roles")
|
||||
@Cacheable
|
||||
@Table(name = "modmail_role")
|
||||
@Getter
|
||||
@Setter
|
||||
@EqualsAndHashCode
|
||||
@Cacheable
|
||||
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
|
||||
public class ModMailRole {
|
||||
public class ModMailRole implements Serializable {
|
||||
|
||||
/**
|
||||
* Unique ID of the mod mail role
|
||||
|
||||
@@ -5,6 +5,7 @@ import lombok.*;
|
||||
import org.hibernate.annotations.CacheConcurrencyStrategy;
|
||||
|
||||
import javax.persistence.*;
|
||||
import java.io.Serializable;
|
||||
import java.time.Instant;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -18,11 +19,12 @@ import java.util.List;
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Table(name = "modmail_thread")
|
||||
@Cacheable
|
||||
@Getter
|
||||
@Setter
|
||||
@EqualsAndHashCode
|
||||
@Cacheable
|
||||
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
|
||||
public class ModMailThread {
|
||||
public class ModMailThread implements Serializable {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
|
||||
@@ -16,9 +16,10 @@ import java.time.Instant;
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Table(name = "modmail_subscriber")
|
||||
@Cacheable
|
||||
@Getter
|
||||
@Setter
|
||||
@EqualsAndHashCode
|
||||
@Cacheable
|
||||
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
|
||||
public class ModMailThreadSubscriber {
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ package dev.sheldan.abstracto.modmail.service;
|
||||
|
||||
|
||||
import dev.sheldan.abstracto.core.models.UndoActionInstance;
|
||||
import dev.sheldan.abstracto.core.models.database.AChannel;
|
||||
import dev.sheldan.abstracto.core.models.database.AUser;
|
||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||
import dev.sheldan.abstracto.modmail.models.database.ModMailThread;
|
||||
@@ -50,9 +51,9 @@ public interface ModMailThreadService {
|
||||
* In case there was no channel found, this will cause a message to be shown to the user and the existing mod mail thread will be closed.
|
||||
* This is the case, if the mod mail thread was still open in the database, but no text channel was found anymore.
|
||||
* @param modMailThread The {@link ModMailThread} on which the user answered
|
||||
* @param message The {@link Message} object which was sent by the user to answer with
|
||||
* @param messageFromUser The {@link Message} object which was sent by the user as an answer
|
||||
*/
|
||||
CompletableFuture<Message> relayMessageToModMailThread(ModMailThread modMailThread, Message message, List<UndoActionInstance> undoActions);
|
||||
CompletableFuture<Message> relayMessageToModMailThread(ModMailThread modMailThread, Message messageFromUser, List<UndoActionInstance> undoActions);
|
||||
|
||||
/**
|
||||
* Forwards a message send by a moderator to the direct message channel opened with the user. If the message is
|
||||
@@ -91,4 +92,7 @@ public interface ModMailThreadService {
|
||||
* @param logThread Whether or not the thread should be logged to the appropriate post target
|
||||
*/
|
||||
CompletableFuture<Void> closeModMailThread(ModMailThread modMailThread, String note, boolean notifyUser, boolean logThread, List<UndoActionInstance> undoActions);
|
||||
|
||||
boolean isModMailThread(AChannel channel);
|
||||
boolean isModMailThread(Long channelId);
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import dev.sheldan.abstracto.modmail.models.database.ModMailThread;
|
||||
import net.dv8tion.jda.api.entities.Message;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* Management service to handle the creation and retrieval of {@link ModMailMessage} instances from the database
|
||||
@@ -14,13 +15,15 @@ public interface ModMailMessageManagementService {
|
||||
/**
|
||||
* Creates an instance of {@link ModMailMessage}, attaches it to the given {@link ModMailThread} and returns the created instance
|
||||
* @param modMailThread The {@link ModMailThread} the message should be attached to
|
||||
* @param message The {@link Message} which should be attached to the {@link ModMailThread}
|
||||
* @param createdMessageInDM The {@link Message} which should be attached to the {@link ModMailThread} and was posted to the DM channel (might be null)
|
||||
* @param createdMessageInChannel The {@link Message} which should be attached to the {@link ModMailThread} and was posted to the modmail thread (might be null)
|
||||
* @param userPostedMessage The {@link Message} which caused this message to be created, the command or the message by the user
|
||||
* @param author The {@link AUserInAServer} who authored the {@link Message} originally
|
||||
* @param anonymous Whether or not the message was sent anonymous (only possible by staff members)
|
||||
* @param dmChannel Whether or not the message originated from the user, and therefore in an direct message channel
|
||||
* @return
|
||||
*/
|
||||
ModMailMessage addMessageToThread(ModMailThread modMailThread, Message message, AUserInAServer author, Boolean anonymous, Boolean dmChannel);
|
||||
ModMailMessage addMessageToThread(ModMailThread modMailThread, Message createdMessageInDM, Message createdMessageInChannel, Message userPostedMessage, AUserInAServer author, Boolean anonymous, Boolean dmChannel);
|
||||
|
||||
/**
|
||||
* Retrieves all messages which were sent in a {@link ModMailThread}
|
||||
@@ -28,4 +31,8 @@ public interface ModMailMessageManagementService {
|
||||
* @return A list of {@link ModMailMessage} which were sent in the given thread
|
||||
*/
|
||||
List<ModMailMessage> getMessagesOfThread(ModMailThread modMailThread);
|
||||
|
||||
Optional<ModMailMessage> getByMessageIdOptional(Long messageId);
|
||||
|
||||
void deleteMessageFromThread(ModMailMessage modMailMessage);
|
||||
}
|
||||
|
||||
@@ -45,6 +45,8 @@ public interface ModMailThreadManagementService {
|
||||
* @return The found mod mail thread, or null if none was found
|
||||
*/
|
||||
ModMailThread getByChannel(AChannel channel);
|
||||
Optional<ModMailThread> getByChannelOptional(AChannel channel);
|
||||
Optional<ModMailThread> getByChannelIdOptional(Long channelId);
|
||||
|
||||
/**
|
||||
* Searches for mod mail threads with the appropriate staten which concern the given {@link AUserInAServer}
|
||||
|
||||
@@ -7,8 +7,8 @@ import lombok.*;
|
||||
import org.hibernate.annotations.CacheConcurrencyStrategy;
|
||||
|
||||
import javax.persistence.*;
|
||||
import java.io.Serializable;
|
||||
import java.time.Instant;
|
||||
import java.util.Objects;
|
||||
|
||||
@Entity
|
||||
@Table(name="embedded_message")
|
||||
@@ -17,9 +17,10 @@ import java.util.Objects;
|
||||
@NoArgsConstructor
|
||||
@Getter
|
||||
@Setter
|
||||
@EqualsAndHashCode
|
||||
@Cacheable
|
||||
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
|
||||
public class EmbeddedMessage {
|
||||
public class EmbeddedMessage implements Serializable {
|
||||
|
||||
@Getter
|
||||
@ManyToOne
|
||||
@@ -66,23 +67,5 @@ public class EmbeddedMessage {
|
||||
this.created = Instant.now();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
EmbeddedMessage that = (EmbeddedMessage) o;
|
||||
return Objects.equals(embeddedUser, that.embeddedUser) &&
|
||||
Objects.equals(embeddingUser, that.embeddingUser) &&
|
||||
Objects.equals(embeddedServer, that.embeddedServer) &&
|
||||
Objects.equals(embeddedChannel, that.embeddedChannel) &&
|
||||
Objects.equals(embeddedMessageId, that.embeddedMessageId) &&
|
||||
Objects.equals(embeddingServer, that.embeddingServer) &&
|
||||
Objects.equals(embeddingChannel, that.embeddingChannel) &&
|
||||
Objects.equals(embeddingMessageId, that.embeddingMessageId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(embeddedUser, embeddingUser, embeddedServer, embeddedChannel, embeddedMessageId, embeddingServer, embeddingChannel, embeddingMessageId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,8 +7,8 @@ import lombok.*;
|
||||
import org.hibernate.annotations.CacheConcurrencyStrategy;
|
||||
|
||||
import javax.persistence.*;
|
||||
import java.io.Serializable;
|
||||
import java.time.Instant;
|
||||
import java.util.Objects;
|
||||
|
||||
@Entity
|
||||
@Table(name="reminder")
|
||||
@@ -17,9 +17,10 @@ import java.util.Objects;
|
||||
@NoArgsConstructor
|
||||
@Getter
|
||||
@Setter
|
||||
@EqualsAndHashCode
|
||||
@Cacheable
|
||||
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
|
||||
public class Reminder {
|
||||
public class Reminder implements Serializable {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
@@ -73,24 +74,4 @@ public class Reminder {
|
||||
@Setter
|
||||
private String jobTriggerKey;
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
Reminder reminder = (Reminder) o;
|
||||
return reminded == reminder.reminded &&
|
||||
Objects.equals(id, reminder.id) &&
|
||||
Objects.equals(remindedUser, reminder.remindedUser) &&
|
||||
Objects.equals(messageId, reminder.messageId) &&
|
||||
Objects.equals(channel, reminder.channel) &&
|
||||
Objects.equals(server, reminder.server) &&
|
||||
Objects.equals(reminderDate, reminder.reminderDate) &&
|
||||
Objects.equals(targetDate, reminder.targetDate) &&
|
||||
Objects.equals(text, reminder.text);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(id, remindedUser, messageId, channel, server, reminderDate, targetDate, text, reminded);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,9 +6,9 @@ import lombok.*;
|
||||
import org.hibernate.annotations.CacheConcurrencyStrategy;
|
||||
|
||||
import javax.persistence.*;
|
||||
import java.io.Serializable;
|
||||
import java.time.Instant;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
@Entity
|
||||
@Table(name="starboard_post")
|
||||
@@ -17,9 +17,10 @@ import java.util.Objects;
|
||||
@NoArgsConstructor
|
||||
@Getter
|
||||
@Setter
|
||||
@EqualsAndHashCode
|
||||
@Cacheable
|
||||
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
|
||||
public class StarboardPost {
|
||||
public class StarboardPost implements Serializable {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
@@ -88,25 +89,4 @@ public class StarboardPost {
|
||||
return this.reactions.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
StarboardPost post = (StarboardPost) o;
|
||||
return ignored == post.ignored &&
|
||||
Objects.equals(id, post.id) &&
|
||||
Objects.equals(author, post.author) &&
|
||||
Objects.equals(starboardMessageId, post.starboardMessageId) &&
|
||||
Objects.equals(postMessageId, post.postMessageId) &&
|
||||
Objects.equals(starboardChannel, post.starboardChannel) &&
|
||||
Objects.equals(sourceChanel, post.sourceChanel) &&
|
||||
Objects.equals(reactionCount, post.reactionCount) &&
|
||||
Objects.equals(reactions, post.reactions) &&
|
||||
Objects.equals(starredDate, post.starredDate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(id, author, starboardMessageId, postMessageId, starboardChannel, sourceChanel, reactionCount, reactions, starredDate, ignored);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,8 +5,8 @@ import lombok.*;
|
||||
import org.hibernate.annotations.CacheConcurrencyStrategy;
|
||||
|
||||
import javax.persistence.*;
|
||||
import java.io.Serializable;
|
||||
import java.time.Instant;
|
||||
import java.util.Objects;
|
||||
|
||||
@Entity
|
||||
@Table(name="starboard_post_reaction")
|
||||
@@ -15,9 +15,10 @@ import java.util.Objects;
|
||||
@NoArgsConstructor
|
||||
@Getter
|
||||
@Setter
|
||||
@EqualsAndHashCode
|
||||
@Cacheable
|
||||
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
|
||||
public class StarboardPostReaction {
|
||||
public class StarboardPostReaction implements Serializable {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
@@ -40,18 +41,4 @@ public class StarboardPostReaction {
|
||||
this.created = Instant.now();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
StarboardPostReaction that = (StarboardPostReaction) o;
|
||||
return Objects.equals(id, that.id) &&
|
||||
Objects.equals(reactor, that.reactor) &&
|
||||
Objects.equals(starboardPost, that.starboardPost);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(id, reactor, starboardPost);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,8 +5,10 @@ import dev.sheldan.abstracto.core.models.database.AServer;
|
||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||
import dev.sheldan.abstracto.utility.models.SuggestionState;
|
||||
import lombok.*;
|
||||
import org.hibernate.annotations.CacheConcurrencyStrategy;
|
||||
|
||||
import javax.persistence.*;
|
||||
import java.io.Serializable;
|
||||
import java.time.Instant;
|
||||
import java.util.Objects;
|
||||
|
||||
@@ -17,7 +19,10 @@ import java.util.Objects;
|
||||
@NoArgsConstructor
|
||||
@Getter
|
||||
@Setter
|
||||
public class Suggestion {
|
||||
@EqualsAndHashCode
|
||||
@Cacheable
|
||||
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
|
||||
public class Suggestion implements Serializable {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
|
||||
@@ -2,11 +2,14 @@ package dev.sheldan.abstracto.core.command.service;
|
||||
|
||||
import com.google.common.collect.Iterables;
|
||||
import dev.sheldan.abstracto.core.command.Command;
|
||||
import dev.sheldan.abstracto.core.command.CommandReceivedHandler;
|
||||
import dev.sheldan.abstracto.core.command.condition.CommandCondition;
|
||||
import dev.sheldan.abstracto.core.command.condition.ConditionResult;
|
||||
import dev.sheldan.abstracto.core.command.condition.ConditionalCommand;
|
||||
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
|
||||
import dev.sheldan.abstracto.core.command.config.Parameters;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
||||
import dev.sheldan.abstracto.core.command.execution.UnParsedCommandParameter;
|
||||
import dev.sheldan.abstracto.core.command.models.database.ACommand;
|
||||
import dev.sheldan.abstracto.core.command.models.database.ACommandInAServer;
|
||||
import dev.sheldan.abstracto.core.command.models.database.AModule;
|
||||
@@ -19,10 +22,12 @@ import dev.sheldan.abstracto.core.models.database.AFeature;
|
||||
import dev.sheldan.abstracto.core.models.database.ARole;
|
||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.entities.Message;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
@@ -44,6 +49,12 @@ public class CommandServiceBean implements CommandService {
|
||||
@Autowired
|
||||
private CommandInServerManagementService commandInServerManagementService;
|
||||
|
||||
@Autowired
|
||||
private CommandRegistry commandRegistry;
|
||||
|
||||
@Autowired
|
||||
private CommandReceivedHandler commandReceivedHandler;
|
||||
|
||||
@Override
|
||||
public ACommand createCommand(String name, String moduleName, FeatureEnum featureEnum) {
|
||||
AModule module = moduleManagementService.getOrCreate(moduleName);
|
||||
@@ -151,6 +162,14 @@ public class CommandServiceBean implements CommandService {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Parameters> getParametersForCommand(String commandName, Message messageContainingContent) {
|
||||
String contentStripped = messageContainingContent.getContentRaw();
|
||||
UnParsedCommandParameter unParsedParameter = new UnParsedCommandParameter(contentStripped);
|
||||
Command command = commandRegistry.findCommandByParameters(commandName, unParsedParameter);
|
||||
return commandReceivedHandler.getParsedParameters(unParsedParameter, command, messageContainingContent);
|
||||
}
|
||||
|
||||
private ConditionResult checkConditions(CommandContext commandContext, Command command, List<CommandCondition> conditions) {
|
||||
if(conditions != null) {
|
||||
for (CommandCondition condition : conditions) {
|
||||
|
||||
@@ -6,6 +6,7 @@ import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import javax.persistence.*;
|
||||
import java.io.Serializable;
|
||||
|
||||
@Entity
|
||||
@Table(name = "lock")
|
||||
@@ -13,7 +14,7 @@ import javax.persistence.*;
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Getter
|
||||
public class ALock {
|
||||
public class ALock implements Serializable {
|
||||
@Id
|
||||
@Column(name = "id")
|
||||
private Long id;
|
||||
|
||||
@@ -130,10 +130,7 @@ public class BotServiceBean implements BotService {
|
||||
Optional<TextChannel> textChannelOptional = getTextChannelFromServerOptional(serverId, channelId);
|
||||
if(textChannelOptional.isPresent()) {
|
||||
TextChannel textChannel = textChannelOptional.get();
|
||||
return textChannel.deleteMessageById(messageId).submit().exceptionally(throwable -> {
|
||||
log.warn("Deleting the message {} in channel {} in guild {} failed.", messageId, channelId, serverId, throwable);
|
||||
return null;
|
||||
});
|
||||
return textChannel.deleteMessageById(messageId).submit();
|
||||
} else {
|
||||
log.warn("Could not find channel {} in guild {} to delete message {} in.", channelId, serverId, messageId);
|
||||
}
|
||||
|
||||
@@ -275,9 +275,25 @@ public class MessageServiceBean implements MessageService {
|
||||
channelService.sendEmbedTemplateInChannel(template, model, privateChannel).get(0));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Message> sendMessageToSendToUser(User user, MessageToSend messageToSend) {
|
||||
return user.openPrivateChannel().submit().thenCompose(privateChannel -> channelService.sendMessageToSendToChannel(messageToSend, privateChannel).get(0));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Message> sendMessageToUser(User user, String text) {
|
||||
log.trace("Sending direct string message to user {}.", user.getIdLong());
|
||||
return user.openPrivateChannel().flatMap(privateChannel -> privateChannel.sendMessage(text)).submit();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> deleteMessageInChannelWithUser(User user, Long messageId) {
|
||||
log.info("Deleting message {} in channel with user {}.", messageId, user.getIdLong());
|
||||
return user.openPrivateChannel().flatMap(privateChannel -> privateChannel.deleteMessageById(messageId)).submit();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> editMessageInDMChannel(User user, MessageToSend messageToSend, Long messageId) {
|
||||
return user.openPrivateChannel().submit().thenCompose(privateChannel -> channelService.editMessageInAChannelFuture(messageToSend, privateChannel, messageId).thenApply(message -> null));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,6 @@ import org.hibernate.annotations.CacheConcurrencyStrategy;
|
||||
import javax.persistence.*;
|
||||
import java.io.Serializable;
|
||||
import java.time.Instant;
|
||||
import java.util.Objects;
|
||||
|
||||
@Entity
|
||||
@Table(name = "command")
|
||||
@@ -16,6 +15,7 @@ import java.util.Objects;
|
||||
@AllArgsConstructor
|
||||
@Getter
|
||||
@Cacheable
|
||||
@EqualsAndHashCode
|
||||
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
|
||||
public class ACommand implements Serializable {
|
||||
@Id
|
||||
@@ -53,19 +53,4 @@ public class ACommand implements Serializable {
|
||||
this.updated = Instant.now();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
ACommand aCommand = (ACommand) o;
|
||||
return Objects.equals(id, aCommand.id) &&
|
||||
Objects.equals(name, aCommand.name) &&
|
||||
Objects.equals(module, aCommand.module) &&
|
||||
Objects.equals(feature, aCommand.feature);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(id, name, module, feature);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,6 @@ import org.hibernate.annotations.CacheConcurrencyStrategy;
|
||||
import javax.persistence.*;
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
@Entity(name = "command_in_server")
|
||||
@Getter
|
||||
@@ -16,6 +15,7 @@ import java.util.Objects;
|
||||
@Setter
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@EqualsAndHashCode
|
||||
@Cacheable
|
||||
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
|
||||
public class ACommandInAServer implements Serializable {
|
||||
@@ -49,23 +49,6 @@ public class ACommandInAServer implements Serializable {
|
||||
@Column
|
||||
private Boolean restricted;
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
ACommandInAServer that = (ACommandInAServer) o;
|
||||
return Objects.equals(commandInServerId, that.commandInServerId) &&
|
||||
Objects.equals(commandReference, that.commandReference) &&
|
||||
Objects.equals(serverReference, that.serverReference) &&
|
||||
Objects.equals(allowedRoles, that.allowedRoles) &&
|
||||
Objects.equals(immuneRoles, that.immuneRoles) &&
|
||||
Objects.equals(restricted, that.restricted);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(commandInServerId, commandReference, serverReference, allowedRoles, immuneRoles, restricted);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
package dev.sheldan.abstracto.core.command.models.database;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.*;
|
||||
import org.hibernate.annotations.CacheConcurrencyStrategy;
|
||||
|
||||
import javax.persistence.*;
|
||||
@@ -11,7 +8,6 @@ import java.io.Serializable;
|
||||
import java.time.Instant;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
@Entity
|
||||
@Table(name = "module")
|
||||
@@ -19,6 +15,7 @@ import java.util.Objects;
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Getter
|
||||
@EqualsAndHashCode
|
||||
@Cacheable
|
||||
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
|
||||
public class AModule implements Serializable {
|
||||
@@ -54,18 +51,4 @@ public class AModule implements Serializable {
|
||||
this.updated = Instant.now();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
AModule aModule = (AModule) o;
|
||||
return Objects.equals(id, aModule.id) &&
|
||||
Objects.equals(name, aModule.name) &&
|
||||
Objects.equals(commands, aModule.commands);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(id, name, commands);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,11 +2,15 @@ package dev.sheldan.abstracto.core.command.service;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.Command;
|
||||
import dev.sheldan.abstracto.core.command.condition.ConditionResult;
|
||||
import dev.sheldan.abstracto.core.command.config.Parameters;
|
||||
import dev.sheldan.abstracto.core.command.execution.CommandContext;
|
||||
import dev.sheldan.abstracto.core.command.models.database.ACommand;
|
||||
import dev.sheldan.abstracto.core.config.FeatureEnum;
|
||||
import dev.sheldan.abstracto.core.models.database.ARole;
|
||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||
import net.dv8tion.jda.api.entities.Message;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public interface CommandService {
|
||||
ACommand createCommand(String name, String moduleName, FeatureEnum featureEnum);
|
||||
@@ -21,4 +25,5 @@ public interface CommandService {
|
||||
void disAllowCommandForRole(ACommand aCommand, ARole role);
|
||||
void disAllowFeatureForRole(FeatureEnum featureEnum, ARole role);
|
||||
ConditionResult isCommandExecutable(Command command, CommandContext commandContext);
|
||||
CompletableFuture<Parameters> getParametersForCommand(String commandName, Message messageContainingContent);
|
||||
}
|
||||
|
||||
@@ -8,13 +8,13 @@ import javax.persistence.*;
|
||||
import java.io.Serializable;
|
||||
import java.time.Instant;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
@Entity
|
||||
@Table(name="channel")
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@EqualsAndHashCode
|
||||
@Cacheable
|
||||
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
|
||||
public class AChannel implements SnowFlake, Serializable {
|
||||
@@ -55,20 +55,5 @@ public class AChannel implements SnowFlake, Serializable {
|
||||
@Transient
|
||||
private boolean fake;
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
AChannel channel = (AChannel) o;
|
||||
return Objects.equals(id, channel.id) &&
|
||||
Objects.equals(groups, channel.groups) &&
|
||||
Objects.equals(server, channel.server) &&
|
||||
type == channel.type &&
|
||||
Objects.equals(deleted, channel.deleted);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(id, groups, server, type, deleted);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,6 @@ import javax.persistence.*;
|
||||
import java.io.Serializable;
|
||||
import java.time.Instant;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
@Entity
|
||||
@Table(name="channelGroup")
|
||||
@@ -15,6 +14,7 @@ import java.util.Objects;
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Getter
|
||||
@EqualsAndHashCode
|
||||
@Cacheable
|
||||
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
|
||||
public class AChannelGroup implements Serializable {
|
||||
@@ -49,19 +49,5 @@ public class AChannelGroup implements Serializable {
|
||||
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
|
||||
private List<AChannel> channels;
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
AChannelGroup that = (AChannelGroup) o;
|
||||
return Objects.equals(id, that.id) &&
|
||||
Objects.equals(groupName, that.groupName) &&
|
||||
Objects.equals(server, that.server) &&
|
||||
Objects.equals(channels, that.channels);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(id, groupName, server, channels);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@ import org.hibernate.annotations.CacheConcurrencyStrategy;
|
||||
|
||||
import javax.persistence.*;
|
||||
import java.io.Serializable;
|
||||
import java.util.Objects;
|
||||
|
||||
@Entity
|
||||
@Table(name = "channel_group_command")
|
||||
@@ -14,6 +13,7 @@ import java.util.Objects;
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Getter
|
||||
@EqualsAndHashCode
|
||||
@Cacheable
|
||||
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
|
||||
public class AChannelGroupCommand implements Serializable {
|
||||
@@ -35,19 +35,4 @@ public class AChannelGroupCommand implements Serializable {
|
||||
@Setter
|
||||
private Boolean enabled;
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
AChannelGroupCommand that = (AChannelGroupCommand) o;
|
||||
return Objects.equals(commandInGroupId, that.commandInGroupId) &&
|
||||
Objects.equals(command, that.command) &&
|
||||
Objects.equals(group, that.group) &&
|
||||
Objects.equals(enabled, that.enabled);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(commandInGroupId, command, group, enabled);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@ import org.hibernate.annotations.CacheConcurrencyStrategy;
|
||||
import javax.persistence.*;
|
||||
import java.io.Serializable;
|
||||
import java.time.Instant;
|
||||
import java.util.Objects;
|
||||
|
||||
@Entity
|
||||
@Table(name="systemConfig")
|
||||
@@ -14,6 +13,7 @@ import java.util.Objects;
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Getter
|
||||
@EqualsAndHashCode
|
||||
@Cacheable
|
||||
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
|
||||
public class AConfig implements Serializable {
|
||||
@@ -70,20 +70,5 @@ public class AConfig implements Serializable {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
AConfig config = (AConfig) o;
|
||||
return Objects.equals(id, config.id) &&
|
||||
Objects.equals(name, config.name) &&
|
||||
Objects.equals(stringValue, config.stringValue) &&
|
||||
Objects.equals(doubleValue, config.doubleValue) &&
|
||||
Objects.equals(server, config.server);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(id, name, stringValue, doubleValue, server);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package dev.sheldan.abstracto.core.models.database;
|
||||
|
||||
import lombok.*;
|
||||
import org.hibernate.annotations.CacheConcurrencyStrategy;
|
||||
|
||||
import javax.persistence.*;
|
||||
import java.io.Serializable;
|
||||
@@ -12,6 +13,9 @@ import java.time.Instant;
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Getter
|
||||
@EqualsAndHashCode
|
||||
@Cacheable
|
||||
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
|
||||
public class ADefaultConfig implements Serializable {
|
||||
@javax.persistence.Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
|
||||
@@ -6,7 +6,6 @@ import org.hibernate.annotations.CacheConcurrencyStrategy;
|
||||
import javax.persistence.*;
|
||||
import java.io.Serializable;
|
||||
import java.time.Instant;
|
||||
import java.util.Objects;
|
||||
|
||||
@Entity
|
||||
@Table(name = "emote")
|
||||
@@ -14,6 +13,7 @@ import java.util.Objects;
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Getter
|
||||
@EqualsAndHashCode
|
||||
@Cacheable
|
||||
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
|
||||
public class AEmote implements Serializable {
|
||||
@@ -71,22 +71,4 @@ public class AEmote implements Serializable {
|
||||
@Transient
|
||||
private boolean fake;
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
AEmote emote = (AEmote) o;
|
||||
return Objects.equals(id, emote.id) &&
|
||||
Objects.equals(name, emote.name) &&
|
||||
Objects.equals(emoteKey, emote.emoteKey) &&
|
||||
Objects.equals(emoteId, emote.emoteId) &&
|
||||
Objects.equals(animated, emote.animated) &&
|
||||
Objects.equals(custom, emote.custom) &&
|
||||
Objects.equals(serverRef, emote.serverRef);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(id, name, emoteKey, emoteId, animated, custom, serverRef);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,13 +9,13 @@ import javax.persistence.*;
|
||||
import java.io.Serializable;
|
||||
import java.time.Instant;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
@Entity
|
||||
@Table(name="feature")
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@EqualsAndHashCode
|
||||
@Cacheable
|
||||
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
|
||||
public class AFeature implements SnowFlake, Serializable {
|
||||
@@ -52,18 +52,5 @@ public class AFeature implements SnowFlake, Serializable {
|
||||
this.updated = Instant.now();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
AFeature feature = (AFeature) o;
|
||||
return Objects.equals(id, feature.id) &&
|
||||
Objects.equals(key, feature.key) &&
|
||||
Objects.equals(commands, feature.commands);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(id, key, commands);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,13 +7,13 @@ import javax.persistence.*;
|
||||
import java.io.Serializable;
|
||||
import java.time.Instant;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
@Entity
|
||||
@Table(name="feature_flag")
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@EqualsAndHashCode
|
||||
@Cacheable
|
||||
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
|
||||
public class AFeatureFlag implements Serializable {
|
||||
@@ -62,19 +62,5 @@ public class AFeatureFlag implements Serializable {
|
||||
this.updateTimestamp = Instant.now();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
AFeatureFlag that = (AFeatureFlag) o;
|
||||
return enabled == that.enabled &&
|
||||
Objects.equals(id, that.id) &&
|
||||
Objects.equals(server, that.server) &&
|
||||
Objects.equals(feature, that.feature);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(id, server, feature, enabled);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ import java.time.Instant;
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@EqualsAndHashCode
|
||||
@Cacheable
|
||||
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
|
||||
public class AFeatureMode implements Serializable {
|
||||
|
||||
@@ -7,13 +7,13 @@ import org.hibernate.annotations.CacheConcurrencyStrategy;
|
||||
import javax.persistence.*;
|
||||
import java.io.Serializable;
|
||||
import java.time.Instant;
|
||||
import java.util.Objects;
|
||||
|
||||
@Entity
|
||||
@Table(name="role")
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@EqualsAndHashCode
|
||||
@Cacheable
|
||||
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
|
||||
public class ARole implements SnowFlake, Serializable {
|
||||
@@ -52,21 +52,6 @@ public class ARole implements SnowFlake, Serializable {
|
||||
this.updated = Instant.now();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
ARole role = (ARole) o;
|
||||
return Objects.equals(id, role.id) &&
|
||||
Objects.equals(server, role.server) &&
|
||||
Objects.equals(deleted, role.deleted);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(id, server, deleted);
|
||||
}
|
||||
|
||||
public String getAsMention() {
|
||||
return "<@&" + getId() + '>';
|
||||
}
|
||||
|
||||
@@ -9,7 +9,6 @@ import java.io.Serializable;
|
||||
import java.time.Instant;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
@Entity
|
||||
@Table(name = "server")
|
||||
@@ -17,6 +16,7 @@ import java.util.Objects;
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Getter
|
||||
@EqualsAndHashCode
|
||||
@Cacheable
|
||||
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
|
||||
public class AServer implements SnowFlake, Serializable {
|
||||
@@ -89,16 +89,4 @@ public class AServer implements SnowFlake, Serializable {
|
||||
private List<AEmote> emotes = new ArrayList<>();
|
||||
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
AServer aServer = (AServer) o;
|
||||
return Objects.equals(id, aServer.id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(id);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,6 @@ import javax.persistence.*;
|
||||
import java.io.Serializable;
|
||||
import java.time.Instant;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
@Entity
|
||||
@Table(name="auser")
|
||||
@@ -15,6 +14,7 @@ import java.util.Objects;
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Getter
|
||||
@EqualsAndHashCode
|
||||
@Cacheable
|
||||
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
|
||||
public class AUser implements Serializable {
|
||||
@@ -45,17 +45,4 @@ public class AUser implements Serializable {
|
||||
this.updated = Instant.now();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
AUser user = (AUser) o;
|
||||
return Objects.equals(id, user.id) &&
|
||||
Objects.equals(servers, user.servers);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(id, servers);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@ import org.hibernate.annotations.CacheConcurrencyStrategy;
|
||||
import javax.persistence.*;
|
||||
import java.io.Serializable;
|
||||
import java.time.Instant;
|
||||
import java.util.Objects;
|
||||
|
||||
@Entity
|
||||
@Table(name = "user_in_server")
|
||||
@@ -15,6 +14,7 @@ import java.util.Objects;
|
||||
@Setter
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@EqualsAndHashCode
|
||||
@Cacheable
|
||||
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
|
||||
public class AUserInAServer implements Serializable {
|
||||
@@ -47,18 +47,4 @@ public class AUserInAServer implements Serializable {
|
||||
this.updated = Instant.now();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
AUserInAServer that = (AUserInAServer) o;
|
||||
return Objects.equals(userInServerId, that.userInServerId) &&
|
||||
Objects.equals(userReference, that.userReference) &&
|
||||
Objects.equals(serverReference, that.serverReference);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(userInServerId, userReference, serverReference);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import lombok.*;
|
||||
import org.hibernate.annotations.CacheConcurrencyStrategy;
|
||||
|
||||
import javax.persistence.*;
|
||||
import java.io.Serializable;
|
||||
|
||||
@Entity
|
||||
@Table(name = "counter")
|
||||
@@ -13,9 +14,10 @@ import javax.persistence.*;
|
||||
@Setter
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@EqualsAndHashCode
|
||||
@Cacheable
|
||||
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
|
||||
public class Counter {
|
||||
public class Counter implements Serializable {
|
||||
|
||||
@EmbeddedId
|
||||
private CounterId counterId;
|
||||
|
||||
@@ -6,7 +6,6 @@ import org.hibernate.annotations.CacheConcurrencyStrategy;
|
||||
import javax.persistence.*;
|
||||
import java.io.Serializable;
|
||||
import java.time.Instant;
|
||||
import java.util.Objects;
|
||||
|
||||
@Entity
|
||||
@Table(name = "default_emote")
|
||||
@@ -14,6 +13,7 @@ import java.util.Objects;
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Getter
|
||||
@EqualsAndHashCode
|
||||
@Cacheable
|
||||
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
|
||||
public class DefaultEmote implements Serializable {
|
||||
@@ -45,20 +45,5 @@ public class DefaultEmote implements Serializable {
|
||||
this.updated = Instant.now();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
DefaultEmote that = (DefaultEmote) o;
|
||||
return Objects.equals(id, that.id) &&
|
||||
Objects.equals(name, that.name) &&
|
||||
Objects.equals(emoteKey, that.emoteKey) &&
|
||||
Objects.equals(created, that.created) &&
|
||||
Objects.equals(updated, that.updated);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(id, name, emoteKey, created, updated);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,13 +6,13 @@ import org.hibernate.annotations.CacheConcurrencyStrategy;
|
||||
import javax.persistence.*;
|
||||
import java.io.Serializable;
|
||||
import java.time.Instant;
|
||||
import java.util.Objects;
|
||||
|
||||
@Entity
|
||||
@Table(name="default_feature_flag")
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@EqualsAndHashCode
|
||||
@Cacheable
|
||||
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
|
||||
public class DefaultFeatureFlag implements Serializable {
|
||||
@@ -53,21 +53,5 @@ public class DefaultFeatureFlag implements Serializable {
|
||||
this.updateTimestamp = Instant.now();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
DefaultFeatureFlag that = (DefaultFeatureFlag) o;
|
||||
return enabled == that.enabled &&
|
||||
Objects.equals(id, that.id) &&
|
||||
Objects.equals(feature, that.feature) &&
|
||||
Objects.equals(mode, that.mode) &&
|
||||
Objects.equals(created, that.created) &&
|
||||
Objects.equals(updateTimestamp, that.updateTimestamp);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(id, feature, enabled, mode, created, updateTimestamp);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,8 +13,8 @@ import java.util.List;
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Cacheable
|
||||
@EqualsAndHashCode
|
||||
@Cacheable
|
||||
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
|
||||
public class DefaultFeatureMode implements Serializable {
|
||||
|
||||
|
||||
@@ -6,13 +6,13 @@ import org.hibernate.annotations.CacheConcurrencyStrategy;
|
||||
import javax.persistence.*;
|
||||
import java.io.Serializable;
|
||||
import java.time.Instant;
|
||||
import java.util.Objects;
|
||||
|
||||
@Entity
|
||||
@Table(name="default_posttarget")
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@EqualsAndHashCode
|
||||
@Cacheable
|
||||
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
|
||||
public class DefaultPostTarget implements Serializable {
|
||||
|
||||
@@ -6,13 +6,13 @@ import org.hibernate.annotations.CacheConcurrencyStrategy;
|
||||
import javax.persistence.*;
|
||||
import java.io.Serializable;
|
||||
import java.time.Instant;
|
||||
import java.util.Objects;
|
||||
|
||||
@Entity
|
||||
@Table(name="posttarget")
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@EqualsAndHashCode
|
||||
@Cacheable
|
||||
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
|
||||
public class PostTarget implements Serializable {
|
||||
@@ -51,19 +51,5 @@ public class PostTarget implements Serializable {
|
||||
this.updated = Instant.now();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
PostTarget that = (PostTarget) o;
|
||||
return Objects.equals(id, that.id) &&
|
||||
Objects.equals(name, that.name) &&
|
||||
Objects.equals(channelReference, that.channelReference) &&
|
||||
Objects.equals(serverReference, that.serverReference);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(id, name, channelReference, serverReference);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,10 +3,7 @@ package dev.sheldan.abstracto.core.service;
|
||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||
import dev.sheldan.abstracto.templating.model.MessageToSend;
|
||||
import dev.sheldan.abstracto.core.models.database.AChannel;
|
||||
import net.dv8tion.jda.api.entities.Message;
|
||||
import net.dv8tion.jda.api.entities.MessageChannel;
|
||||
import net.dv8tion.jda.api.entities.MessageEmbed;
|
||||
import net.dv8tion.jda.api.entities.TextChannel;
|
||||
import net.dv8tion.jda.api.entities.*;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
@@ -39,5 +39,8 @@ public interface MessageService {
|
||||
CompletableFuture<Message> sendTemplateToUser(User user, String template, Object model);
|
||||
CompletableFuture<Void> sendEmbedToUser(User user, String template, Object model);
|
||||
CompletableFuture<Message> sendEmbedToUserWithMessage(User user, String template, Object model);
|
||||
CompletableFuture<Message> sendMessageToSendToUser(User user, MessageToSend messageToSend);
|
||||
CompletableFuture<Message> sendMessageToUser(User user, String text);
|
||||
CompletableFuture<Void> deleteMessageInChannelWithUser(User user, Long messageId);
|
||||
CompletableFuture<Void> editMessageInDMChannel(User user, MessageToSend messageToSend, Long messageId);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
=== Mod mail
|
||||
|
||||
This feature enables users to contact the moderation of the server in a private manner. This can be initiated by messaging the Abstracto bot.
|
||||
The messages, in the channel which is created to contain the mod mail thread, are not automatically sent to the user, but only when using the commands
|
||||
`reply` or `anonReply`. Any other message is ignored with the intention of enabling discussions within the channel. In case the message of a message sent to the user
|
||||
needs to be updated or deleted, you can do simply by editing/deleting the message containing the command.
|
||||
|
||||
Feature key: `modmail`
|
||||
|
||||
@@ -27,6 +30,8 @@ Feature key: `modmail`
|
||||
|
||||
==== Feature modes
|
||||
`log`:: If this is enabled, the messages should be logged into the `modmailLog` post target when the thread is closed (by the respective commands). This is required for the command `closeNoLog` to be available. Enabled by default.
|
||||
`threadMessage`:: if this is enabled, every message which is send via the commands `reply` and `anonReply` will also be sent to the thread in order to have a visualizer how the message looks
|
||||
and to have a clear indication which messages were sent. Enabled by default.
|
||||
|
||||
|
||||
==== Emotes
|
||||
|
||||
@@ -2,9 +2,10 @@ package dev.sheldan.abstracto.scheduling.model.database;
|
||||
|
||||
|
||||
import lombok.*;
|
||||
import org.hibernate.annotations.CacheConcurrencyStrategy;
|
||||
|
||||
import javax.persistence.*;
|
||||
import java.util.Objects;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* The scheduler job instance according to the properties stored in the database. This is needed in order to have a
|
||||
@@ -17,7 +18,10 @@ import java.util.Objects;
|
||||
@Table(name = "scheduler_job")
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class SchedulerJob {
|
||||
@EqualsAndHashCode
|
||||
@Cacheable
|
||||
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
|
||||
public class SchedulerJob implements Serializable {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
@@ -53,22 +57,4 @@ public class SchedulerJob {
|
||||
*/
|
||||
private boolean recovery;
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
SchedulerJob that = (SchedulerJob) o;
|
||||
return active == that.active &&
|
||||
recovery == that.recovery &&
|
||||
Objects.equals(id, that.id) &&
|
||||
Objects.equals(name, that.name) &&
|
||||
Objects.equals(groupName, that.groupName) &&
|
||||
Objects.equals(clazz, that.clazz) &&
|
||||
Objects.equals(cronExpression, that.cronExpression);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(id, name, groupName, clazz, cronExpression, active, recovery);
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,7 @@
|
||||
package dev.sheldan.abstracto.templating.model.database;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.*;
|
||||
import org.hibernate.annotations.CacheConcurrencyStrategy;
|
||||
|
||||
import javax.persistence.*;
|
||||
|
||||
@@ -13,6 +11,9 @@ import javax.persistence.*;
|
||||
@AllArgsConstructor
|
||||
@Table(name = "auto_load_macro")
|
||||
@Getter
|
||||
@EqualsAndHashCode
|
||||
@Cacheable
|
||||
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
|
||||
public class AutoLoadMacro {
|
||||
|
||||
@Id
|
||||
|
||||
@@ -1,14 +1,11 @@
|
||||
package dev.sheldan.abstracto.templating.model.database;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.*;
|
||||
import org.hibernate.annotations.CacheConcurrencyStrategy;
|
||||
|
||||
import javax.persistence.*;
|
||||
import java.io.Serializable;
|
||||
import java.time.Instant;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Represents the template stored in the database.
|
||||
@@ -18,9 +15,10 @@ import java.util.Objects;
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Table(name = "template")
|
||||
@EqualsAndHashCode
|
||||
@Cacheable
|
||||
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
|
||||
public class Template {
|
||||
public class Template implements Serializable {
|
||||
|
||||
/**
|
||||
* The globally unique key of the template
|
||||
@@ -64,19 +62,4 @@ public class Template {
|
||||
this.updated = Instant.now();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
Template template = (Template) o;
|
||||
return Objects.equals(key, template.key) &&
|
||||
Objects.equals(content, template.content) &&
|
||||
Objects.equals(section, template.section) &&
|
||||
Objects.equals(lastModified, template.lastModified);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(key, content, section, lastModified);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user