mirror of
https://github.com/Sheldan/abstracto.git
synced 2026-01-19 22:43:31 +00:00
[AB-264] fixing profanity filter not considering message edits
This commit is contained in:
@@ -1,107 +0,0 @@
|
||||
package dev.sheldan.abstracto.profanityfilter.listener;
|
||||
|
||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.listener.DefaultListenerResult;
|
||||
import dev.sheldan.abstracto.core.listener.async.jda.AsyncMessageReceivedListener;
|
||||
import dev.sheldan.abstracto.core.metric.service.CounterMetric;
|
||||
import dev.sheldan.abstracto.core.metric.service.MetricService;
|
||||
import dev.sheldan.abstracto.core.metric.service.MetricTag;
|
||||
import dev.sheldan.abstracto.core.models.database.ProfanityRegex;
|
||||
import dev.sheldan.abstracto.core.models.listener.MessageReceivedModel;
|
||||
import dev.sheldan.abstracto.core.service.FeatureModeService;
|
||||
import dev.sheldan.abstracto.core.service.MessageService;
|
||||
import dev.sheldan.abstracto.core.service.ProfanityService;
|
||||
import dev.sheldan.abstracto.core.service.RoleImmunityService;
|
||||
import dev.sheldan.abstracto.profanityfilter.config.ProfanityFilterFeatureDefinition;
|
||||
import dev.sheldan.abstracto.profanityfilter.config.ProfanityFilterMode;
|
||||
import dev.sheldan.abstracto.profanityfilter.service.ProfanityFilterService;
|
||||
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 javax.annotation.PostConstruct;
|
||||
import java.util.Arrays;
|
||||
import java.util.Optional;
|
||||
|
||||
import static dev.sheldan.abstracto.profanityfilter.service.ProfanityFilterService.PROFANITY_FILTER_EFFECT_KEY;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class ProfanityDetectionListener implements AsyncMessageReceivedListener {
|
||||
|
||||
@Autowired
|
||||
private ProfanityService profanityService;
|
||||
|
||||
@Autowired
|
||||
private ProfanityFilterService profanityFilterService;
|
||||
|
||||
@Autowired
|
||||
private FeatureModeService featureModeService;
|
||||
|
||||
@Autowired
|
||||
private MessageService messageService;
|
||||
|
||||
@Autowired
|
||||
private MetricService metricService;
|
||||
|
||||
@Autowired
|
||||
private RoleImmunityService roleImmunityService;
|
||||
|
||||
public static final String MODERATION_PURGE_METRIC = "profanity.filter";
|
||||
public static final String STEP = "step";
|
||||
|
||||
private static final CounterMetric PROFANITIES_DETECTED_METRIC =
|
||||
CounterMetric
|
||||
.builder()
|
||||
.tagList(Arrays.asList(MetricTag.getTag(STEP, "detection")))
|
||||
.name(MODERATION_PURGE_METRIC)
|
||||
.build();
|
||||
|
||||
@Override
|
||||
public DefaultListenerResult execute(MessageReceivedModel model) {
|
||||
Message message = model.getMessage();
|
||||
if(message.isWebhookMessage() || message.getType().isSystem() || !message.isFromGuild()) {
|
||||
return DefaultListenerResult.IGNORED;
|
||||
}
|
||||
|
||||
if(roleImmunityService.isImmune(message.getMember(), PROFANITY_FILTER_EFFECT_KEY)) {
|
||||
log.info("Not checking for profanities in message, because author {} in channel {} in guild {} is immune against profanity filter.",
|
||||
message.getMember().getIdLong(), message.getGuild().getIdLong(), message.getChannel().getIdLong());
|
||||
return DefaultListenerResult.IGNORED;
|
||||
}
|
||||
|
||||
Long serverId = model.getServerId();
|
||||
Optional<ProfanityRegex> potentialProfanityGroup = profanityService.getProfanityRegex(message.getContentRaw(), serverId);
|
||||
if(potentialProfanityGroup.isPresent()) {
|
||||
metricService.incrementCounter(PROFANITIES_DETECTED_METRIC);
|
||||
if(featureModeService.featureModeActive(ProfanityFilterFeatureDefinition.PROFANITY_FILTER, serverId, ProfanityFilterMode.PROFANITY_REPORT)) {
|
||||
ProfanityRegex foundProfanityGroup = potentialProfanityGroup.get();
|
||||
profanityFilterService.createProfanityReport(message, foundProfanityGroup).exceptionally(throwable -> {
|
||||
log.error("Failed to report or persist profanities in server {} for message {} in channel {}.",
|
||||
serverId, message.getChannel().getIdLong(), message.getIdLong(), throwable);
|
||||
return null;
|
||||
});
|
||||
}
|
||||
if(featureModeService.featureModeActive(ProfanityFilterFeatureDefinition.PROFANITY_FILTER, serverId, ProfanityFilterMode.AUTO_DELETE_PROFANITIES)) {
|
||||
messageService.deleteMessage(message).exceptionally(throwable -> {
|
||||
log.error("Failed to delete profanity message with id {} in channel {} in server {}.",
|
||||
message.getIdLong(), message.getChannel().getIdLong(), message.getGuild().getIdLong(), throwable);
|
||||
return null;
|
||||
});
|
||||
}
|
||||
return DefaultListenerResult.PROCESSED;
|
||||
}
|
||||
return DefaultListenerResult.IGNORED;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FeatureDefinition getFeature() {
|
||||
return ProfanityFilterFeatureDefinition.PROFANITY_FILTER;
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
public void postConstruct() {
|
||||
metricService.registerCounter(PROFANITIES_DETECTED_METRIC, "Amount of profanities detected");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
package dev.sheldan.abstracto.profanityfilter.listener;
|
||||
|
||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.listener.DefaultListenerResult;
|
||||
import dev.sheldan.abstracto.core.listener.async.jda.AsyncMessageReceivedListener;
|
||||
import dev.sheldan.abstracto.core.models.database.ProfanityRegex;
|
||||
import dev.sheldan.abstracto.core.models.listener.MessageReceivedModel;
|
||||
import dev.sheldan.abstracto.core.service.ProfanityService;
|
||||
import dev.sheldan.abstracto.profanityfilter.config.ProfanityFilterFeatureDefinition;
|
||||
import dev.sheldan.abstracto.profanityfilter.service.ProfanityFilterService;
|
||||
import dev.sheldan.abstracto.profanityfilter.service.ProfanityFilterServiceBean;
|
||||
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.Optional;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class ProfanityMessageReceivedListener implements AsyncMessageReceivedListener {
|
||||
|
||||
@Autowired
|
||||
private ProfanityService profanityService;
|
||||
|
||||
@Autowired
|
||||
private ProfanityFilterService profanityFilterService;
|
||||
|
||||
@Autowired
|
||||
private ProfanityFilterServiceBean profanityFilterServiceBean;
|
||||
|
||||
@Override
|
||||
public DefaultListenerResult execute(MessageReceivedModel model) {
|
||||
Message message = model.getMessage();
|
||||
if(message.isWebhookMessage() || message.getType().isSystem() || !message.isFromGuild()) {
|
||||
return DefaultListenerResult.IGNORED;
|
||||
}
|
||||
|
||||
if(profanityFilterService.isImmuneAgainstProfanityFilter(message.getMember())) {
|
||||
log.debug("Not checking for profanities in message, because author {} in channel {} in guild {} is immune against profanity filter.",
|
||||
message.getMember().getIdLong(), message.getGuild().getIdLong(), message.getChannel().getIdLong());
|
||||
return DefaultListenerResult.IGNORED;
|
||||
}
|
||||
|
||||
Long serverId = model.getServerId();
|
||||
Optional<ProfanityRegex> potentialProfanityGroup = profanityService.getProfanityRegex(message.getContentRaw(), serverId);
|
||||
if(potentialProfanityGroup.isPresent()) {
|
||||
ProfanityRegex foundProfanityGroup = potentialProfanityGroup.get();
|
||||
profanityFilterServiceBean.handleProfaneMessage(message, foundProfanityGroup);
|
||||
return DefaultListenerResult.PROCESSED;
|
||||
}
|
||||
return DefaultListenerResult.IGNORED;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FeatureDefinition getFeature() {
|
||||
return ProfanityFilterFeatureDefinition.PROFANITY_FILTER;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
package dev.sheldan.abstracto.profanityfilter.listener;
|
||||
|
||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.listener.DefaultListenerResult;
|
||||
import dev.sheldan.abstracto.core.listener.async.jda.AsyncMessageUpdatedListener;
|
||||
import dev.sheldan.abstracto.core.models.database.ProfanityRegex;
|
||||
import dev.sheldan.abstracto.core.models.listener.MessageUpdatedModel;
|
||||
import dev.sheldan.abstracto.core.service.ProfanityService;
|
||||
import dev.sheldan.abstracto.profanityfilter.config.ProfanityFilterFeatureDefinition;
|
||||
import dev.sheldan.abstracto.profanityfilter.service.ProfanityFilterService;
|
||||
import dev.sheldan.abstracto.profanityfilter.service.ProfanityFilterServiceBean;
|
||||
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.Optional;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class ProfanityMessageUpdatedListener implements AsyncMessageUpdatedListener {
|
||||
|
||||
@Autowired
|
||||
private ProfanityService profanityService;
|
||||
|
||||
@Autowired
|
||||
private ProfanityFilterService profanityFilterService;
|
||||
|
||||
@Autowired
|
||||
private ProfanityFilterServiceBean profanityFilterServiceBean;
|
||||
|
||||
@Override
|
||||
public DefaultListenerResult execute(MessageUpdatedModel model) {
|
||||
Message message = model.getAfter();
|
||||
if(message.isWebhookMessage() || message.getType().isSystem() || !message.isFromGuild()) {
|
||||
return DefaultListenerResult.IGNORED;
|
||||
}
|
||||
|
||||
if(profanityFilterService.isImmuneAgainstProfanityFilter(message.getMember())) {
|
||||
log.debug("Not checking for profanities in message, because author {} in channel {} in guild {} is immune against profanity filter.",
|
||||
message.getMember().getIdLong(), message.getGuild().getIdLong(), message.getChannel().getIdLong());
|
||||
return DefaultListenerResult.IGNORED;
|
||||
}
|
||||
|
||||
Long serverId = model.getServerId();
|
||||
Optional<ProfanityRegex> potentialProfanityGroup = profanityService.getProfanityRegex(message.getContentRaw(), serverId);
|
||||
if(potentialProfanityGroup.isPresent()) {
|
||||
ProfanityRegex foundProfanityGroup = potentialProfanityGroup.get();
|
||||
profanityFilterServiceBean.handleProfaneMessage(message, foundProfanityGroup);
|
||||
return DefaultListenerResult.PROCESSED;
|
||||
}
|
||||
return DefaultListenerResult.IGNORED;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FeatureDefinition getFeature() {
|
||||
return ProfanityFilterFeatureDefinition.PROFANITY_FILTER;
|
||||
}
|
||||
}
|
||||
@@ -6,10 +6,7 @@ import dev.sheldan.abstracto.core.metric.service.MetricTag;
|
||||
import dev.sheldan.abstracto.core.models.ServerChannelMessage;
|
||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||
import dev.sheldan.abstracto.core.models.database.ProfanityRegex;
|
||||
import dev.sheldan.abstracto.core.service.FeatureModeService;
|
||||
import dev.sheldan.abstracto.core.service.MessageService;
|
||||
import dev.sheldan.abstracto.core.service.PostTargetService;
|
||||
import dev.sheldan.abstracto.core.service.ReactionService;
|
||||
import dev.sheldan.abstracto.core.service.*;
|
||||
import dev.sheldan.abstracto.core.service.management.ProfanityRegexManagementService;
|
||||
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
|
||||
import dev.sheldan.abstracto.core.templating.model.MessageToSend;
|
||||
@@ -18,13 +15,13 @@ import dev.sheldan.abstracto.core.utils.FutureUtils;
|
||||
import dev.sheldan.abstracto.profanityfilter.config.ProfanityFilterFeatureDefinition;
|
||||
import dev.sheldan.abstracto.profanityfilter.config.ProfanityFilterMode;
|
||||
import dev.sheldan.abstracto.profanityfilter.config.ProfanityFilterPostTarget;
|
||||
import dev.sheldan.abstracto.profanityfilter.listener.ProfanityDetectionListener;
|
||||
import dev.sheldan.abstracto.profanityfilter.model.database.ProfanityUse;
|
||||
import dev.sheldan.abstracto.profanityfilter.model.database.ProfanityUserInAServer;
|
||||
import dev.sheldan.abstracto.profanityfilter.model.template.ProfanityReportModel;
|
||||
import dev.sheldan.abstracto.profanityfilter.service.management.ProfanityUseManagementService;
|
||||
import dev.sheldan.abstracto.profanityfilter.service.management.ProfanityUserInServerManagementService;
|
||||
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;
|
||||
@@ -70,23 +67,37 @@ public class ProfanityFilterServiceBean implements ProfanityFilterService {
|
||||
@Autowired
|
||||
private MetricService metricService;
|
||||
|
||||
@Autowired
|
||||
private RoleImmunityService roleImmunityService;
|
||||
|
||||
@Autowired
|
||||
private ProfanityFilterServiceBean self;
|
||||
|
||||
private static final String PROFANITY_REPORT_TEMPLATE_KEY = "profanityDetection_listener_report";
|
||||
|
||||
public static final String MODERATION_PURGE_METRIC = "profanity.filter";
|
||||
public static final String STEP = "step";
|
||||
|
||||
private static final CounterMetric PROFANITIES_DETECTED_METRIC =
|
||||
CounterMetric
|
||||
.builder()
|
||||
.tagList(Arrays.asList(MetricTag.getTag(STEP, "detection")))
|
||||
.name(MODERATION_PURGE_METRIC)
|
||||
.build();
|
||||
|
||||
|
||||
private static final CounterMetric PROFANITIES_AGREEMENT =
|
||||
CounterMetric
|
||||
.builder()
|
||||
.tagList(Arrays.asList(MetricTag.getTag(ProfanityDetectionListener.STEP, "agreement")))
|
||||
.name(ProfanityDetectionListener.MODERATION_PURGE_METRIC)
|
||||
.tagList(Arrays.asList(MetricTag.getTag(STEP, "agreement")))
|
||||
.name(MODERATION_PURGE_METRIC)
|
||||
.build();
|
||||
|
||||
private static final CounterMetric PROFANITIES_DISAGREEMENT =
|
||||
CounterMetric
|
||||
.builder()
|
||||
.tagList(Arrays.asList(MetricTag.getTag(ProfanityDetectionListener.STEP, "disagreement")))
|
||||
.name(ProfanityDetectionListener.MODERATION_PURGE_METRIC)
|
||||
.tagList(Arrays.asList(MetricTag.getTag(STEP, "disagreement")))
|
||||
.name(MODERATION_PURGE_METRIC)
|
||||
.build();
|
||||
|
||||
@Override
|
||||
@@ -202,9 +213,33 @@ public class ProfanityFilterServiceBean implements ProfanityFilterService {
|
||||
profanityUseManagementService.createProfanityUse(profaneMessageObj, reportMessageObj, profaneUser, profanityRegex.getGroup());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isImmuneAgainstProfanityFilter(Member member) {
|
||||
return roleImmunityService.isImmune(member, PROFANITY_FILTER_EFFECT_KEY);
|
||||
}
|
||||
|
||||
public void handleProfaneMessage(Message message, ProfanityRegex foundProfanityGroup) {
|
||||
metricService.incrementCounter(PROFANITIES_DETECTED_METRIC);
|
||||
if(featureModeService.featureModeActive(ProfanityFilterFeatureDefinition.PROFANITY_FILTER, message.getGuild().getIdLong(), ProfanityFilterMode.PROFANITY_REPORT)) {
|
||||
createProfanityReport(message, foundProfanityGroup).exceptionally(throwable -> {
|
||||
log.error("Failed to report or persist profanities in server {} for message {} in channel {}.",
|
||||
message.getGuild().getIdLong(), message.getChannel().getIdLong(), message.getIdLong(), throwable);
|
||||
return null;
|
||||
});
|
||||
}
|
||||
if(featureModeService.featureModeActive(ProfanityFilterFeatureDefinition.PROFANITY_FILTER, message.getGuild().getIdLong(), ProfanityFilterMode.AUTO_DELETE_PROFANITIES)) {
|
||||
messageService.deleteMessage(message).exceptionally(throwable -> {
|
||||
log.error("Failed to delete profanity message with id {} in channel {} in server {}.",
|
||||
message.getIdLong(), message.getChannel().getIdLong(), message.getGuild().getIdLong(), throwable);
|
||||
return null;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
public void postConstruct() {
|
||||
metricService.registerCounter(PROFANITIES_AGREEMENT, "Amount of profanity votes resulting in agreement");
|
||||
metricService.registerCounter(PROFANITIES_DISAGREEMENT, "Amount of profanity votes resulting in disagreement");
|
||||
metricService.registerCounter(PROFANITIES_DETECTED_METRIC, "Amount of profanities detected");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||
import dev.sheldan.abstracto.core.models.database.ProfanityRegex;
|
||||
import dev.sheldan.abstracto.profanityfilter.model.database.ProfanityUse;
|
||||
import dev.sheldan.abstracto.profanityfilter.model.database.ProfanityUserInAServer;
|
||||
import net.dv8tion.jda.api.entities.Member;
|
||||
import net.dv8tion.jda.api.entities.Message;
|
||||
|
||||
import java.util.List;
|
||||
@@ -15,14 +16,7 @@ public interface ProfanityFilterService {
|
||||
String PROFANITY_VOTES_CONFIG_KEY = "profanityVotes";
|
||||
String REPORT_DISAGREE_EMOTE = "profanityFilterDisagreeEmote";
|
||||
String PROFANITY_FILTER_EFFECT_KEY = "profanityFilter";
|
||||
|
||||
enum VoteResult {
|
||||
AGREEMENT, DISAGREEMENT, BELOW_THRESHOLD;
|
||||
public static boolean isFinal(VoteResult result) {
|
||||
return result.equals(AGREEMENT) || result.equals(DISAGREEMENT);
|
||||
}
|
||||
}
|
||||
|
||||
boolean isImmuneAgainstProfanityFilter(Member member);
|
||||
CompletableFuture<Void> createProfanityReport(Message message, ProfanityRegex profanityRegex);
|
||||
boolean isMessageProfanityReport(Long messageId);
|
||||
void verifyProfanityUse(ProfanityUse profanityUse, VoteResult result);
|
||||
@@ -32,4 +26,11 @@ public interface ProfanityFilterService {
|
||||
Long getFalseProfanityReportCountForUser(ProfanityUserInAServer aUserInAServer);
|
||||
List<ServerChannelMessage> getRecentPositiveReports(AUserInAServer aUserInAServer, int count);
|
||||
List<ServerChannelMessage> getRecentPositiveReports(ProfanityUserInAServer aUserInAServer, int count);
|
||||
|
||||
enum VoteResult {
|
||||
AGREEMENT, DISAGREEMENT, BELOW_THRESHOLD;
|
||||
public static boolean isFinal(VoteResult result) {
|
||||
return result.equals(AGREEMENT) || result.equals(DISAGREEMENT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user