mirror of
https://github.com/Sheldan/abstracto.git
synced 2026-03-05 16:01:49 +00:00
[AB-xxx] reworking mute logging to use audit log events instead of active logging and member update events
This commit is contained in:
@@ -1,139 +0,0 @@
|
||||
package dev.sheldan.abstracto.moderation.listener;
|
||||
|
||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.listener.DefaultListenerResult;
|
||||
import dev.sheldan.abstracto.core.listener.async.jda.AsyncMemberTimeoutUpdatedListener;
|
||||
import dev.sheldan.abstracto.core.models.ServerUser;
|
||||
import dev.sheldan.abstracto.core.models.listener.MemberTimeoutUpdatedModel;
|
||||
import dev.sheldan.abstracto.core.models.template.display.MemberDisplay;
|
||||
import dev.sheldan.abstracto.core.service.MemberService;
|
||||
import dev.sheldan.abstracto.core.service.PostTargetService;
|
||||
import dev.sheldan.abstracto.core.templating.model.MessageToSend;
|
||||
import dev.sheldan.abstracto.core.templating.service.TemplateService;
|
||||
import dev.sheldan.abstracto.core.utils.FutureUtils;
|
||||
import dev.sheldan.abstracto.moderation.config.feature.ModerationFeatureDefinition;
|
||||
import dev.sheldan.abstracto.moderation.config.posttarget.MutingPostTarget;
|
||||
import dev.sheldan.abstracto.moderation.model.template.command.MuteListenerModel;
|
||||
import dev.sheldan.abstracto.moderation.service.MuteServiceBean;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.audit.ActionType;
|
||||
import net.dv8tion.jda.api.audit.AuditLogEntry;
|
||||
import net.dv8tion.jda.api.audit.AuditLogKey;
|
||||
import net.dv8tion.jda.api.entities.Guild;
|
||||
import net.dv8tion.jda.api.entities.Member;
|
||||
import net.dv8tion.jda.api.entities.User;
|
||||
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 MemberTimeoutListener implements AsyncMemberTimeoutUpdatedListener {
|
||||
|
||||
@Autowired
|
||||
private TemplateService templateService;
|
||||
|
||||
@Autowired
|
||||
private PostTargetService postTargetService;
|
||||
|
||||
@Autowired
|
||||
private MemberTimeoutListener self;
|
||||
|
||||
@Autowired
|
||||
private MemberService memberService;
|
||||
|
||||
@Override
|
||||
public DefaultListenerResult execute(MemberTimeoutUpdatedModel model) {
|
||||
Guild guild = model.getGuild();
|
||||
guild.retrieveAuditLogs()
|
||||
.type(ActionType.MEMBER_UPDATE)
|
||||
.limit(10)
|
||||
.queue(auditLogEntries -> {
|
||||
CompletableFuture<Void> notificationFuture = null;
|
||||
if(auditLogEntries.isEmpty()) {
|
||||
log.info("Did not find recent timeouts in guild {}.", model.getServerId());
|
||||
notificationFuture = self.sendMutingUpdateNotification(model, null);
|
||||
} else {
|
||||
Optional<AuditLogEntry> timeoutEntryOptional = auditLogEntries
|
||||
.stream()
|
||||
.filter(auditLogEntry -> auditLogEntry.getChangeByKey(AuditLogKey.MEMBER_TIME_OUT) != null
|
||||
&& auditLogEntry.getTargetIdLong() == model.getTimeoutUser().getUserId())
|
||||
.findFirst();
|
||||
if(timeoutEntryOptional.isPresent()) {
|
||||
AuditLogEntry auditLogEntry = timeoutEntryOptional.get();
|
||||
User responsibleUser = auditLogEntry.getUser();
|
||||
if(guild.getSelfMember().getIdLong() != responsibleUser.getIdLong()) {
|
||||
notificationFuture = self.sendMutingUpdateNotification(model, auditLogEntry);
|
||||
}
|
||||
} else {
|
||||
notificationFuture = self.sendMutingUpdateNotification(model, null);
|
||||
}
|
||||
}
|
||||
if(notificationFuture != null) {
|
||||
notificationFuture.thenAccept(unused -> {
|
||||
log.info("Sent notification about timeout change {} -> {} of user {} in server {}.",
|
||||
model.getOldTimeout(), model.getNewTimeout(), model.getTimeoutUser().getUserId(), model.getServerId());
|
||||
}).exceptionally(throwable -> {
|
||||
log.info("Sent notification about timeout change {} -> {} of user {} in server {}.",
|
||||
model.getOldTimeout(), model.getNewTimeout(), model.getTimeoutUser().getUserId(), model.getServerId());
|
||||
return null;
|
||||
});
|
||||
}
|
||||
});
|
||||
return DefaultListenerResult.PROCESSED;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public CompletableFuture<Void> sendMutingUpdateNotification(MemberTimeoutUpdatedModel model, AuditLogEntry logEntry) {
|
||||
User responsibleUser;
|
||||
Guild guild = model.getGuild();
|
||||
CompletableFuture<Member> future;
|
||||
String reason;
|
||||
if(logEntry != null) {
|
||||
responsibleUser = logEntry.getUser();
|
||||
if(responsibleUser != null) {
|
||||
ServerUser responsibleServerUser = ServerUser
|
||||
.builder()
|
||||
.serverId(guild.getIdLong())
|
||||
.isBot(responsibleUser.isBot())
|
||||
.userId(responsibleUser.getIdLong())
|
||||
.build();
|
||||
future = memberService.retrieveMemberInServer(responsibleServerUser);
|
||||
} else {
|
||||
future = CompletableFuture.completedFuture(null);
|
||||
}
|
||||
reason = logEntry.getReason();
|
||||
} else {
|
||||
future = CompletableFuture.completedFuture(null);
|
||||
reason = null;
|
||||
}
|
||||
CompletableFuture<Void> returningFuture = new CompletableFuture<>();
|
||||
future.whenComplete((aVoid, throwable) -> {
|
||||
try {
|
||||
MuteListenerModel muteLogModel = MuteListenerModel
|
||||
.builder()
|
||||
.muteTargetDate(model.getNewTimeout() != null ? model.getNewTimeout().toInstant() : null)
|
||||
.oldMuteTargetDate(model.getOldTimeout() != null ? model.getOldTimeout().toInstant() : null)
|
||||
.mutingUser(future.isCompletedExceptionally() ? null : MemberDisplay.fromMember(future.join()))
|
||||
.mutedUser(MemberDisplay.fromMember(model.getMember()))
|
||||
.reason(reason)
|
||||
.build();
|
||||
MessageToSend message = templateService.renderEmbedTemplate(MuteServiceBean.MUTE_LOG_TEMPLATE, muteLogModel, guild.getIdLong());
|
||||
FutureUtils.toSingleFutureGeneric(postTargetService.sendEmbedInPostTarget(message, MutingPostTarget.MUTE_LOG, model.getServerId()));
|
||||
returningFuture.complete(null);
|
||||
} catch (Exception exception) {
|
||||
log.error("Failed to log timeout update event for user {} in guild {}.", model.getTimeoutUser().getUserId(), model.getServerId(), exception);
|
||||
}
|
||||
});
|
||||
|
||||
return returningFuture;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FeatureDefinition getFeature() {
|
||||
return ModerationFeatureDefinition.MUTING;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
package dev.sheldan.abstracto.moderation.listener;
|
||||
|
||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.listener.DefaultListenerResult;
|
||||
import dev.sheldan.abstracto.core.listener.async.jda.AsyncMemberTimeoutUpdatedListener;
|
||||
import dev.sheldan.abstracto.core.models.listener.MemberTimeoutUpdatedModel;
|
||||
import dev.sheldan.abstracto.core.models.template.display.MemberDisplay;
|
||||
import dev.sheldan.abstracto.core.service.PostTargetService;
|
||||
import dev.sheldan.abstracto.core.templating.model.MessageToSend;
|
||||
import dev.sheldan.abstracto.core.templating.service.TemplateService;
|
||||
import dev.sheldan.abstracto.core.utils.FutureUtils;
|
||||
import dev.sheldan.abstracto.moderation.config.feature.ModerationFeatureDefinition;
|
||||
import dev.sheldan.abstracto.moderation.config.posttarget.MutingPostTarget;
|
||||
import dev.sheldan.abstracto.moderation.model.template.command.MuteListenerModel;
|
||||
import dev.sheldan.abstracto.moderation.service.MuteServiceBean;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.entities.Guild;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class MemberTimeoutLoggerListener implements AsyncMemberTimeoutUpdatedListener {
|
||||
|
||||
@Autowired
|
||||
private TemplateService templateService;
|
||||
|
||||
@Autowired
|
||||
private PostTargetService postTargetService;
|
||||
|
||||
@Override
|
||||
public DefaultListenerResult execute(MemberTimeoutUpdatedModel model) {
|
||||
Guild guild = model.getGuild();
|
||||
MemberDisplay memberDisplay = model.getMember() != null ? MemberDisplay.fromMember(model.getMember()) : MemberDisplay.fromServerUser(model.getTimeoutUser());
|
||||
Duration duration = null;
|
||||
if(model.getNewTimeout() != null) {
|
||||
duration = Duration.between(Instant.now(), model.getNewTimeout());
|
||||
}
|
||||
MuteListenerModel muteLogModel = MuteListenerModel
|
||||
.builder()
|
||||
.muteTargetDate(model.getNewTimeout() != null ? model.getNewTimeout().toInstant() : null)
|
||||
.oldMuteTargetDate(model.getOldTimeout() != null ? model.getOldTimeout().toInstant() : null)
|
||||
.mutingUser(MemberDisplay.fromIds(model.getServerId(), model.getResponsibleUserId()))
|
||||
.mutedUser(memberDisplay)
|
||||
.duration(duration)
|
||||
.reason(model.getReason())
|
||||
.build();
|
||||
MessageToSend message = templateService.renderEmbedTemplate(MuteServiceBean.MUTE_LOG_TEMPLATE, muteLogModel, guild.getIdLong());
|
||||
FutureUtils.toSingleFutureGeneric(postTargetService.sendEmbedInPostTarget(message, MutingPostTarget.MUTE_LOG, model.getServerId()));
|
||||
return DefaultListenerResult.PROCESSED;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FeatureDefinition getFeature() {
|
||||
return ModerationFeatureDefinition.MUTING;
|
||||
}
|
||||
}
|
||||
@@ -6,30 +6,23 @@ import dev.sheldan.abstracto.core.models.ServerUser;
|
||||
import dev.sheldan.abstracto.core.models.database.AChannel;
|
||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||
import dev.sheldan.abstracto.core.models.template.display.MemberDisplay;
|
||||
import dev.sheldan.abstracto.core.service.*;
|
||||
import dev.sheldan.abstracto.core.service.management.ChannelManagementService;
|
||||
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
|
||||
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
|
||||
import dev.sheldan.abstracto.core.templating.model.MessageToSend;
|
||||
import dev.sheldan.abstracto.core.templating.service.TemplateService;
|
||||
import dev.sheldan.abstracto.core.utils.FutureUtils;
|
||||
import dev.sheldan.abstracto.moderation.config.feature.ModerationFeatureDefinition;
|
||||
import dev.sheldan.abstracto.moderation.config.feature.MutingFeatureConfig;
|
||||
import dev.sheldan.abstracto.moderation.config.posttarget.MutingPostTarget;
|
||||
import dev.sheldan.abstracto.moderation.exception.NoMuteFoundException;
|
||||
import dev.sheldan.abstracto.moderation.model.MuteResult;
|
||||
import dev.sheldan.abstracto.moderation.model.database.Infraction;
|
||||
import dev.sheldan.abstracto.moderation.model.database.Mute;
|
||||
import dev.sheldan.abstracto.moderation.model.template.command.MuteListenerModel;
|
||||
import dev.sheldan.abstracto.moderation.model.template.command.MuteNotification;
|
||||
import dev.sheldan.abstracto.moderation.model.template.command.UnMuteLog;
|
||||
import dev.sheldan.abstracto.moderation.service.management.MuteManagementService;
|
||||
import dev.sheldan.abstracto.scheduling.model.JobParameters;
|
||||
import dev.sheldan.abstracto.scheduling.service.SchedulerService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.entities.Guild;
|
||||
import net.dv8tion.jda.api.entities.Message;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.stereotype.Component;
|
||||
@@ -175,14 +168,13 @@ public class MuteServiceBean implements MuteService {
|
||||
Long muteId = counterService.getNextCounterValue(server, MUTE_COUNTER_KEY);
|
||||
CompletableFuture<MuteResult> result = muteUserInServer(guild, userToMute, reason, duration);
|
||||
return result
|
||||
.thenCompose(unused -> self.sendMuteLog(userToMute, mutingUser, duration, reason))
|
||||
.thenCompose(logMessage -> self.evaluateAndStoreInfraction(userToMute, mutingUser, reason, targetDate, logMessage))
|
||||
.thenCompose(logMessage -> self.evaluateAndStoreInfraction(userToMute, mutingUser, reason, targetDate))
|
||||
.thenAccept(infractionId -> self.persistMute(userToMute, mutingUser, targetDate, muteId, reason, infractionId, origin))
|
||||
.thenApply(unused -> result.join());
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public CompletableFuture<Long> evaluateAndStoreInfraction(ServerUser userToMute, ServerUser mutingUser, String reason, Instant targetDate, Message logMessage) {
|
||||
public CompletableFuture<Long> evaluateAndStoreInfraction(ServerUser userToMute, ServerUser mutingUser, String reason, Instant targetDate) {
|
||||
Long serverId = userToMute.getServerId();
|
||||
if(featureFlagService.getFeatureFlagValue(ModerationFeatureDefinition.INFRACTIONS, serverId)) {
|
||||
Long infractionPoints = configService.getLongValueOrConfigDefault(MutingFeatureConfig.MUTE_INFRACTION_POINTS, serverId);
|
||||
@@ -190,7 +182,7 @@ public class MuteServiceBean implements MuteService {
|
||||
AUserInAServer mutingUserInAServer = userInServerManagementService.loadOrCreateUser(mutingUser);
|
||||
Map<String, String> parameters = new HashMap<>();
|
||||
parameters.put(INFRACTION_PARAMETER_DURATION_KEY, templateService.renderDuration(Duration.between(Instant.now(), targetDate), serverId));
|
||||
return infractionService.createInfractionWithNotification(mutedUserInAServer, infractionPoints, MUTE_INFRACTION_TYPE, reason, mutingUserInAServer, parameters, logMessage)
|
||||
return infractionService.createInfractionWithNotification(mutedUserInAServer, infractionPoints, MUTE_INFRACTION_TYPE, reason, mutingUserInAServer, parameters)
|
||||
.thenApply(Infraction::getId);
|
||||
} else {
|
||||
return CompletableFuture.completedFuture(null);
|
||||
@@ -204,48 +196,13 @@ public class MuteServiceBean implements MuteService {
|
||||
createMuteObject(userToMute, mutingUser, reason, targetDate, muteId, triggerKey, infractionId, origin);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public CompletableFuture<Message> sendMuteLog(ServerUser userBeingMuted, ServerUser mutingUser, Duration duration, String reason) {
|
||||
Instant targetDate = Instant.now().plus(duration);
|
||||
MuteListenerModel model = MuteListenerModel
|
||||
.builder()
|
||||
.mutedUser(MemberDisplay.fromServerUser(userBeingMuted))
|
||||
.mutingUser(MemberDisplay.fromServerUser(mutingUser))
|
||||
.oldMuteTargetDate(null)
|
||||
.duration(duration)
|
||||
.muteTargetDate(targetDate)
|
||||
.reason(reason)
|
||||
.build();
|
||||
log.debug("Sending mute log to the mute post target.");
|
||||
Long serverId = userBeingMuted.getServerId();
|
||||
MessageToSend message = templateService.renderEmbedTemplate(MUTE_LOG_TEMPLATE, model, serverId);
|
||||
List<CompletableFuture<Message>> futures = postTargetService.sendEmbedInPostTarget(message, MutingPostTarget.MUTE_LOG, serverId);
|
||||
return FutureUtils.toSingleFutureGeneric(futures).thenApply(unused -> futures.get(0).join());
|
||||
}
|
||||
|
||||
private CompletableFuture<Void> sendUnMuteLogMessage(UnMuteLog muteLogModel, AServer server) {
|
||||
MuteListenerModel model = MuteListenerModel
|
||||
.builder()
|
||||
.mutedUser(muteLogModel.getUnMutedUser())
|
||||
.mutingUser(muteLogModel.getMutingUser())
|
||||
.oldMuteTargetDate(muteLogModel.getMute() != null ? muteLogModel.getMute().getMuteTargetDate() : null)
|
||||
.muteTargetDate(null)
|
||||
.build();
|
||||
if(muteLogModel.getMute() != null) {
|
||||
log.debug("Sending unMute log for mute {} to the mute posttarget in server {}", muteLogModel.getMute().getMuteId().getId(), server.getId());
|
||||
}
|
||||
MessageToSend message = templateService.renderEmbedTemplate(MUTE_LOG_TEMPLATE, model, server.getId());
|
||||
return FutureUtils.toSingleFutureGeneric(postTargetService.sendEmbedInPostTarget(message, MutingPostTarget.MUTE_LOG, server.getId()));
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public CompletableFuture<Void> unMuteUser(ServerUser userToUnmute, ServerUser unMutingUser, Guild guild) {
|
||||
AUserInAServer aUserInAServer = userInServerManagementService.loadOrCreateUser(userToUnmute);
|
||||
boolean muteActive = muteManagementService.hasActiveMute(aUserInAServer);
|
||||
if(!muteActive) {
|
||||
return memberService.removeTimeout(guild, userToUnmute, null)
|
||||
.thenCompose(unused -> self.sendUnmuteLog(null, guild, userToUnmute, unMutingUser));
|
||||
return memberService.removeTimeout(guild, userToUnmute, null);
|
||||
} else {
|
||||
Mute mute = muteManagementService.getAMuteOf(aUserInAServer);
|
||||
return endMute(mute, guild);
|
||||
@@ -261,32 +218,13 @@ public class MuteServiceBean implements MuteService {
|
||||
Long muteId = mute.getMuteId().getId();
|
||||
AServer mutingServer = mute.getServer();
|
||||
ServerUser mutedUser = ServerUser.fromAUserInAServer(mute.getMutedUser());
|
||||
ServerUser mutingUser = ServerUser.fromAUserInAServer(mute.getMutingUser());
|
||||
log.info("UnMuting {} in server {}", mute.getMutedUser().getUserReference().getId(), mutingServer.getId());
|
||||
return memberService.removeTimeout(guild, mutedUser, null)
|
||||
.thenCompose(unused -> self.sendUnmuteLog(muteId, guild, mutedUser, mutingUser));
|
||||
}
|
||||
|
||||
|
||||
@Transactional
|
||||
public CompletableFuture<Void> sendUnmuteLog(Long muteId, Guild guild, ServerUser unMutedMember, ServerUser mutingMember) {
|
||||
Mute mute = null;
|
||||
if(muteId != null) {
|
||||
mute = muteManagementService.findMute(muteId, guild.getIdLong());
|
||||
}
|
||||
AServer mutingServer = serverManagementService.loadServer(guild.getIdLong());
|
||||
UnMuteLog unMuteLog = UnMuteLog
|
||||
.builder()
|
||||
.mute(mute)
|
||||
.mutingUser(MemberDisplay.fromServerUser(mutingMember))
|
||||
.unMutedUser(MemberDisplay.fromServerUser(unMutedMember))
|
||||
.build();
|
||||
CompletableFuture<Void> notificationFuture = sendUnMuteLogMessage(unMuteLog, mutingServer);
|
||||
return CompletableFuture.allOf(notificationFuture).thenAccept(aVoid -> {
|
||||
if(muteId != null) {
|
||||
self.endMuteInDatabase(muteId, guild.getIdLong());
|
||||
}
|
||||
});
|
||||
.thenAccept(unused -> {
|
||||
if(muteId != null) {
|
||||
self.endMuteInDatabase(muteId, guild.getIdLong());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Transactional
|
||||
|
||||
@@ -1,71 +0,0 @@
|
||||
package dev.sheldan.abstracto.moderation.model.template.command;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.template.display.MemberDisplay;
|
||||
import dev.sheldan.abstracto.core.utils.MessageUtils;
|
||||
import dev.sheldan.abstracto.moderation.model.database.Mute;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
import lombok.experimental.SuperBuilder;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
|
||||
/**
|
||||
* Used when rendering the notification when a member was muted. The template is: "unmute_log_embed"
|
||||
*/
|
||||
@Getter
|
||||
@SuperBuilder
|
||||
@Setter
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class UnMuteLog {
|
||||
/**
|
||||
* The un-muted Member, is null if the member left the server
|
||||
*/
|
||||
private MemberDisplay unMutedUser;
|
||||
/**
|
||||
* The user casting the mute, is null if the member left the server
|
||||
*/
|
||||
private MemberDisplay mutingUser;
|
||||
/**
|
||||
* The persisted mute object from the database containing the information about the mute
|
||||
*/
|
||||
private Mute mute;
|
||||
|
||||
/**
|
||||
* The actual duration between the date the mute started and the current time
|
||||
* @return The difference between mute start and now
|
||||
*/
|
||||
public Duration getMuteDuration() {
|
||||
return Duration.between(mute.getMuteDate(), Instant.now());
|
||||
}
|
||||
|
||||
/**
|
||||
* The duration between the date the mute started and the un-mute planned
|
||||
* @return The difference between mute start and the target date
|
||||
*/
|
||||
public Duration getPlannedMuteDuration() {
|
||||
return Duration.between(mute.getMuteDate(), mute.getMuteTargetDate());
|
||||
}
|
||||
|
||||
/**
|
||||
* The un-mute date, which is now, because this is the un-mute log message.
|
||||
* @return The current time stamp
|
||||
*/
|
||||
public Instant getUnmuteDate() {
|
||||
return Instant.now();
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the link to the original message triggering the mute
|
||||
* @return A string containing an URL leading to the message where the mute was triggered
|
||||
*/
|
||||
public String getMessageUrl() {
|
||||
if(this.mute.getMessageId() != null && this.mute.getMutingChannel() != null) {
|
||||
return MessageUtils.buildMessageUrl(this.mute.getServer().getId(), this.mute.getMutingChannel().getId(), this.mute.getMessageId());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -3,8 +3,13 @@ package dev.sheldan.abstracto.core.listener.async.jda;
|
||||
import dev.sheldan.abstracto.core.listener.ListenerService;
|
||||
import dev.sheldan.abstracto.core.models.ServerUser;
|
||||
import dev.sheldan.abstracto.core.models.listener.MemberTimeoutUpdatedModel;
|
||||
import dev.sheldan.abstracto.core.service.MemberService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.events.guild.member.update.GuildMemberUpdateTimeOutEvent;
|
||||
import net.dv8tion.jda.api.audit.ActionType;
|
||||
import net.dv8tion.jda.api.audit.AuditLogChange;
|
||||
import net.dv8tion.jda.api.audit.AuditLogKey;
|
||||
import net.dv8tion.jda.api.entities.Member;
|
||||
import net.dv8tion.jda.api.events.guild.GuildAuditLogEntryCreateEvent;
|
||||
import net.dv8tion.jda.api.hooks.ListenerAdapter;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
@@ -12,7 +17,10 @@ import org.springframework.core.task.TaskExecutor;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.time.OffsetDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
@@ -27,23 +35,46 @@ public class AsyncMemberTimeoutListenerBean extends ListenerAdapter {
|
||||
@Autowired
|
||||
private ListenerService listenerService;
|
||||
|
||||
@Autowired
|
||||
private MemberService memberService;
|
||||
|
||||
@Override
|
||||
public void onGuildMemberUpdateTimeOut(@Nonnull GuildMemberUpdateTimeOutEvent event) {
|
||||
public void onGuildAuditLogEntryCreate(@Nonnull GuildAuditLogEntryCreateEvent event) {
|
||||
if(listenerList == null) return;
|
||||
MemberTimeoutUpdatedModel model = getModel(event);
|
||||
listenerList.forEach(leaveListener -> listenerService.executeFeatureAwareListener(leaveListener, model, memberTimeoutExecutor));
|
||||
if(event.getEntry().getType().equals(ActionType.MEMBER_UPDATE)) {
|
||||
AuditLogChange memberTimeoutChange = event.getEntry().getChangeByKey(AuditLogKey.MEMBER_TIME_OUT);
|
||||
if(memberTimeoutChange != null) {
|
||||
CompletableFuture<Member> memberInstanceFuture = memberService.retrieveMemberInServer(ServerUser.fromId(event.getGuild().getIdLong(), event.getEntry().getTargetIdLong()));
|
||||
memberInstanceFuture.whenComplete((member, throwable) -> {
|
||||
executeListeners(memberTimeoutChange, event, member);
|
||||
}).exceptionally(throwable -> {
|
||||
Long memberId = event.getEntry().getTargetIdLong();
|
||||
Long serverId = event.getGuild().getIdLong();
|
||||
log.warn("Failed to load member {} for member update audit log in server {}.", memberId, serverId, throwable);
|
||||
executeListeners(memberTimeoutChange, event, null);
|
||||
return null;
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private MemberTimeoutUpdatedModel getModel(GuildMemberUpdateTimeOutEvent event) {
|
||||
return MemberTimeoutUpdatedModel
|
||||
.builder()
|
||||
.oldTimeout(event.getOldTimeOutEnd())
|
||||
.newTimeout(event.getNewTimeOutEnd())
|
||||
.member(event.getMember())
|
||||
.event(event)
|
||||
.timeoutUser(ServerUser.fromMember(event.getMember()))
|
||||
.guild(event.getGuild())
|
||||
.user(event.getUser())
|
||||
.build();
|
||||
}
|
||||
private void executeListeners(AuditLogChange change, GuildAuditLogEntryCreateEvent event, Member member) {
|
||||
DateTimeFormatter timeFormatter = DateTimeFormatter.ISO_DATE_TIME;
|
||||
OffsetDateTime timeoutAfter = change.getNewValue() != null ? OffsetDateTime.parse(change.getNewValue(), timeFormatter) : null;
|
||||
OffsetDateTime timeoutBefore = change.getOldValue() != null ? OffsetDateTime.parse(change.getOldValue(), timeFormatter) : null;
|
||||
String reason = event.getEntry().getReason();
|
||||
MemberTimeoutUpdatedModel model = MemberTimeoutUpdatedModel
|
||||
.builder()
|
||||
.oldTimeout(timeoutBefore)
|
||||
.newTimeout(timeoutAfter)
|
||||
.responsibleUserId(event.getEntry().getUserIdLong())
|
||||
.member(member)
|
||||
.reason(reason)
|
||||
.guild(event.getGuild())
|
||||
.user(member != null ? member.getUser() : null)
|
||||
.timeoutUser(ServerUser.fromId(event.getGuild().getIdLong(), event.getEntry().getTargetIdLong()))
|
||||
.build();
|
||||
listenerList.forEach(leaveListener -> listenerService.executeFeatureAwareListener(leaveListener, model, memberTimeoutExecutor));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,6 @@ import lombok.Setter;
|
||||
import net.dv8tion.jda.api.entities.Guild;
|
||||
import net.dv8tion.jda.api.entities.Member;
|
||||
import net.dv8tion.jda.api.entities.User;
|
||||
import net.dv8tion.jda.api.events.guild.member.update.GuildMemberUpdateTimeOutEvent;
|
||||
|
||||
import java.time.OffsetDateTime;
|
||||
|
||||
@@ -19,10 +18,11 @@ public class MemberTimeoutUpdatedModel implements FeatureAwareListenerModel {
|
||||
private ServerUser timeoutUser;
|
||||
private User user;
|
||||
private Guild guild;
|
||||
private String reason;
|
||||
private Long responsibleUserId;
|
||||
private OffsetDateTime oldTimeout;
|
||||
private OffsetDateTime newTimeout;
|
||||
private Member member;
|
||||
private GuildMemberUpdateTimeOutEvent event;
|
||||
@Override
|
||||
public Long getServerId() {
|
||||
return guild.getIdLong();
|
||||
|
||||
Reference in New Issue
Block a user