mirror of
https://github.com/Sheldan/abstracto.git
synced 2026-03-21 04:48:44 +00:00
Compare commits
2 Commits
feature/us
...
release-20
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
58632bcf9d | ||
|
|
592ac01bfa |
2
.env
2
.env
@@ -1,2 +1,2 @@
|
|||||||
REGISTRY_PREFIX=harbor.sheldan.dev/abstracto/
|
REGISTRY_PREFIX=harbor.sheldan.dev/abstracto/
|
||||||
VERSION=1.5.60
|
VERSION=1.6.0
|
||||||
1
.github/workflows/release_manual.yml
vendored
1
.github/workflows/release_manual.yml
vendored
@@ -39,6 +39,7 @@ jobs:
|
|||||||
git-release-bot-name: "release-bot"
|
git-release-bot-name: "release-bot"
|
||||||
git-release-bot-email: "release-bot@sheldan.dev"
|
git-release-bot-email: "release-bot@sheldan.dev"
|
||||||
release-branch-name: master
|
release-branch-name: master
|
||||||
|
version-minor: true
|
||||||
maven-args: "-Dmaven.javadoc.skip=true -s settings.xml -DskipTests"
|
maven-args: "-Dmaven.javadoc.skip=true -s settings.xml -DskipTests"
|
||||||
access-token: ${{ secrets.GITHUB_TOKEN }}
|
access-token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
- name: Install node dependencies and build
|
- name: Install node dependencies and build
|
||||||
|
|||||||
@@ -1,66 +0,0 @@
|
|||||||
package dev.sheldan.abstracto.repostdetection.listener;
|
|
||||||
|
|
||||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
|
||||||
import dev.sheldan.abstracto.core.listener.DefaultListenerResult;
|
|
||||||
import dev.sheldan.abstracto.core.listener.async.jda.AsyncMessageEmbeddedListener;
|
|
||||||
import dev.sheldan.abstracto.core.models.database.AChannel;
|
|
||||||
import dev.sheldan.abstracto.core.models.listener.GuildMessageEmbedEventModel;
|
|
||||||
import dev.sheldan.abstracto.core.service.ChannelService;
|
|
||||||
import dev.sheldan.abstracto.core.service.management.ChannelManagementService;
|
|
||||||
import dev.sheldan.abstracto.repostdetection.config.RepostDetectionFeatureDefinition;
|
|
||||||
import dev.sheldan.abstracto.repostdetection.service.RepostCheckChannelService;
|
|
||||||
import dev.sheldan.abstracto.repostdetection.service.RepostService;
|
|
||||||
import dev.sheldan.abstracto.repostdetection.service.management.PostedImageManagement;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import net.dv8tion.jda.api.entities.EmbedType;
|
|
||||||
import net.dv8tion.jda.api.entities.MessageEmbed;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
@Component
|
|
||||||
@Slf4j
|
|
||||||
public class RepostEmbedListener implements AsyncMessageEmbeddedListener {
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private RepostCheckChannelService repostCheckChannelService;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private RepostService repostService;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private PostedImageManagement repostManagement;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private ChannelManagementService channelManagementService;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private ChannelService channelService;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public DefaultListenerResult execute(GuildMessageEmbedEventModel eventModel) {
|
|
||||||
AChannel channel = channelManagementService.loadChannel(eventModel.getChannelId());
|
|
||||||
if(repostCheckChannelService.duplicateCheckEnabledForChannel(channel)) {
|
|
||||||
if(repostManagement.messageEmbedsHaveBeenCovered(eventModel.getMessageId())) {
|
|
||||||
log.info("The embeds of the message {} in channel {} in server {} have already been covered by repost check -- ignoring.",
|
|
||||||
eventModel.getMessageId(), eventModel.getChannelId(), eventModel.getServerId());
|
|
||||||
return DefaultListenerResult.IGNORED;
|
|
||||||
}
|
|
||||||
channelService.retrieveMessageInChannel(eventModel.getServerId(), eventModel.getChannelId(), eventModel.getMessageId()).thenAccept(message -> {
|
|
||||||
List<MessageEmbed> imageEmbeds = eventModel.getEmbeds().stream().filter(messageEmbed -> messageEmbed.getType().equals(EmbedType.IMAGE)).collect(Collectors.toList());
|
|
||||||
if(!imageEmbeds.isEmpty()) {
|
|
||||||
repostService.processMessageEmbedsRepostCheck(imageEmbeds, message);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return DefaultListenerResult.PROCESSED;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public FeatureDefinition getFeature() {
|
|
||||||
return RepostDetectionFeatureDefinition.REPOST_DETECTION;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,137 +0,0 @@
|
|||||||
package dev.sheldan.abstracto.repostdetection.listener;
|
|
||||||
|
|
||||||
import dev.sheldan.abstracto.core.models.database.AChannel;
|
|
||||||
import dev.sheldan.abstracto.core.models.listener.GuildMessageEmbedEventModel;
|
|
||||||
import dev.sheldan.abstracto.core.service.ChannelService;
|
|
||||||
import dev.sheldan.abstracto.core.service.management.ChannelManagementService;
|
|
||||||
import dev.sheldan.abstracto.repostdetection.service.RepostCheckChannelService;
|
|
||||||
import dev.sheldan.abstracto.repostdetection.service.RepostService;
|
|
||||||
import dev.sheldan.abstracto.repostdetection.service.management.PostedImageManagement;
|
|
||||||
import net.dv8tion.jda.api.entities.EmbedType;
|
|
||||||
import net.dv8tion.jda.api.entities.Message;
|
|
||||||
import net.dv8tion.jda.api.entities.MessageEmbed;
|
|
||||||
import net.dv8tion.jda.api.entities.channel.concrete.TextChannel;
|
|
||||||
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.List;
|
|
||||||
import java.util.concurrent.CompletableFuture;
|
|
||||||
|
|
||||||
import static org.mockito.Mockito.*;
|
|
||||||
|
|
||||||
@RunWith(MockitoJUnitRunner.class)
|
|
||||||
public class RepostEmbedListenerTest {
|
|
||||||
|
|
||||||
@InjectMocks
|
|
||||||
private RepostEmbedListener testUnit;
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private RepostCheckChannelService repostCheckChannelService;
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private RepostService repostService;
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private PostedImageManagement repostManagement;
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private ChannelManagementService channelManagementService;
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private ChannelService channelService;
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private GuildMessageEmbedEventModel model;
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private TextChannel textChannel;
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private Message message;
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private AChannel channel;
|
|
||||||
|
|
||||||
@Captor
|
|
||||||
private ArgumentCaptor<List<MessageEmbed>> embedListsParameterCaptor;
|
|
||||||
|
|
||||||
private static final Long MESSAGE_ID = 1L;
|
|
||||||
private static final Long CHANNEL_ID = 2L;
|
|
||||||
private static final Long SERVER_ID = 3L;
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testExecuteCheckDisabled() {
|
|
||||||
when(model.getChannelId()).thenReturn(CHANNEL_ID);
|
|
||||||
testUnit.execute(model);
|
|
||||||
verify(repostManagement, times(0)).messageEmbedsHaveBeenCovered(anyLong());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testExecuteEmbedsHaveBeenCovered() {
|
|
||||||
channelSetup();
|
|
||||||
setupMessageHasBeenCovered(true);
|
|
||||||
testUnit.execute(model);
|
|
||||||
verify(repostService, times(0)).processMessageEmbedsRepostCheck(anyList(), any(Message.class));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testExecuteNoEmbeds() {
|
|
||||||
channelSetup();
|
|
||||||
setupMessageHasBeenCovered(false);
|
|
||||||
when(channelService.retrieveMessageInChannel(SERVER_ID, CHANNEL_ID, MESSAGE_ID)).thenReturn(CompletableFuture.completedFuture(message));
|
|
||||||
testUnit.execute(model);
|
|
||||||
verify(repostService, times(0)).processMessageEmbedsRepostCheck(anyList(), any(Message.class));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testExecuteOneImageEmbed() {
|
|
||||||
channelSetup();
|
|
||||||
setupMessageHasBeenCovered(false);
|
|
||||||
MessageEmbed imageEmbed = Mockito.mock(MessageEmbed.class);
|
|
||||||
when(imageEmbed.getType()).thenReturn(EmbedType.IMAGE);
|
|
||||||
when(model.getEmbeds()).thenReturn(Arrays.asList(imageEmbed));
|
|
||||||
when(channelService.retrieveMessageInChannel(SERVER_ID, CHANNEL_ID, MESSAGE_ID)).thenReturn(CompletableFuture.completedFuture(message));
|
|
||||||
testUnit.execute(model);
|
|
||||||
verifySingleEmbedProcessed(imageEmbed);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testExecuteMultipleEmbedsOneImage() {
|
|
||||||
channelSetup();
|
|
||||||
setupMessageHasBeenCovered(false);
|
|
||||||
MessageEmbed imageEmbed = Mockito.mock(MessageEmbed.class);
|
|
||||||
MessageEmbed nonImageEmbed = Mockito.mock(MessageEmbed.class);
|
|
||||||
when(imageEmbed.getType()).thenReturn(EmbedType.IMAGE);
|
|
||||||
when(nonImageEmbed.getType()).thenReturn(EmbedType.LINK);
|
|
||||||
when(model.getEmbeds()).thenReturn(Arrays.asList(imageEmbed, nonImageEmbed));
|
|
||||||
when(channelService.retrieveMessageInChannel(SERVER_ID, CHANNEL_ID, MESSAGE_ID)).thenReturn(CompletableFuture.completedFuture(message));
|
|
||||||
testUnit.execute(model);
|
|
||||||
verifySingleEmbedProcessed(imageEmbed);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setupMessageHasBeenCovered(boolean covered) {
|
|
||||||
when(model.getMessageId()).thenReturn(MESSAGE_ID);
|
|
||||||
when(repostManagement.messageEmbedsHaveBeenCovered(MESSAGE_ID)).thenReturn(covered);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void verifySingleEmbedProcessed(MessageEmbed imageEmbed) {
|
|
||||||
verify(repostService, times(1)).processMessageEmbedsRepostCheck(embedListsParameterCaptor.capture(), eq(message));
|
|
||||||
List<MessageEmbed> embeds = embedListsParameterCaptor.getValue();
|
|
||||||
Assert.assertEquals(1, embeds.size());
|
|
||||||
Assert.assertEquals(imageEmbed, embeds.get(0));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private void channelSetup() {
|
|
||||||
when(model.getChannelId()).thenReturn(CHANNEL_ID);
|
|
||||||
when(model.getServerId()).thenReturn(SERVER_ID);
|
|
||||||
when(channelManagementService.loadChannel(CHANNEL_ID)).thenReturn(channel);
|
|
||||||
when(repostCheckChannelService.duplicateCheckEnabledForChannel(channel)).thenReturn(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -52,11 +52,6 @@ public class ListenerExecutorConfig {
|
|||||||
return executorService.setupExecutorFor("messageReceivedListener");
|
return executorService.setupExecutorFor("messageReceivedListener");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean(name = "messageEmbeddedExecutor")
|
|
||||||
public TaskExecutor messageEmbeddedExecutor() {
|
|
||||||
return executorService.setupExecutorFor("messageEmbeddedListener");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean(name = "messageUpdatedExecutor")
|
@Bean(name = "messageUpdatedExecutor")
|
||||||
public TaskExecutor messageUpdatedExecutor() {
|
public TaskExecutor messageUpdatedExecutor() {
|
||||||
return executorService.setupExecutorFor("messageUpdatedListener");
|
return executorService.setupExecutorFor("messageUpdatedListener");
|
||||||
|
|||||||
@@ -1,52 +0,0 @@
|
|||||||
package dev.sheldan.abstracto.core.listener.async.jda;
|
|
||||||
|
|
||||||
import dev.sheldan.abstracto.core.listener.ListenerService;
|
|
||||||
import dev.sheldan.abstracto.core.models.listener.GuildMessageEmbedEventModel;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import net.dv8tion.jda.api.events.message.MessageEmbedEvent;
|
|
||||||
import net.dv8tion.jda.api.hooks.ListenerAdapter;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.beans.factory.annotation.Qualifier;
|
|
||||||
import org.springframework.core.task.TaskExecutor;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@Component
|
|
||||||
@Slf4j
|
|
||||||
public class AsyncMessageEmbeddedListenerBean extends ListenerAdapter {
|
|
||||||
|
|
||||||
@Autowired(required = false)
|
|
||||||
private List<AsyncMessageEmbeddedListener> listenerList;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
@Qualifier("messageEmbeddedExecutor")
|
|
||||||
private TaskExecutor messageEmbeddedListener;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private AsyncMessageEmbeddedListenerBean self;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private ListenerService listenerService;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Transactional
|
|
||||||
public void onMessageEmbed(@Nonnull MessageEmbedEvent event) {
|
|
||||||
if(listenerList == null) return;
|
|
||||||
GuildMessageEmbedEventModel model = getModel(event);
|
|
||||||
listenerList.forEach(leaveListener -> listenerService.executeFeatureAwareListener(leaveListener, model, messageEmbeddedListener));
|
|
||||||
}
|
|
||||||
|
|
||||||
private GuildMessageEmbedEventModel getModel(MessageEmbedEvent event) {
|
|
||||||
return GuildMessageEmbedEventModel
|
|
||||||
.builder()
|
|
||||||
.channelId(event.getChannel().getIdLong())
|
|
||||||
.serverId(event.getGuild().getIdLong())
|
|
||||||
.embeds(event.getMessageEmbeds())
|
|
||||||
.messageId(event.getMessageIdLong())
|
|
||||||
.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,76 +0,0 @@
|
|||||||
package dev.sheldan.abstracto.core.listener.sync.jda;
|
|
||||||
|
|
||||||
import dev.sheldan.abstracto.core.command.service.ExceptionService;
|
|
||||||
import dev.sheldan.abstracto.core.listener.ListenerService;
|
|
||||||
import dev.sheldan.abstracto.core.models.listener.GuildMessageEmbedEventModel;
|
|
||||||
import dev.sheldan.abstracto.core.service.BotService;
|
|
||||||
import dev.sheldan.abstracto.core.service.FeatureConfigService;
|
|
||||||
import dev.sheldan.abstracto.core.service.FeatureFlagService;
|
|
||||||
import dev.sheldan.abstracto.core.service.MessageCache;
|
|
||||||
import dev.sheldan.abstracto.core.utils.BeanUtils;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import net.dv8tion.jda.api.events.message.MessageEmbedEvent;
|
|
||||||
import net.dv8tion.jda.api.hooks.ListenerAdapter;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
import org.springframework.transaction.annotation.Isolation;
|
|
||||||
import org.springframework.transaction.annotation.Propagation;
|
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
|
||||||
import javax.annotation.PostConstruct;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@Component
|
|
||||||
@Slf4j
|
|
||||||
public class MessageEmbeddedListenerBean extends ListenerAdapter {
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private MessageCache messageCache;
|
|
||||||
|
|
||||||
@Autowired(required = false)
|
|
||||||
private List<MessageEmbeddedListener> listenerList;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private FeatureConfigService featureConfigService;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private FeatureFlagService featureFlagService;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private BotService botService;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private ExceptionService exceptionService;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private ListenerService listenerService;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Transactional
|
|
||||||
public void onMessageEmbed(@Nonnull MessageEmbedEvent event) {
|
|
||||||
if(listenerList == null) return;
|
|
||||||
GuildMessageEmbedEventModel model = buildModel(event);
|
|
||||||
listenerList.forEach(messageReceivedListener -> listenerService.executeFeatureAwareListener(messageReceivedListener, model));
|
|
||||||
}
|
|
||||||
|
|
||||||
private GuildMessageEmbedEventModel buildModel(MessageEmbedEvent event) {
|
|
||||||
return GuildMessageEmbedEventModel
|
|
||||||
.builder()
|
|
||||||
.channelId(event.getChannel().getIdLong())
|
|
||||||
.serverId(event.getGuild().getIdLong())
|
|
||||||
.embeds(event.getMessageEmbeds())
|
|
||||||
.messageId(event.getMessageIdLong())
|
|
||||||
.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Transactional(propagation = Propagation.REQUIRES_NEW, isolation = Isolation.SERIALIZABLE)
|
|
||||||
public void executeIndividualGuildMessageReceivedListener(GuildMessageEmbedEventModel model, MessageEmbeddedListener messageReceivedListener) {
|
|
||||||
messageReceivedListener.execute(model);
|
|
||||||
}
|
|
||||||
|
|
||||||
@PostConstruct
|
|
||||||
public void postConstruct() {
|
|
||||||
BeanUtils.sortPrioritizedListeners(listenerList);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
package dev.sheldan.abstracto.core.listener.async.jda;
|
|
||||||
|
|
||||||
import dev.sheldan.abstracto.core.listener.DefaultListenerResult;
|
|
||||||
import dev.sheldan.abstracto.core.listener.FeatureAwareListener;
|
|
||||||
import dev.sheldan.abstracto.core.models.listener.GuildMessageEmbedEventModel;
|
|
||||||
|
|
||||||
public interface AsyncMessageEmbeddedListener extends FeatureAwareListener<GuildMessageEmbedEventModel, DefaultListenerResult> {
|
|
||||||
}
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
package dev.sheldan.abstracto.core.listener.sync.jda;
|
|
||||||
|
|
||||||
import dev.sheldan.abstracto.core.Prioritized;
|
|
||||||
import dev.sheldan.abstracto.core.listener.DefaultListenerResult;
|
|
||||||
import dev.sheldan.abstracto.core.listener.FeatureAwareListener;
|
|
||||||
import dev.sheldan.abstracto.core.models.listener.GuildMessageEmbedEventModel;
|
|
||||||
|
|
||||||
public interface MessageEmbeddedListener extends FeatureAwareListener<GuildMessageEmbedEventModel, DefaultListenerResult>, Prioritized {
|
|
||||||
}
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
package dev.sheldan.abstracto.core.models.listener;
|
|
||||||
|
|
||||||
import dev.sheldan.abstracto.core.listener.FeatureAwareListenerModel;
|
|
||||||
import lombok.Builder;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.Setter;
|
|
||||||
import net.dv8tion.jda.api.entities.MessageEmbed;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
@Builder
|
|
||||||
public class GuildMessageEmbedEventModel implements FeatureAwareListenerModel {
|
|
||||||
@Builder.Default
|
|
||||||
private List<MessageEmbed> embeds = new ArrayList<>();
|
|
||||||
private Long messageId;
|
|
||||||
private Long channelId;
|
|
||||||
private Long serverId;
|
|
||||||
}
|
|
||||||
@@ -8,7 +8,7 @@ import net.dv8tion.jda.api.interactions.InteractionHook;
|
|||||||
public class ContextUtils {
|
public class ContextUtils {
|
||||||
|
|
||||||
public static boolean isGuildKnown(Interaction interaction) {
|
public static boolean isGuildKnown(Interaction interaction) {
|
||||||
return interaction.hasFullGuild();
|
return interaction.isFromAttachedGuild();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isGuildNotKnown(Interaction interaction) {
|
public static boolean isGuildNotKnown(Interaction interaction) {
|
||||||
@@ -25,7 +25,7 @@ public class ContextUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isUserCommand(Interaction interaction) {
|
public static boolean isUserCommand(Interaction interaction) {
|
||||||
return interaction.getIntegrationOwners().getUserIntegration() != null && interaction.getIntegrationOwners().getGuildIntegration() == null;
|
return interaction.getIntegrationOwners().isUserIntegration();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isNotUserCommand(Interaction interaction) {
|
public static boolean isNotUserCommand(Interaction interaction) {
|
||||||
|
|||||||
Reference in New Issue
Block a user