Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package net.discordjug.javabot.systems.moderation;

import java.time.Duration;
import java.time.ZonedDateTime;
import java.util.concurrent.ExecutorService;

import lombok.RequiredArgsConstructor;
import net.discordjug.javabot.data.config.BotConfig;
import net.discordjug.javabot.systems.moderation.warn.dao.WarnRepository;
import net.discordjug.javabot.systems.notification.NotificationService;
import net.dv8tion.jda.api.audit.AuditLogChange;
import net.dv8tion.jda.api.audit.AuditLogEntry;
import net.dv8tion.jda.api.events.guild.GuildAuditLogEntryCreateEvent;
import net.dv8tion.jda.api.hooks.ListenerAdapter;

/**
* Logs moderative actions that did not use bot commands.
*/
@RequiredArgsConstructor
public class DiscordModerationLogListener extends ListenerAdapter{

private final NotificationService notificationService;
private final BotConfig botConfig;
private final WarnRepository warnRepository;
private final ExecutorService asyncPool;

@Override
public void onGuildAuditLogEntryCreate(GuildAuditLogEntryCreateEvent event) {

ModerationService moderationService = new ModerationService(notificationService, botConfig.get(event.getGuild()), warnRepository, asyncPool);

AuditLogEntry entry = event.getEntry();
long targetUserId = entry.getTargetIdLong();
long moderatorUserId = entry.getUserIdLong();
if (moderatorUserId == event.getJDA().getSelfUser().getIdLong()) {
return;
}
event.getJDA().retrieveUserById(targetUserId).queue(targetUser -> {
event.getGuild().retrieveMemberById(moderatorUserId).queue(moderator -> {
String reason = entry.getReason();
if (reason == null) {
reason = "<no reason provided>";
}
switch(entry.getType()) {
case KICK -> moderationService.sendKickGuildNotification(targetUser, reason, moderator);
case BAN -> moderationService.sendBanGuildNotification(targetUser, reason, moderator);
case UNBAN -> moderationService.sendUnbanGuildNotification(targetUser, reason, moderator);
case MEMBER_UPDATE -> {
if (entry.getChanges().containsKey("communication_disabled_until")) {
AuditLogChange change = entry.getChangeByKey("communication_disabled_until");
if (change.getNewValue()!=null) {
ZonedDateTime timeoutRemovalTimestamp = java.time.ZonedDateTime.parse(change.getNewValue());
moderationService.sendTimeoutGuildNotification(targetUser, reason, moderator, Duration.between(ZonedDateTime.now(), timeoutRemovalTimestamp));
}else {
moderationService.sendRemoveTimeoutGuildNotification(targetUser, reason, moderator);
}
}
}
default -> {}
}
});
});

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ public void timeout(@Nonnull User user, @Nonnull String reason, @Nonnull Member
* @param quiet If true, don't send a message in the channel.
*/
public void removeTimeout(Member member, String reason, Member removedBy, MessageChannel channel, boolean quiet) {
MessageEmbed removeTimeoutEmbed = buildTimeoutRemovedEmbed(member, removedBy, reason);
MessageEmbed removeTimeoutEmbed = buildTimeoutRemovedEmbed(member.getUser(), removedBy, reason);
removedBy.getGuild().removeTimeout(member).queue(s -> {
notificationService.withUser(member.getUser(), removedBy.getGuild()).sendDirectMessage(c -> c.sendMessageEmbeds(removeTimeoutEmbed));
notificationService.withGuild(member.getGuild()).sendToModerationLog(c -> c.sendMessageEmbeds(removeTimeoutEmbed));
Expand Down Expand Up @@ -291,6 +291,35 @@ public void kick(User user, String reason, Member kickedBy, MessageChannel chann
}, ExceptionLogger::capture);
}

public void sendKickGuildNotification(User user, String reason, Member moderator) {
sendGuildNotification(moderator.getGuild(), buildKickEmbed(user, moderator, reason));
}

public void sendBanGuildNotification(User user, String reason, Member moderator) {
sendGuildNotification(moderator.getGuild(), buildBanEmbed(user, moderator, reason));
}

public void sendUnbanGuildNotification(User user, String reason, Member moderator) {
sendGuildNotification(moderator.getGuild(), buildUnbanEmbed(user.getIdLong(), reason, moderator));
}

public void sendTimeoutGuildNotification(User user, String reason, Member moderator, Duration duration) {
sendGuildNotification(moderator.getGuild(), buildTimeoutEmbed(user, moderator, reason, duration));
}

public void sendRemoveTimeoutGuildNotification(User user, String reason, Member moderator) {
sendGuildNotification(moderator.getGuild(), buildTimeoutRemovedEmbed(user, moderator, reason));
}

private void sendGuildNotification(Guild guild, MessageEmbed embed) {
MessageEmbed newEmbed = new EmbedBuilder(embed)
.addField("Source", "This action was executed manually without a bot command.", false)
.build();
notificationService
.withGuild(guild)
.sendToModerationLog(c -> c.sendMessageEmbeds(newEmbed));
}

private @NotNull EmbedBuilder buildModerationEmbed(@NotNull User user, @NotNull Member moderator, String reason) {
return new EmbedBuilder()
.setAuthor(UserUtils.getUserTag(moderator.getUser()), null, moderator.getEffectiveAvatarUrl())
Expand Down Expand Up @@ -372,8 +401,8 @@ public void kick(User user, String reason, Member kickedBy, MessageChannel chann
.build();
}

private @NotNull MessageEmbed buildTimeoutRemovedEmbed(@NotNull Member member, Member timedOutBy, String reason) {
return buildModerationEmbed(member.getUser(), timedOutBy, reason)
private @NotNull MessageEmbed buildTimeoutRemovedEmbed(@NotNull User user, Member timedOutBy, String reason) {
return buildModerationEmbed(user, timedOutBy, reason)
.setTitle("Timeout Removed")
.setColor(Responses.Type.SUCCESS.getColor())
.build();
Expand Down