From ad937379d062237cc7007a0ed38a6017902723cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Spie=C3=9F?= Date: Sun, 26 Mar 2023 14:51:01 +0200 Subject: [PATCH 01/39] Basic automod support --- .../net/dv8tion/jda/api/entities/Guild.java | 32 ++ .../entities/automod/AutoModEventType.java | 48 +++ .../api/entities/automod/AutoModResponse.java | 94 +++++ .../jda/api/entities/automod/AutoModRule.java | 117 ++++++ .../entities/automod/AutoModTriggerType.java | 59 +++ .../build/AbstractAutoModRuleBuilder.java | 162 +++++++++ .../build/AbstractKeywordRuleBuilder.java | 62 ++++ .../automod/build/AutoModRuleData.java | 188 ++++++++++ .../automod/build/MentionSpamRuleBuilder.java | 52 +++ .../net/dv8tion/jda/api/requests/Route.java | 9 + .../jda/internal/entities/GuildImpl.java | 55 +++ .../entities/automod/AutoModResponseImpl.java | 131 +++++++ .../entities/automod/AutoModRuleImpl.java | 344 ++++++++++++++++++ 13 files changed, 1353 insertions(+) create mode 100644 src/main/java/net/dv8tion/jda/api/entities/automod/AutoModEventType.java create mode 100644 src/main/java/net/dv8tion/jda/api/entities/automod/AutoModResponse.java create mode 100644 src/main/java/net/dv8tion/jda/api/entities/automod/AutoModRule.java create mode 100644 src/main/java/net/dv8tion/jda/api/entities/automod/AutoModTriggerType.java create mode 100644 src/main/java/net/dv8tion/jda/api/entities/automod/build/AbstractAutoModRuleBuilder.java create mode 100644 src/main/java/net/dv8tion/jda/api/entities/automod/build/AbstractKeywordRuleBuilder.java create mode 100644 src/main/java/net/dv8tion/jda/api/entities/automod/build/AutoModRuleData.java create mode 100644 src/main/java/net/dv8tion/jda/api/entities/automod/build/MentionSpamRuleBuilder.java create mode 100644 src/main/java/net/dv8tion/jda/internal/entities/automod/AutoModResponseImpl.java create mode 100644 src/main/java/net/dv8tion/jda/internal/entities/automod/AutoModRuleImpl.java diff --git a/src/main/java/net/dv8tion/jda/api/entities/Guild.java b/src/main/java/net/dv8tion/jda/api/entities/Guild.java index f61853dc79..7d0c5f5999 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/Guild.java +++ b/src/main/java/net/dv8tion/jda/api/entities/Guild.java @@ -21,6 +21,8 @@ import net.dv8tion.jda.api.JDA; import net.dv8tion.jda.api.Permission; import net.dv8tion.jda.api.Region; +import net.dv8tion.jda.api.entities.automod.AutoModRule; +import net.dv8tion.jda.api.entities.automod.build.AutoModRuleData; import net.dv8tion.jda.api.entities.channel.Channel; import net.dv8tion.jda.api.entities.channel.attribute.ICopyableChannel; import net.dv8tion.jda.api.entities.channel.attribute.IGuildChannelContainer; @@ -405,6 +407,36 @@ default RestAction> retrieveRegions() @CheckReturnValue RestAction> retrieveRegions(boolean includeDeprecated); + @Nonnull + @CheckReturnValue + RestAction> retrieveAutoModRules(); + + @Nonnull + @CheckReturnValue + RestAction retrieveAutoModRuleById(@Nonnull String id); + + @Nonnull + @CheckReturnValue + default RestAction retrieveAutoModRuleById(long id) + { + return retrieveAutoModRuleById(Long.toUnsignedString(id)); + } + + @Nonnull + @CheckReturnValue + RestAction createAutoModRule(@Nonnull AutoModRuleData data); + + @Nonnull + @CheckReturnValue + RestAction deleteAutoModRuleById(@Nonnull String id); + + @Nonnull + @CheckReturnValue + default RestAction deleteAutoModRuleById(long id) + { + return deleteAutoModRuleById(Long.toUnsignedString(id)); + } + /** * Adds the user to this guild as a member. *
This requires an OAuth2 Access Token with the scope {@code guilds.join}. diff --git a/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModEventType.java b/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModEventType.java new file mode 100644 index 0000000000..2d7304b6c4 --- /dev/null +++ b/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModEventType.java @@ -0,0 +1,48 @@ +/* + * Copyright 2015 Austin Keener, Michael Ritter, Florian Spieß, and the JDA contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.dv8tion.jda.api.entities.automod; + +import javax.annotation.Nonnull; + +public enum AutoModEventType +{ + MESSAGE_SEND(1), + UNKNOWN(-1); + + private final int key; + + AutoModEventType(int key) + { + this.key = key; + } + + public int getKey() + { + return key; + } + + @Nonnull + public static AutoModEventType fromKey(int key) + { + for (AutoModEventType type : values()) + { + if (type.key == key) + return type; + } + return UNKNOWN; + } +} diff --git a/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModResponse.java b/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModResponse.java new file mode 100644 index 0000000000..62dcec2c26 --- /dev/null +++ b/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModResponse.java @@ -0,0 +1,94 @@ +/* + * Copyright 2015 Austin Keener, Michael Ritter, Florian Spieß, and the JDA contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.dv8tion.jda.api.entities.automod; + +import net.dv8tion.jda.api.entities.channel.middleman.GuildMessageChannel; +import net.dv8tion.jda.api.utils.data.SerializableData; +import net.dv8tion.jda.internal.entities.automod.AutoModResponseImpl; +import net.dv8tion.jda.internal.utils.Checks; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.time.Duration; + +public interface AutoModResponse extends SerializableData +{ + @Nonnull + Type getType(); + + @Nullable + GuildMessageChannel getChannel(); + + @Nullable + String getCustomMessage(); + + @Nullable + Duration getTimeoutDuration(); + + @Nonnull + static AutoModResponse blockMessage(@Nullable String customMessage) + { + return new AutoModResponseImpl(Type.BLOCK_MESSAGE, customMessage); + } + + @Nonnull + static AutoModResponse sendAlert(@Nonnull GuildMessageChannel channel) + { + Checks.notNull(channel, "Channel"); + return new AutoModResponseImpl(Type.SEND_ALERT_MESSAGE, channel); + } + + @Nonnull + static AutoModResponse timeoutMember(@Nonnull Duration duration) + { + Checks.notNull(duration, "Duration"); + Checks.check(!duration.isNegative() && !duration.isZero(), "Duration must be positive"); + return new AutoModResponseImpl(Type.TIMEOUT, duration); + } + + enum Type + { + BLOCK_MESSAGE(1), + SEND_ALERT_MESSAGE(2), + TIMEOUT(3), + UNKNOWN(-1) + ; + + private final int key; + + Type(int key) + { + this.key = key; + } + + public int getKey() + { + return key; + } + + @Nonnull + public static Type fromKey(int key) + { + for (Type type : values()) + { + if (type.key == key) + return type; + } + return UNKNOWN; + } + } +} diff --git a/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModRule.java b/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModRule.java new file mode 100644 index 0000000000..92fba50d2a --- /dev/null +++ b/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModRule.java @@ -0,0 +1,117 @@ +/* + * Copyright 2015 Austin Keener, Michael Ritter, Florian Spieß, and the JDA contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.dv8tion.jda.api.entities.automod; + +import net.dv8tion.jda.api.entities.Guild; +import net.dv8tion.jda.api.entities.ISnowflake; +import net.dv8tion.jda.api.entities.Role; +import net.dv8tion.jda.api.entities.automod.build.MentionSpamRuleBuilder; +import net.dv8tion.jda.api.entities.channel.middleman.GuildChannel; + +import javax.annotation.Nonnull; +import java.util.EnumSet; +import java.util.List; + +public interface AutoModRule extends ISnowflake +{ + int MAX_KEYWORD_LENGTH = 60; + int MAX_KEYWORD_TOTAL_LENGTH = 1000; + int MAX_ALLOWLIST_TOTAL_LENGTH = 100; + int MAX_ALLOWLIST_PRESET_LENGTH = 1000; + + @Nonnull + static MentionSpamRuleBuilder createMentionSpamRule(@Nonnull String name, int limit) + { + return new MentionSpamRuleBuilder(name, limit); + } + + @Nonnull + Guild getGuild(); + + long getOwnerIdLong(); + + @Nonnull + default String getOwnerId() + { + return Long.toUnsignedString(getOwnerIdLong()); + } + + @Nonnull + String getName(); + + @Nonnull + AutoModEventType getEventType(); + + @Nonnull + AutoModTriggerType getTriggerType(); + + boolean isEnabled(); + + @Nonnull + List getExemptRoles(); + + @Nonnull + List getExemptChannels(); + + @Nonnull + List getActions(); + + @Nonnull + List getFilteredKeywords(); + + @Nonnull + List getFilteredRegex(); + + @Nonnull + EnumSet getFilteredPresets(); + + @Nonnull + List getAllowlist(); + + int getMentionLimit(); + + enum KeywordPreset + { + PROFANITY(1), + SEXUAL_CONTENT(2), + SLURS(3), + UNKNOWN(-1); + + private final int key; + + KeywordPreset(int key) + { + this.key = key; + } + + public int getKey() + { + return key; + } + + @Nonnull + public static KeywordPreset fromKey(int key) + { + for (KeywordPreset preset : values()) + { + if (preset.key == key) + return preset; + } + return UNKNOWN; + } + } +} diff --git a/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModTriggerType.java b/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModTriggerType.java new file mode 100644 index 0000000000..3f5f15c3f7 --- /dev/null +++ b/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModTriggerType.java @@ -0,0 +1,59 @@ +/* + * Copyright 2015 Austin Keener, Michael Ritter, Florian Spieß, and the JDA contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.dv8tion.jda.api.entities.automod; + +import javax.annotation.Nonnull; + +public enum AutoModTriggerType +{ + KEYWORD(1, 6), + SPAM(3, 1), + KEYWORD_PRESET(4, 1), + MENTION(5, 1), + UNKNOWN(-1, 1), + ; + + private final int key; + private final int maxPerGuild; + + AutoModTriggerType(int key, int maxPerGuild) + { + this.key = key; + this.maxPerGuild = maxPerGuild; + } + + public int getKey() + { + return key; + } + + public int getMaxPerGuild() + { + return maxPerGuild; + } + + @Nonnull + public static AutoModTriggerType fromKey(int key) + { + for (AutoModTriggerType trigger : values()) + { + if (trigger.key == key) + return trigger; + } + return UNKNOWN; + } +} diff --git a/src/main/java/net/dv8tion/jda/api/entities/automod/build/AbstractAutoModRuleBuilder.java b/src/main/java/net/dv8tion/jda/api/entities/automod/build/AbstractAutoModRuleBuilder.java new file mode 100644 index 0000000000..0a0607e8f9 --- /dev/null +++ b/src/main/java/net/dv8tion/jda/api/entities/automod/build/AbstractAutoModRuleBuilder.java @@ -0,0 +1,162 @@ +/* + * Copyright 2015 Austin Keener, Michael Ritter, Florian Spieß, and the JDA contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.dv8tion.jda.api.entities.automod.build; + +import gnu.trove.list.TLongList; +import gnu.trove.list.array.TLongArrayList; +import net.dv8tion.jda.api.entities.Role; +import net.dv8tion.jda.api.entities.automod.AutoModEventType; +import net.dv8tion.jda.api.entities.automod.AutoModResponse; +import net.dv8tion.jda.api.entities.automod.AutoModTriggerType; +import net.dv8tion.jda.api.entities.channel.middleman.GuildChannel; +import net.dv8tion.jda.internal.utils.Checks; + +import javax.annotation.Nonnull; +import java.util.ArrayList; +import java.util.Collection; +import java.util.EnumMap; + +public abstract class AbstractAutoModRuleBuilder> +{ + protected final AutoModTriggerType triggerType; + protected final AutoModEventType eventType; + protected String name; + protected boolean enabled = true; + + protected final EnumMap actions = new EnumMap<>(AutoModResponse.Type.class); + protected final TLongList exemptChannels = new TLongArrayList(); + protected final TLongList exemptRoles = new TLongArrayList(); + + protected AbstractAutoModRuleBuilder(AutoModTriggerType triggerType, AutoModEventType eventType, String name) + { + Checks.notNull(triggerType, "Trigger Type"); + Checks.notNull(eventType, "Event Type"); + this.triggerType = triggerType; + this.eventType = eventType; + setName(name); + } + + @Nonnull + public B setName(@Nonnull String name) + { + Checks.notEmpty(name, "Name"); + this.name = name; + return (B) this; + } + + @Nonnull + public B setEnabled(boolean enabled) + { + this.enabled = enabled; + return (B) this; + } + + @Nonnull + public B putResponses(@Nonnull AutoModResponse... responses) + { + Checks.noneNull(responses, "Responses"); + for (AutoModResponse response : responses) + actions.put(response.getType(), response); + return (B) this; + } + + @Nonnull + public B putResponses(@Nonnull Collection responses) + { + Checks.noneNull(responses, "Responses"); + for (AutoModResponse response : responses) + actions.put(response.getType(), response); + return (B) this; + } + + @Nonnull + public B setResponses(@Nonnull Collection responses) + { + Checks.noneNull(responses, "Responses"); + actions.clear(); + for (AutoModResponse response : responses) + actions.put(response.getType(), response); + return (B) this; + } + + @Nonnull + public B addExemptRoles(@Nonnull Role... roles) + { + Checks.noneNull(roles, "Roles"); + for (Role role : roles) + exemptRoles.add(role.getIdLong()); + return (B) this; + } + + @Nonnull + public B addExemptRoles(@Nonnull Collection roles) + { + Checks.noneNull(roles, "Roles"); + for (Role role : roles) + exemptRoles.add(role.getIdLong()); + return (B) this; + } + + @Nonnull + public B setExemptRoles(@Nonnull Collection roles) + { + Checks.noneNull(roles, "Roles"); + exemptRoles.clear(); + for (Role role : roles) + exemptRoles.add(role.getIdLong()); + return (B) this; + } + + @Nonnull + public B addExemptChannels(@Nonnull GuildChannel... channels) + { + Checks.noneNull(channels, "Channels"); + for (GuildChannel channel : channels) + exemptChannels.add(channel.getIdLong()); + return (B) this; + } + + @Nonnull + public B addExemptChannels(@Nonnull Collection channels) + { + Checks.noneNull(channels, "Channels"); + for (GuildChannel channel : channels) + exemptChannels.add(channel.getIdLong()); + return (B) this; + } + + @Nonnull + public B setExemptChannels(@Nonnull Collection channels) + { + Checks.noneNull(channels, "Channels"); + exemptChannels.clear(); + for (GuildChannel channel : channels) + exemptChannels.add(channel.getIdLong()); + return (B) this; + } + + @Nonnull + public AutoModRuleData build() + { + AutoModRuleData rule = new AutoModRuleData(triggerType, eventType, name); + rule.setEnabled(enabled); + rule.setExemptChannels(exemptChannels.toArray()); + rule.setExemptRoles(exemptRoles.toArray()); + rule.setActions(new ArrayList<>(actions.values())); + return rule; + } +} diff --git a/src/main/java/net/dv8tion/jda/api/entities/automod/build/AbstractKeywordRuleBuilder.java b/src/main/java/net/dv8tion/jda/api/entities/automod/build/AbstractKeywordRuleBuilder.java new file mode 100644 index 0000000000..f6a26e5405 --- /dev/null +++ b/src/main/java/net/dv8tion/jda/api/entities/automod/build/AbstractKeywordRuleBuilder.java @@ -0,0 +1,62 @@ +/* + * Copyright 2015 Austin Keener, Michael Ritter, Florian Spieß, and the JDA contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.dv8tion.jda.api.entities.automod.build; + +import net.dv8tion.jda.api.entities.automod.AutoModEventType; +import net.dv8tion.jda.api.entities.automod.AutoModTriggerType; +import net.dv8tion.jda.internal.utils.Checks; + +import javax.annotation.Nonnull; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +public abstract class AbstractKeywordRuleBuilder> extends AbstractAutoModRuleBuilder +{ + protected final List allowList = new ArrayList<>(); + + protected AbstractKeywordRuleBuilder(AutoModTriggerType triggerType, AutoModEventType eventType, String name) + { + super(triggerType, eventType, name); + } + + @Nonnull + public B addAllowList(@Nonnull String... keywords) + { + Checks.noneNull(keywords, "Keywords"); + Collections.addAll(allowList, keywords); + return (B) this; + } + + @Nonnull + public B addAllowList(@Nonnull Collection keywords) + { + Checks.noneNull(keywords, "Keywords"); + allowList.addAll(keywords); + return (B) this; + } + + @Nonnull + public B setAllowList(@Nonnull Collection keywords) + { + Checks.noneNull(keywords, "Keywords"); + allowList.clear(); + allowList.addAll(keywords); + return (B) this; + } +} diff --git a/src/main/java/net/dv8tion/jda/api/entities/automod/build/AutoModRuleData.java b/src/main/java/net/dv8tion/jda/api/entities/automod/build/AutoModRuleData.java new file mode 100644 index 0000000000..6114711062 --- /dev/null +++ b/src/main/java/net/dv8tion/jda/api/entities/automod/build/AutoModRuleData.java @@ -0,0 +1,188 @@ +/* + * Copyright 2015 Austin Keener, Michael Ritter, Florian Spieß, and the JDA contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.dv8tion.jda.api.entities.automod.build; + +import net.dv8tion.jda.api.entities.automod.AutoModEventType; +import net.dv8tion.jda.api.entities.automod.AutoModResponse; +import net.dv8tion.jda.api.entities.automod.AutoModRule; +import net.dv8tion.jda.api.entities.automod.AutoModTriggerType; +import net.dv8tion.jda.api.utils.data.DataArray; +import net.dv8tion.jda.api.utils.data.DataObject; +import net.dv8tion.jda.api.utils.data.SerializableData; + +import javax.annotation.Nonnull; +import java.util.EnumSet; +import java.util.List; + +public class AutoModRuleData implements SerializableData +{ + private final AutoModTriggerType triggerType; + private final AutoModEventType eventType; + private final String name; + + private boolean enabled = true; + private int mentionLimit = -1; + private List actions; + private long[] exemptRoles; + private long[] exemptChannels; + private List filteredKeywords; + private List filteredRegex; + private EnumSet filteredPresets; + private List allowlist; + + protected AutoModRuleData(AutoModTriggerType triggerType, AutoModEventType eventType, String name) + { + this.triggerType = triggerType; + this.eventType = eventType; + this.name = name; + } + + protected AutoModRuleData setEnabled(boolean enabled) + { + this.enabled = enabled; + return this; + } + + protected AutoModRuleData setMentionLimit(int mentionLimit) + { + this.mentionLimit = mentionLimit; + return this; + } + + protected AutoModRuleData setActions(List actions) + { + this.actions = actions; + return this; + } + + protected AutoModRuleData setExemptRoles(long... exemptRoles) + { + this.exemptRoles = exemptRoles; + return this; + } + + protected AutoModRuleData setExemptChannels(long... exemptChannels) + { + this.exemptChannels = exemptChannels; + return this; + } + + protected AutoModRuleData setFilteredKeywords(List filteredKeywords) + { + this.filteredKeywords = filteredKeywords; + return this; + } + + protected AutoModRuleData setFilteredRegex(List filteredRegex) + { + this.filteredRegex = filteredRegex; + return this; + } + + protected AutoModRuleData setFilteredPresets(EnumSet filteredPresets) + { + this.filteredPresets = filteredPresets; + return this; + } + + protected AutoModRuleData setAllowlist(List allowlist) + { + this.allowlist = allowlist; + return this; + } + + @Nonnull + @Override + public DataObject toData() + { + DataObject data = DataObject.empty() + .put("name", name) + .put("trigger_type", triggerType.getKey()) + .put("event_type", eventType.getKey()); + + data.put("enabled", enabled); + + if (actions != null) + data.put("actions", DataArray.fromCollection(actions)); + else + data.put("actions", DataArray.empty()); + + if (exemptRoles != null) + { + DataArray array = DataArray.empty(); + for (long id : exemptRoles) + array.add(id); + data.put("exempt_roles", array); + } + else + { + data.put("exempt_roles", DataArray.empty()); + } + + if (exemptChannels != null) + { + DataArray array = DataArray.empty(); + for (long id : exemptChannels) + array.add(id); + data.put("exempt_channels", array); + } + else + { + data.put("exempt_channels", DataArray.empty()); + } + + DataObject metadata = DataObject.empty(); + + switch (triggerType) + { + case MENTION: + if (mentionLimit != -1) + metadata.put("mention_total_limit", mentionLimit); + break; + case SPAM: + break; + case KEYWORD: + if (filteredKeywords != null) + metadata.put("filtered_keywords", DataArray.fromCollection(filteredKeywords)); + else + metadata.put("filtered_keywords", DataArray.empty()); + if (filteredRegex != null) + metadata.put("filtered_regex", DataArray.fromCollection(filteredRegex)); + else + metadata.put("filtered_regex", DataArray.empty()); + if (allowlist != null) + metadata.put("allow_list", DataArray.fromCollection(allowlist)); + else + metadata.put("allow_list", DataArray.empty()); + break; + case KEYWORD_PRESET: + if (filteredPresets != null) + metadata.put("filtered_presets", DataArray.fromCollection(filteredPresets)); + else + metadata.put("filtered_presets", DataArray.empty()); + if (allowlist != null) + metadata.put("allow_list", DataArray.fromCollection(allowlist)); + else + metadata.put("allow_list", DataArray.empty()); + break; + } + + data.put("trigger_metadata", metadata); + + return data; + } +} diff --git a/src/main/java/net/dv8tion/jda/api/entities/automod/build/MentionSpamRuleBuilder.java b/src/main/java/net/dv8tion/jda/api/entities/automod/build/MentionSpamRuleBuilder.java new file mode 100644 index 0000000000..807fba103c --- /dev/null +++ b/src/main/java/net/dv8tion/jda/api/entities/automod/build/MentionSpamRuleBuilder.java @@ -0,0 +1,52 @@ +/* + * Copyright 2015 Austin Keener, Michael Ritter, Florian Spieß, and the JDA contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.dv8tion.jda.api.entities.automod.build; + +import net.dv8tion.jda.api.entities.automod.AutoModEventType; +import net.dv8tion.jda.api.entities.automod.AutoModTriggerType; +import net.dv8tion.jda.internal.utils.Checks; + +import javax.annotation.Nonnull; + +public class MentionSpamRuleBuilder extends AbstractAutoModRuleBuilder +{ + private int mentionLimit; + + public MentionSpamRuleBuilder(@Nonnull String name, int limit) + { + super(AutoModTriggerType.MENTION, AutoModEventType.MESSAGE_SEND, name); + Checks.positive(limit, "Mention Limit"); + this.mentionLimit = limit; + } + + @Nonnull + public MentionSpamRuleBuilder setMentionLimit(int limit) + { + Checks.positive(limit, "Mention Limit"); + this.mentionLimit = limit; + return this; + } + + @Nonnull + @Override + public AutoModRuleData build() + { + AutoModRuleData rule = super.build(); + rule.setMentionLimit(mentionLimit); + return rule; + } +} diff --git a/src/main/java/net/dv8tion/jda/api/requests/Route.java b/src/main/java/net/dv8tion/jda/api/requests/Route.java index 3c64d22762..f5e04a79ab 100644 --- a/src/main/java/net/dv8tion/jda/api/requests/Route.java +++ b/src/main/java/net/dv8tion/jda/api/requests/Route.java @@ -229,6 +229,15 @@ public static class StageInstances public static final Route CREATE_INSTANCE = new Route(POST, "stage-instances"); } + public static class AutoModeration + { + public static final Route LIST_RULES = new Route(GET, "guilds/{guild_id}/auto-moderation/rules"); + public static final Route GET_RULE = new Route(GET, "guilds/{guild_id}/auto-moderation/rules/{rule_id}"); + public static final Route CREATE_RULE = new Route(POST, "guilds/{guild_id}/auto-moderation/rules"); + public static final Route UPDATE_RULE = new Route(PATCH, "guilds/{guild_id}/auto-moderation/rules/{rule_id}"); + public static final Route DELETE_RULE = new Route(DELETE, "guilds/{guild_id}/auto-moderation/rules/{rule_id}"); + } + public static class Messages { public static final Route EDIT_MESSAGE = new Route(PATCH, "channels/{channel_id}/messages/{message_id}"); // requires special handling, same bucket but different endpoints diff --git a/src/main/java/net/dv8tion/jda/internal/entities/GuildImpl.java b/src/main/java/net/dv8tion/jda/internal/entities/GuildImpl.java index ef18eea01d..fb11eb2371 100644 --- a/src/main/java/net/dv8tion/jda/internal/entities/GuildImpl.java +++ b/src/main/java/net/dv8tion/jda/internal/entities/GuildImpl.java @@ -23,6 +23,8 @@ import net.dv8tion.jda.api.Region; import net.dv8tion.jda.api.audio.hooks.ConnectionStatus; import net.dv8tion.jda.api.entities.*; +import net.dv8tion.jda.api.entities.automod.AutoModRule; +import net.dv8tion.jda.api.entities.automod.build.AutoModRuleData; import net.dv8tion.jda.api.entities.channel.Channel; import net.dv8tion.jda.api.entities.channel.ChannelType; import net.dv8tion.jda.api.entities.channel.concrete.*; @@ -61,6 +63,7 @@ import net.dv8tion.jda.api.utils.data.DataArray; import net.dv8tion.jda.api.utils.data.DataObject; import net.dv8tion.jda.internal.JDAImpl; +import net.dv8tion.jda.internal.entities.automod.AutoModRuleImpl; import net.dv8tion.jda.internal.handle.EventCache; import net.dv8tion.jda.internal.interactions.CommandDataImpl; import net.dv8tion.jda.internal.interactions.command.CommandImpl; @@ -358,6 +361,58 @@ public RestAction> retrieveRegions(boolean includeDeprecated) }); } + @Nonnull + @Override + public RestAction> retrieveAutoModRules() + { + Route.CompiledRoute route = Route.AutoModeration.LIST_RULES.compile(getId()); + return new RestActionImpl<>(api, route, (response, request) -> + { + DataArray array = response.getArray(); + List rules = new ArrayList<>(array.length()); + for (int i = 0; i < array.length(); i++) + { + try + { + DataObject obj = array.getObject(i); + rules.add(AutoModRuleImpl.fromData(this, obj)); + } + catch (ParsingException exception) + { + EntityBuilder.LOG.error("Failed to parse AutoModRule", exception); + } + } + return Collections.unmodifiableList(rules); + }); + } + + @Nonnull + @Override + public RestAction retrieveAutoModRuleById(@Nonnull String id) + { + Checks.isSnowflake(id); + Route.CompiledRoute route = Route.AutoModeration.GET_RULE.compile(getId(), id); + return new RestActionImpl<>(api, route, (response, request) -> AutoModRuleImpl.fromData(this, response.getObject())); + } + + @Nonnull + @Override + public RestAction createAutoModRule(@Nonnull AutoModRuleData rule) + { + Checks.notNull(rule, "AutoMod Rule"); + Route.CompiledRoute route = Route.AutoModeration.CREATE_RULE.compile(getId()); + return new RestActionImpl<>(api, route, rule.toData(), (response, request) -> AutoModRuleImpl.fromData(this, response.getObject())); + } + + @Nonnull + @Override + public RestAction deleteAutoModRuleById(@Nonnull String id) + { + Checks.isSnowflake(id); + Route.CompiledRoute route = Route.AutoModeration.DELETE_RULE.compile(getId(), id); + return new RestActionImpl<>(api, route); + } + @Nonnull @Override public MemberAction addMember(@Nonnull String accessToken, @Nonnull UserSnowflake user) diff --git a/src/main/java/net/dv8tion/jda/internal/entities/automod/AutoModResponseImpl.java b/src/main/java/net/dv8tion/jda/internal/entities/automod/AutoModResponseImpl.java new file mode 100644 index 0000000000..e92b4d75c2 --- /dev/null +++ b/src/main/java/net/dv8tion/jda/internal/entities/automod/AutoModResponseImpl.java @@ -0,0 +1,131 @@ +/* + * Copyright 2015 Austin Keener, Michael Ritter, Florian Spieß, and the JDA contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.dv8tion.jda.internal.entities.automod; + +import net.dv8tion.jda.api.entities.Guild; +import net.dv8tion.jda.api.entities.automod.AutoModResponse; +import net.dv8tion.jda.api.entities.channel.middleman.GuildMessageChannel; +import net.dv8tion.jda.api.utils.data.DataObject; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.time.Duration; + +public class AutoModResponseImpl implements AutoModResponse +{ + private final Type type; + private final GuildMessageChannel channel; + private final String customMessage; + private final long timeoutDuration; + + public AutoModResponseImpl(Type type, GuildMessageChannel channel) + { + this.type = type; + this.channel = channel; + this.customMessage = null; + this.timeoutDuration = 0; + } + + public AutoModResponseImpl(Type type, String customMessage) + { + this.type = type; + this.customMessage = customMessage; + this.channel = null; + this.timeoutDuration = 0; + } + + public AutoModResponseImpl(Type type, Duration duration) + { + this.type = type; + this.timeoutDuration = duration.getSeconds(); + this.customMessage = null; + this.channel = null; + } + + public AutoModResponseImpl(Guild guild, DataObject json) + { + this.type = AutoModResponse.Type.fromKey(json.getInt("type", -1)); + this.channel = guild.getChannelById(GuildMessageChannel.class, json.getUnsignedLong("channel_id", 0L)); + this.customMessage = json.getString("custom_message", null); + this.timeoutDuration = json.getUnsignedLong("duration_seconds", 0L); + } + + @Nonnull + @Override + public Type getType() + { + return type; + } + + @Nullable + @Override + public GuildMessageChannel getChannel() + { + return channel; + } + + @Nullable + @Override + public String getCustomMessage() + { + return customMessage; + } + + @Nullable + @Override + public Duration getTimeoutDuration() + { + return timeoutDuration == 0 ? null : Duration.ofSeconds(timeoutDuration); + } + + @Nonnull + @Override + public DataObject toData() + { + DataObject action = DataObject.empty(); + action.put("type", type.getKey()); + if (type == Type.BLOCK_MESSAGE && customMessage == null) + return action; + + DataObject metadata = DataObject.empty(); + if (customMessage != null) + metadata.put("custom_message", customMessage); + if (channel != null) + metadata.put("channel_id", channel.getId()); + if (timeoutDuration > 0) + metadata.put("duration_seconds", timeoutDuration); + action.put("metadata", metadata); + return action; + } + + @Override + public int hashCode() + { + return type.hashCode(); + } + + @Override + public boolean equals(Object obj) + { + if (this == obj) + return true; + if (!(obj instanceof AutoModResponseImpl)) + return false; + AutoModResponseImpl o = (AutoModResponseImpl) obj; + return type == o.type; + } +} diff --git a/src/main/java/net/dv8tion/jda/internal/entities/automod/AutoModRuleImpl.java b/src/main/java/net/dv8tion/jda/internal/entities/automod/AutoModRuleImpl.java new file mode 100644 index 0000000000..dfc61dcea0 --- /dev/null +++ b/src/main/java/net/dv8tion/jda/internal/entities/automod/AutoModRuleImpl.java @@ -0,0 +1,344 @@ +/* + * Copyright 2015 Austin Keener, Michael Ritter, Florian Spieß, and the JDA contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.dv8tion.jda.internal.entities.automod; + +import gnu.trove.list.TLongList; +import gnu.trove.list.array.TLongArrayList; +import net.dv8tion.jda.api.entities.Guild; +import net.dv8tion.jda.api.entities.Role; +import net.dv8tion.jda.api.entities.automod.AutoModEventType; +import net.dv8tion.jda.api.entities.automod.AutoModResponse; +import net.dv8tion.jda.api.entities.automod.AutoModRule; +import net.dv8tion.jda.api.entities.automod.AutoModTriggerType; +import net.dv8tion.jda.api.entities.channel.middleman.GuildChannel; +import net.dv8tion.jda.api.utils.data.DataArray; +import net.dv8tion.jda.api.utils.data.DataObject; +import net.dv8tion.jda.internal.utils.EntityString; +import net.dv8tion.jda.internal.utils.Helpers; +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.EnumSet; +import java.util.List; +import java.util.stream.Collectors; + +public class AutoModRuleImpl implements AutoModRule +{ + private final long id; + private Guild guild; + private long ownerId; + private String name = ""; + private AutoModEventType eventType = AutoModEventType.UNKNOWN; + private AutoModTriggerType triggerType = AutoModTriggerType.UNKNOWN; + private boolean enabled = false; + private TLongList exemptRoles = new TLongArrayList(); + private TLongList exemptChannels = new TLongArrayList(); + private List actions = Collections.emptyList(); + private List filteredKeywords = Collections.emptyList(); + private List filteredRegex = Collections.emptyList(); + private EnumSet filteredPresets = EnumSet.noneOf(KeywordPreset.class); + private List allowlist = Collections.emptyList(); + private int mentionLimit = -1; + + public AutoModRuleImpl(Guild guild, long id) + { + this.id = id; + this.guild = guild; + } + + @Override + public long getIdLong() + { + return id; + } + + @NotNull + @Override + public Guild getGuild() + { + Guild realGuild = guild.getJDA().getGuildById(guild.getIdLong()); + if (realGuild != null) + guild = realGuild; + return guild; + } + + @Override + public long getOwnerIdLong() + { + return ownerId; + } + + @NotNull + @Override + public String getName() + { + return name; + } + + @NotNull + @Override + public AutoModEventType getEventType() + { + return eventType; + } + + @NotNull + @Override + public AutoModTriggerType getTriggerType() + { + return triggerType; + } + + @Override + public boolean isEnabled() + { + return enabled; + } + + @NotNull + @Override + public List getExemptRoles() + { + List roles = new ArrayList<>(exemptRoles.size()); + for (int i = 0; i < exemptRoles.size(); i++) + { + long roleId = exemptRoles.get(i); + Role role = guild.getRoleById(roleId); + if (role != null) + roles.add(role); + } + return Collections.unmodifiableList(roles); + } + + @NotNull + @Override + public List getExemptChannels() + { + List channels = new ArrayList<>(exemptChannels.size()); + for (int i = 0; i < exemptChannels.size(); i++) + { + long channelId = exemptChannels.get(i); + GuildChannel channel = guild.getGuildChannelById(channelId); + if (channel != null) + channels.add(channel); + } + return Collections.unmodifiableList(channels); + } + + @NotNull + @Override + public List getActions() + { + return actions; + } + + @NotNull + @Override + public List getFilteredKeywords() + { + return filteredKeywords; + } + + @NotNull + @Override + public List getFilteredRegex() + { + return filteredRegex; + } + + @NotNull + @Override + public EnumSet getFilteredPresets() + { + return Helpers.copyEnumSet(KeywordPreset.class, filteredPresets); + } + + @NotNull + @Override + public List getAllowlist() + { + return allowlist; + } + + @Override + public int getMentionLimit() + { + return mentionLimit; + } + + public AutoModRuleImpl setName(String name) + { + this.name = name; + return this; + } + + public AutoModRuleImpl setEnabled(boolean enabled) + { + this.enabled = enabled; + return this; + } + + public AutoModRuleImpl setOwnerId(long ownerId) + { + this.ownerId = ownerId; + return this; + } + + public AutoModRuleImpl setEventType(AutoModEventType eventType) + { + this.eventType = eventType; + return this; + } + + public AutoModRuleImpl setTriggerType(AutoModTriggerType triggerType) + { + this.triggerType = triggerType; + return this; + } + + public AutoModRuleImpl setExemptRoles(TLongList exemptRoles) + { + this.exemptRoles = exemptRoles; + return this; + } + + public AutoModRuleImpl setExemptChannels(TLongList exemptChannels) + { + this.exemptChannels = exemptChannels; + return this; + } + + public AutoModRuleImpl setActions(List actions) + { + this.actions = actions; + return this; + } + + public AutoModRuleImpl setFilteredKeywords(List filteredKeywords) + { + this.filteredKeywords = filteredKeywords; + return this; + } + + public AutoModRuleImpl setFilteredRegex(List filteredRegex) + { + this.filteredRegex = filteredRegex; + return this; + } + + public AutoModRuleImpl setFilteredPresets(EnumSet filteredPresets) + { + this.filteredPresets = filteredPresets; + return this; + } + + public AutoModRuleImpl setAllowlist(List allowlist) + { + this.allowlist = allowlist; + return this; + } + + public AutoModRuleImpl setMentionLimit(int mentionLimit) + { + this.mentionLimit = mentionLimit; + return this; + } + + @Override + public int hashCode() + { + return Long.hashCode(id); + } + + @Override + public boolean equals(Object obj) + { + if (obj == this) + return true; + if (!(obj instanceof AutoModRuleImpl)) + return false; + AutoModRuleImpl oRule = (AutoModRuleImpl) obj; + return this.id == oRule.id; + } + + @Override + public String toString() + { + return new EntityString(this) + .setType(triggerType) + .setName(name) + .addMetadata("id", getId()) + .toString(); + } + + public static AutoModRuleImpl fromData(Guild guild, DataObject data) + { + long id = data.getUnsignedLong("id"); + AutoModRuleImpl rule = new AutoModRuleImpl(guild, id); + + rule.setName(data.getString("name")) + .setEnabled(data.getBoolean("enabled", true)) + .setOwnerId(data.getUnsignedLong("creator_id", 0L)) + .setEventType(AutoModEventType.fromKey(data.getInt("event_type", -1))) + .setTriggerType(AutoModTriggerType.fromKey(data.getInt("trigger_type", -1))); + + data.optArray("exempt_roles").ifPresent(array -> rule.setExemptRoles(parseList(array))); + data.optArray("exempt_channels").ifPresent(array -> rule.setExemptChannels(parseList(array))); + + data.optArray("actions").ifPresent(array -> + rule.setActions(array.stream(DataArray::getObject) + .map(obj -> new AutoModResponseImpl(guild, obj)) + .collect(Helpers.toUnmodifiableList())) + ); + + data.optObject("trigger_metadata").ifPresent(metadata -> { + // Only for KEYWORD type + metadata.optArray("keyword_filter").ifPresent(array -> + rule.setFilteredKeywords(array.stream(DataArray::getString) + .collect(Helpers.toUnmodifiableList())) + ); + metadata.optArray("regex_patterns").ifPresent(array -> + rule.setFilteredRegex(array.stream(DataArray::getString) + .collect(Helpers.toUnmodifiableList())) + ); + // Both KEYWORD and KEYWORD_PRESET + metadata.optArray("allow_list").ifPresent(array -> + rule.setAllowlist(array.stream(DataArray::getString) + .collect(Helpers.toUnmodifiableList())) + ); + // Only KEYWORD_PRESET + metadata.optArray("presets").ifPresent(array -> + rule.setFilteredPresets(array.stream(DataArray::getInt) + .map(KeywordPreset::fromKey) + .collect(Collectors.toCollection(() -> EnumSet.noneOf(KeywordPreset.class)))) + ); + // Only for MENTION type + rule.setMentionLimit(metadata.getInt("mention_total_limit", 0)); + }); + + return rule; + } + + private static TLongList parseList(DataArray array) + { + TLongList list = new TLongArrayList(array.length()); + for (int i = 0; i < array.length(); i++) + list.add(array.getUnsignedLong(i)); + return list; + } +} From 2dc6f4eacfb86719b785b6cfcf35a890caf36a09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Spie=C3=9F?= Date: Sun, 26 Mar 2023 16:02:06 +0200 Subject: [PATCH 02/39] Add keyword rules --- .../jda/api/entities/automod/AutoModRule.java | 14 ++ .../build/AbstractKeywordRuleBuilder.java | 9 ++ .../build/CustomKeywordRuleBuilder.java | 124 ++++++++++++++++++ .../build/PresetKeywordRuleBuilder.java | 80 +++++++++++ 4 files changed, 227 insertions(+) create mode 100644 src/main/java/net/dv8tion/jda/api/entities/automod/build/CustomKeywordRuleBuilder.java create mode 100644 src/main/java/net/dv8tion/jda/api/entities/automod/build/PresetKeywordRuleBuilder.java diff --git a/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModRule.java b/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModRule.java index 92fba50d2a..39852b867a 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModRule.java +++ b/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModRule.java @@ -19,7 +19,9 @@ import net.dv8tion.jda.api.entities.Guild; import net.dv8tion.jda.api.entities.ISnowflake; import net.dv8tion.jda.api.entities.Role; +import net.dv8tion.jda.api.entities.automod.build.CustomKeywordRuleBuilder; import net.dv8tion.jda.api.entities.automod.build.MentionSpamRuleBuilder; +import net.dv8tion.jda.api.entities.automod.build.PresetKeywordRuleBuilder; import net.dv8tion.jda.api.entities.channel.middleman.GuildChannel; import javax.annotation.Nonnull; @@ -39,6 +41,18 @@ static MentionSpamRuleBuilder createMentionSpamRule(@Nonnull String name, int li return new MentionSpamRuleBuilder(name, limit); } + @Nonnull + static CustomKeywordRuleBuilder createCustomKeywordRule(@Nonnull String name, @Nonnull String... keywords) + { + return new CustomKeywordRuleBuilder(name).addKeywords(keywords); + } + + @Nonnull + static PresetKeywordRuleBuilder createPresetKeywordRule(@Nonnull String name, @Nonnull KeywordPreset... presets) + { + return new PresetKeywordRuleBuilder(name).enablePresets(presets); + } + @Nonnull Guild getGuild(); diff --git a/src/main/java/net/dv8tion/jda/api/entities/automod/build/AbstractKeywordRuleBuilder.java b/src/main/java/net/dv8tion/jda/api/entities/automod/build/AbstractKeywordRuleBuilder.java index f6a26e5405..4cb8f5ac16 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/automod/build/AbstractKeywordRuleBuilder.java +++ b/src/main/java/net/dv8tion/jda/api/entities/automod/build/AbstractKeywordRuleBuilder.java @@ -59,4 +59,13 @@ public B setAllowList(@Nonnull Collection keywords) allowList.addAll(keywords); return (B) this; } + + @Nonnull + @Override + public AutoModRuleData build() + { + AutoModRuleData rule = super.build(); + rule.setAllowlist(allowList); + return rule; + } } diff --git a/src/main/java/net/dv8tion/jda/api/entities/automod/build/CustomKeywordRuleBuilder.java b/src/main/java/net/dv8tion/jda/api/entities/automod/build/CustomKeywordRuleBuilder.java new file mode 100644 index 0000000000..93cac90c6c --- /dev/null +++ b/src/main/java/net/dv8tion/jda/api/entities/automod/build/CustomKeywordRuleBuilder.java @@ -0,0 +1,124 @@ +/* + * Copyright 2015 Austin Keener, Michael Ritter, Florian Spieß, and the JDA contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.dv8tion.jda.api.entities.automod.build; + +import net.dv8tion.jda.api.entities.automod.AutoModEventType; +import net.dv8tion.jda.api.entities.automod.AutoModTriggerType; +import net.dv8tion.jda.internal.utils.Checks; + +import javax.annotation.Nonnull; +import java.util.*; + +public class CustomKeywordRuleBuilder extends AbstractKeywordRuleBuilder +{ + protected final Set keywords = new HashSet<>(); + protected final Set patterns = new HashSet<>(); + + public CustomKeywordRuleBuilder(@Nonnull String name) + { + super(AutoModTriggerType.KEYWORD, AutoModEventType.MESSAGE_SEND, name); + } + + @Nonnull + public CustomKeywordRuleBuilder addKeywords(@Nonnull String... keywords) + { + Checks.noneNull(keywords, "Keywords"); + for (String keyword : keywords) + checkKeyword(keyword); + + Collections.addAll(this.keywords, keywords); + return this; + } + + @Nonnull + public CustomKeywordRuleBuilder addKeywords(@Nonnull Collection keywords) + { + Checks.noneNull(keywords, "Keywords"); + for (String keyword : keywords) + checkKeyword(keyword); + + this.keywords.addAll(keywords); + return this; + } + + @Nonnull + public CustomKeywordRuleBuilder setKeywords(@Nonnull Collection keywords) + { + Checks.noneNull(keywords, "Keywords"); + for (String keyword : keywords) + checkKeyword(keyword); + + this.keywords.clear(); + this.keywords.addAll(keywords); + return this; + } + + + @Nonnull + public CustomKeywordRuleBuilder addPatterns(@Nonnull String... patterns) + { + Checks.noneNull(patterns, "Patterns"); + for (String pattern : patterns) + checkPattern(pattern); + + Collections.addAll(this.patterns, patterns); + return this; + } + + @Nonnull + public CustomKeywordRuleBuilder addPatterns(@Nonnull Collection patterns) + { + Checks.noneNull(patterns, "Patterns"); + for (String pattern : patterns) + checkPattern(pattern); + + this.patterns.addAll(patterns); + return this; + } + + @Nonnull + public CustomKeywordRuleBuilder setPatterns(@Nonnull Collection patterns) + { + Checks.noneNull(patterns, "Patterns"); + for (String pattern : patterns) + checkPattern(pattern); + + this.patterns.clear(); + this.patterns.addAll(patterns); + return this; + } + + protected static void checkKeyword(String keyword) + { + Checks.notEmpty(keyword, "Keyword"); + } + + protected static void checkPattern(String pattern) + { + Checks.notEmpty(pattern, "Pattern"); + } + + @Nonnull + @Override + public AutoModRuleData build() + { + AutoModRuleData rule = super.build(); + rule.setFilteredKeywords(new ArrayList<>(keywords)); + rule.setFilteredRegex(new ArrayList<>(patterns)); + return rule; + } +} diff --git a/src/main/java/net/dv8tion/jda/api/entities/automod/build/PresetKeywordRuleBuilder.java b/src/main/java/net/dv8tion/jda/api/entities/automod/build/PresetKeywordRuleBuilder.java new file mode 100644 index 0000000000..93baf8f07c --- /dev/null +++ b/src/main/java/net/dv8tion/jda/api/entities/automod/build/PresetKeywordRuleBuilder.java @@ -0,0 +1,80 @@ +/* + * Copyright 2015 Austin Keener, Michael Ritter, Florian Spieß, and the JDA contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.dv8tion.jda.api.entities.automod.build; + +import net.dv8tion.jda.api.entities.automod.AutoModEventType; +import net.dv8tion.jda.api.entities.automod.AutoModRule; +import net.dv8tion.jda.api.entities.automod.AutoModTriggerType; +import net.dv8tion.jda.internal.utils.Checks; + +import javax.annotation.Nonnull; +import java.util.Collection; +import java.util.Collections; +import java.util.EnumSet; + +public class PresetKeywordRuleBuilder extends AbstractKeywordRuleBuilder +{ + private final EnumSet presets = EnumSet.noneOf(AutoModRule.KeywordPreset.class); + + public PresetKeywordRuleBuilder(@Nonnull String name) + { + super(AutoModTriggerType.KEYWORD_PRESET, AutoModEventType.MESSAGE_SEND, name); + } + + @Nonnull + public PresetKeywordRuleBuilder enablePresets(@Nonnull AutoModRule.KeywordPreset... presets) + { + Checks.noneNull(presets, "Presets"); + Collections.addAll(this.presets, presets); + return this; + } + + @Nonnull + public PresetKeywordRuleBuilder enablePresets(@Nonnull Collection presets) + { + Checks.noneNull(presets, "Presets"); + this.presets.addAll(presets); + return this; + } + + @Nonnull + public PresetKeywordRuleBuilder disablePresets(@Nonnull AutoModRule.KeywordPreset... presets) + { + Checks.noneNull(presets, "Presets"); + for (AutoModRule.KeywordPreset preset : presets) + this.presets.remove(preset); + return this; + } + + @Nonnull + public PresetKeywordRuleBuilder disablePresets(@Nonnull Collection presets) + { + Checks.noneNull(presets, "Presets"); + this.presets.removeAll(presets); + return this; + } + + @Nonnull + @Override + public AutoModRuleData build() + { + AutoModRuleData rule = super.build(); + presets.remove(AutoModRule.KeywordPreset.UNKNOWN); + rule.setFilteredPresets(presets); + return rule; + } +} From 71c699a1002a49a386a00fdd193c815451960428 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Spie=C3=9F?= Date: Sun, 26 Mar 2023 16:04:11 +0200 Subject: [PATCH 03/39] Add anit-spam rule --- .../jda/api/entities/automod/AutoModRule.java | 7 +++++ .../automod/build/AntiSpamRuleBuilder.java | 30 +++++++++++++++++++ 2 files changed, 37 insertions(+) create mode 100644 src/main/java/net/dv8tion/jda/api/entities/automod/build/AntiSpamRuleBuilder.java diff --git a/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModRule.java b/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModRule.java index 39852b867a..b77e70b077 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModRule.java +++ b/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModRule.java @@ -19,6 +19,7 @@ import net.dv8tion.jda.api.entities.Guild; import net.dv8tion.jda.api.entities.ISnowflake; import net.dv8tion.jda.api.entities.Role; +import net.dv8tion.jda.api.entities.automod.build.AntiSpamRuleBuilder; import net.dv8tion.jda.api.entities.automod.build.CustomKeywordRuleBuilder; import net.dv8tion.jda.api.entities.automod.build.MentionSpamRuleBuilder; import net.dv8tion.jda.api.entities.automod.build.PresetKeywordRuleBuilder; @@ -53,6 +54,12 @@ static PresetKeywordRuleBuilder createPresetKeywordRule(@Nonnull String name, @N return new PresetKeywordRuleBuilder(name).enablePresets(presets); } + @Nonnull + static AntiSpamRuleBuilder createAntiSpamRule(@Nonnull String name) + { + return new AntiSpamRuleBuilder(name); + } + @Nonnull Guild getGuild(); diff --git a/src/main/java/net/dv8tion/jda/api/entities/automod/build/AntiSpamRuleBuilder.java b/src/main/java/net/dv8tion/jda/api/entities/automod/build/AntiSpamRuleBuilder.java new file mode 100644 index 0000000000..e36c0074cd --- /dev/null +++ b/src/main/java/net/dv8tion/jda/api/entities/automod/build/AntiSpamRuleBuilder.java @@ -0,0 +1,30 @@ +/* + * Copyright 2015 Austin Keener, Michael Ritter, Florian Spieß, and the JDA contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.dv8tion.jda.api.entities.automod.build; + +import net.dv8tion.jda.api.entities.automod.AutoModEventType; +import net.dv8tion.jda.api.entities.automod.AutoModTriggerType; + +import javax.annotation.Nonnull; + +public class AntiSpamRuleBuilder extends AbstractAutoModRuleBuilder +{ + public AntiSpamRuleBuilder(@Nonnull String name) + { + super(AutoModTriggerType.SPAM, AutoModEventType.MESSAGE_SEND, name); + } +} From f1dd910be12e2bba848771c632f9371d21b4d5d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Spie=C3=9F?= Date: Sun, 26 Mar 2023 17:22:19 +0200 Subject: [PATCH 04/39] Add some basic checks --- .../jda/api/entities/automod/AutoModRule.java | 9 ++++++--- .../entities/automod/AutoModTriggerType.java | 2 +- .../build/AbstractKeywordRuleBuilder.java | 20 +++++++++++++++---- .../automod/build/AutoModRuleData.java | 2 +- .../build/CustomKeywordRuleBuilder.java | 18 +++++++++++++---- .../automod/build/MentionSpamRuleBuilder.java | 4 +++- .../build/PresetKeywordRuleBuilder.java | 6 ++++++ 7 files changed, 47 insertions(+), 14 deletions(-) diff --git a/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModRule.java b/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModRule.java index b77e70b077..0399e7d7b3 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModRule.java +++ b/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModRule.java @@ -32,9 +32,12 @@ public interface AutoModRule extends ISnowflake { int MAX_KEYWORD_LENGTH = 60; - int MAX_KEYWORD_TOTAL_LENGTH = 1000; - int MAX_ALLOWLIST_TOTAL_LENGTH = 100; - int MAX_ALLOWLIST_PRESET_LENGTH = 1000; + int MAX_KEYWORD_AMOUNT = 1000; + int MAX_ALLOWLIST_CUSTOM_AMOUNT = 100; + int MAX_ALLOWLIST_PRESET_AMOUNT = 1000; + int MAX_PATTERN_LENGTH = 260; + int MAX_PATTERN_AMOUNT = 10; + int MAX_MENTION_LIMIT = 50; @Nonnull static MentionSpamRuleBuilder createMentionSpamRule(@Nonnull String name, int limit) diff --git a/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModTriggerType.java b/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModTriggerType.java index 3f5f15c3f7..27c9f030ba 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModTriggerType.java +++ b/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModTriggerType.java @@ -23,7 +23,7 @@ public enum AutoModTriggerType KEYWORD(1, 6), SPAM(3, 1), KEYWORD_PRESET(4, 1), - MENTION(5, 1), + MENTION_SPAM(5, 1), UNKNOWN(-1, 1), ; diff --git a/src/main/java/net/dv8tion/jda/api/entities/automod/build/AbstractKeywordRuleBuilder.java b/src/main/java/net/dv8tion/jda/api/entities/automod/build/AbstractKeywordRuleBuilder.java index 4cb8f5ac16..16a1e2311c 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/automod/build/AbstractKeywordRuleBuilder.java +++ b/src/main/java/net/dv8tion/jda/api/entities/automod/build/AbstractKeywordRuleBuilder.java @@ -17,14 +17,12 @@ package net.dv8tion.jda.api.entities.automod.build; import net.dv8tion.jda.api.entities.automod.AutoModEventType; +import net.dv8tion.jda.api.entities.automod.AutoModRule; import net.dv8tion.jda.api.entities.automod.AutoModTriggerType; import net.dv8tion.jda.internal.utils.Checks; import javax.annotation.Nonnull; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.List; +import java.util.*; public abstract class AbstractKeywordRuleBuilder> extends AbstractAutoModRuleBuilder { @@ -39,6 +37,8 @@ protected AbstractKeywordRuleBuilder(AutoModTriggerType triggerType, AutoModEven public B addAllowList(@Nonnull String... keywords) { Checks.noneNull(keywords, "Keywords"); + Checks.check(this.allowList.size() + keywords.length <= maxAllowListAmount(), "Cannot add more than %d keywords!", maxAllowListAmount()); + Arrays.stream(keywords).forEach(AbstractKeywordRuleBuilder::checkKeyword); Collections.addAll(allowList, keywords); return (B) this; } @@ -47,6 +47,8 @@ public B addAllowList(@Nonnull String... keywords) public B addAllowList(@Nonnull Collection keywords) { Checks.noneNull(keywords, "Keywords"); + Checks.check(this.allowList.size() + keywords.size() <= maxAllowListAmount(), "Cannot add more than %d keywords!", maxAllowListAmount()); + keywords.forEach(AbstractKeywordRuleBuilder::checkKeyword); allowList.addAll(keywords); return (B) this; } @@ -55,11 +57,21 @@ public B addAllowList(@Nonnull Collection keywords) public B setAllowList(@Nonnull Collection keywords) { Checks.noneNull(keywords, "Keywords"); + Checks.check(keywords.size() <= maxAllowListAmount(), "Cannot add more than %d keywords!", maxAllowListAmount()); + keywords.forEach(AbstractKeywordRuleBuilder::checkKeyword); allowList.clear(); allowList.addAll(keywords); return (B) this; } + protected abstract int maxAllowListAmount(); + + protected static void checkKeyword(String keyword) + { + Checks.notEmpty(keyword, "Keyword"); + Checks.notLonger(keyword, AutoModRule.MAX_KEYWORD_LENGTH, "Keyword"); + } + @Nonnull @Override public AutoModRuleData build() diff --git a/src/main/java/net/dv8tion/jda/api/entities/automod/build/AutoModRuleData.java b/src/main/java/net/dv8tion/jda/api/entities/automod/build/AutoModRuleData.java index 6114711062..a1b117dea0 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/automod/build/AutoModRuleData.java +++ b/src/main/java/net/dv8tion/jda/api/entities/automod/build/AutoModRuleData.java @@ -149,7 +149,7 @@ public DataObject toData() switch (triggerType) { - case MENTION: + case MENTION_SPAM: if (mentionLimit != -1) metadata.put("mention_total_limit", mentionLimit); break; diff --git a/src/main/java/net/dv8tion/jda/api/entities/automod/build/CustomKeywordRuleBuilder.java b/src/main/java/net/dv8tion/jda/api/entities/automod/build/CustomKeywordRuleBuilder.java index 93cac90c6c..43e63c656d 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/automod/build/CustomKeywordRuleBuilder.java +++ b/src/main/java/net/dv8tion/jda/api/entities/automod/build/CustomKeywordRuleBuilder.java @@ -17,6 +17,7 @@ package net.dv8tion.jda.api.entities.automod.build; import net.dv8tion.jda.api.entities.automod.AutoModEventType; +import net.dv8tion.jda.api.entities.automod.AutoModRule; import net.dv8tion.jda.api.entities.automod.AutoModTriggerType; import net.dv8tion.jda.internal.utils.Checks; @@ -37,6 +38,7 @@ public CustomKeywordRuleBuilder(@Nonnull String name) public CustomKeywordRuleBuilder addKeywords(@Nonnull String... keywords) { Checks.noneNull(keywords, "Keywords"); + Checks.check(this.keywords.size() + keywords.length <= AutoModRule.MAX_KEYWORD_AMOUNT, "Cannot add more than %d keywords!", AutoModRule.MAX_KEYWORD_AMOUNT); for (String keyword : keywords) checkKeyword(keyword); @@ -48,6 +50,7 @@ public CustomKeywordRuleBuilder addKeywords(@Nonnull String... keywords) public CustomKeywordRuleBuilder addKeywords(@Nonnull Collection keywords) { Checks.noneNull(keywords, "Keywords"); + Checks.check(this.keywords.size() + keywords.size() <= AutoModRule.MAX_KEYWORD_AMOUNT, "Cannot add more than %d keywords!", AutoModRule.MAX_KEYWORD_AMOUNT); for (String keyword : keywords) checkKeyword(keyword); @@ -59,6 +62,7 @@ public CustomKeywordRuleBuilder addKeywords(@Nonnull Collection keywords public CustomKeywordRuleBuilder setKeywords(@Nonnull Collection keywords) { Checks.noneNull(keywords, "Keywords"); + Checks.check(keywords.size() <= AutoModRule.MAX_KEYWORD_AMOUNT, "Cannot add more than %d keywords!", AutoModRule.MAX_KEYWORD_AMOUNT); for (String keyword : keywords) checkKeyword(keyword); @@ -72,6 +76,7 @@ public CustomKeywordRuleBuilder setKeywords(@Nonnull Collection keywords public CustomKeywordRuleBuilder addPatterns(@Nonnull String... patterns) { Checks.noneNull(patterns, "Patterns"); + Checks.check(this.patterns.size() + patterns.length <= AutoModRule.MAX_PATTERN_AMOUNT, "Cannot add more than %d patterns!", AutoModRule.MAX_PATTERN_AMOUNT); for (String pattern : patterns) checkPattern(pattern); @@ -83,6 +88,7 @@ public CustomKeywordRuleBuilder addPatterns(@Nonnull String... patterns) public CustomKeywordRuleBuilder addPatterns(@Nonnull Collection patterns) { Checks.noneNull(patterns, "Patterns"); + Checks.check(this.patterns.size() + patterns.size() <= AutoModRule.MAX_PATTERN_AMOUNT, "Cannot add more than %d patterns!", AutoModRule.MAX_PATTERN_AMOUNT); for (String pattern : patterns) checkPattern(pattern); @@ -94,6 +100,7 @@ public CustomKeywordRuleBuilder addPatterns(@Nonnull Collection patterns public CustomKeywordRuleBuilder setPatterns(@Nonnull Collection patterns) { Checks.noneNull(patterns, "Patterns"); + Checks.check(patterns.size() <= AutoModRule.MAX_PATTERN_AMOUNT, "Cannot add more than %d patterns!", AutoModRule.MAX_PATTERN_AMOUNT); for (String pattern : patterns) checkPattern(pattern); @@ -102,20 +109,23 @@ public CustomKeywordRuleBuilder setPatterns(@Nonnull Collection patterns return this; } - protected static void checkKeyword(String keyword) + protected static void checkPattern(String pattern) { - Checks.notEmpty(keyword, "Keyword"); + Checks.notEmpty(pattern, "Pattern"); + Checks.notLonger(pattern, AutoModRule.MAX_PATTERN_LENGTH, "Pattern"); } - protected static void checkPattern(String pattern) + @Override + protected int maxAllowListAmount() { - Checks.notEmpty(pattern, "Pattern"); + return AutoModRule.MAX_ALLOWLIST_CUSTOM_AMOUNT; } @Nonnull @Override public AutoModRuleData build() { + Checks.check(!keywords.isEmpty() || !patterns.isEmpty(), "Must have at least one keyword or pattern!"); AutoModRuleData rule = super.build(); rule.setFilteredKeywords(new ArrayList<>(keywords)); rule.setFilteredRegex(new ArrayList<>(patterns)); diff --git a/src/main/java/net/dv8tion/jda/api/entities/automod/build/MentionSpamRuleBuilder.java b/src/main/java/net/dv8tion/jda/api/entities/automod/build/MentionSpamRuleBuilder.java index 807fba103c..8e0dfa01e0 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/automod/build/MentionSpamRuleBuilder.java +++ b/src/main/java/net/dv8tion/jda/api/entities/automod/build/MentionSpamRuleBuilder.java @@ -17,6 +17,7 @@ package net.dv8tion.jda.api.entities.automod.build; import net.dv8tion.jda.api.entities.automod.AutoModEventType; +import net.dv8tion.jda.api.entities.automod.AutoModRule; import net.dv8tion.jda.api.entities.automod.AutoModTriggerType; import net.dv8tion.jda.internal.utils.Checks; @@ -28,7 +29,7 @@ public class MentionSpamRuleBuilder extends AbstractAutoModRuleBuilder Date: Sun, 26 Mar 2023 19:36:46 +0200 Subject: [PATCH 05/39] Add some docs for factory methods --- .../jda/api/entities/automod/AutoModRule.java | 140 +++++++++++++++++- .../build/AbstractAutoModRuleBuilder.java | 2 + 2 files changed, 138 insertions(+), 4 deletions(-) diff --git a/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModRule.java b/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModRule.java index 0399e7d7b3..cbe066cb34 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModRule.java +++ b/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModRule.java @@ -19,44 +19,176 @@ import net.dv8tion.jda.api.entities.Guild; import net.dv8tion.jda.api.entities.ISnowflake; import net.dv8tion.jda.api.entities.Role; -import net.dv8tion.jda.api.entities.automod.build.AntiSpamRuleBuilder; -import net.dv8tion.jda.api.entities.automod.build.CustomKeywordRuleBuilder; -import net.dv8tion.jda.api.entities.automod.build.MentionSpamRuleBuilder; -import net.dv8tion.jda.api.entities.automod.build.PresetKeywordRuleBuilder; +import net.dv8tion.jda.api.entities.automod.build.*; import net.dv8tion.jda.api.entities.channel.middleman.GuildChannel; import javax.annotation.Nonnull; +import java.util.Collection; import java.util.EnumSet; import java.util.List; +/** + * Rule used for auto-moderation in a {@link Guild}. + * + * @see Guild#retrieveAutoModRules() + * @see Guild#createAutoModRule(AutoModRuleData) + */ public interface AutoModRule extends ISnowflake { + /** + * The maximum length of a rule name. ({@value}) + */ + int MAX_RULE_NAME_LENGTH = 100; + /** + * The maximum length of a keyword in {@link #createCustomKeywordRule(String, String...)}. ({@value}) + */ int MAX_KEYWORD_LENGTH = 60; + /** + * The maximum amount of keywords in {@link #createCustomKeywordRule(String, String...)}. ({@value}) + */ int MAX_KEYWORD_AMOUNT = 1000; + /** + * The maximum amount of whitelisted keywords in {@link #createCustomKeywordRule(String, String...)}. ({@value}) + */ int MAX_ALLOWLIST_CUSTOM_AMOUNT = 100; + /** + * The maximum amount of whitelisted keywords in {@link #createPresetKeywordRule(String, KeywordPreset...)}. ({@value}) + */ int MAX_ALLOWLIST_PRESET_AMOUNT = 1000; + /** + * The maximum length of a regex pattern in {@link #createCustomKeywordRule(String, String...)}. ({@value}) + */ int MAX_PATTERN_LENGTH = 260; + /** + * The maximum amount of regex patterns in {@link #createCustomKeywordRule(String, String...)}. ({@value}) + */ int MAX_PATTERN_AMOUNT = 10; + /** + * The maximum limit of mentions in {@link #createMentionSpamRule(String, int)}. ({@value}) + */ int MAX_MENTION_LIMIT = 50; + /** + * Creates a {@link AutoModTriggerType#MENTION_SPAM MENTION_SPAM} rule. + * + *

Every automod rule must have at least one {@link AutoModResponse} configured. + * + *

Example
+ *

{@code
+     * AutoModRule.createMentionSpamRule("Mention Spam", 10)
+     *     .putResponse(AutoModResponse.blockMessage("Don't spam mentions!"))
+     *     .addExemptRoles(modRole)
+     *     .build()
+     * }
+ * + * @param name + * The name of the rule (max {@value #MAX_RULE_NAME_LENGTH} characters) + * @param limit + * The maximum amount of mentions allowed (up to {@value #MAX_MENTION_LIMIT}) + * + * @throws java.lang.IllegalArgumentException + *
    + *
  • If the name is null, empty, or longer than {@value #MAX_RULE_NAME_LENGTH} characters.
  • + *
  • If the limit is not between 1 and {@value #MAX_MENTION_LIMIT}
  • + *
+ * + * @return {@link MentionSpamRuleBuilder} instance to build the rule + */ @Nonnull static MentionSpamRuleBuilder createMentionSpamRule(@Nonnull String name, int limit) { return new MentionSpamRuleBuilder(name, limit); } + /** + * Creates a {@link AutoModTriggerType#KEYWORD KEYWORD} rule. + *
Keywords may also use wildcards at the beginning and end of the keyword (for example {@code "foo*"} would match {@code "foobar"}). + * Keywords can also contain whitespace to block phrases like {@code "foo bar"}. Additionally, keywords are case-insensitive. + * + *

Every automod rule must have at least one {@link AutoModResponse} configured. + * + *

Example
+ *

{@code
+     * AutoModRule.createCustomKeywordRule("No morbius memes", "morb*", "*morb")
+     *     .putResponse(AutoModResponse.blockMessage("This is not a funny meme."))
+     *     .build()
+     * }
+ * + * @param name + * The name of the rule (max {@value #MAX_RULE_NAME_LENGTH} characters) + * @param keywords + * The blocked keywords (max {@value #MAX_KEYWORD_AMOUNT} keywords, max {@value #MAX_KEYWORD_LENGTH} characters per keyword) + * + * @throws java.lang.IllegalArgumentException + *
    + *
  • If the name is null, empty, or longer than {@value #MAX_RULE_NAME_LENGTH} characters.
  • + *
  • If any keyword is empty or longer than {@value #MAX_KEYWORD_LENGTH}
  • + *
  • If more than {@value #MAX_KEYWORD_AMOUNT} keywords are provided
  • + *
+ * + * @return {@link CustomKeywordRuleBuilder} instance to build the rule + */ @Nonnull static CustomKeywordRuleBuilder createCustomKeywordRule(@Nonnull String name, @Nonnull String... keywords) { return new CustomKeywordRuleBuilder(name).addKeywords(keywords); } + /** + * Creates a {@link AutoModTriggerType#KEYWORD_PRESET KEYWORD_PRESET} rule. + *
In the {@link PresetKeywordRuleBuilder#setAllowList(Collection) allowlist}, + * keywords may also use wildcards at the beginning and end of the keyword (for example {@code "foo*"} would match {@code "foobar"}). + * Keywords can also contain whitespace to block phrases like {@code "foo bar"}. Additionally, keywords are case-insensitive. + * + *

Every automod rule must have at least one {@link AutoModResponse} configured. + * + *

Example
+ *

{@code
+     * AutoModRule.createPresetKeywordRule("No slurs", KeywordPreset.SLURS)
+     *     .putResponse(AutoModResponse.blockMessage("Please refrain from using this kind of language."))
+     *     .build()
+     * }
+ * + * @param name + * The name of the rule (max {@value #MAX_RULE_NAME_LENGTH} characters) + * @param presets + * Preset lists of keywords to block. (Should be at least 1 preset) + * + * @throws java.lang.IllegalArgumentException + *
    + *
  • If the name is null, empty, or longer than {@value #MAX_RULE_NAME_LENGTH} characters.
  • + *
  • If null is provided
  • + *
+ * + * @return {@link PresetKeywordRuleBuilder} instance to build the rule + */ @Nonnull static PresetKeywordRuleBuilder createPresetKeywordRule(@Nonnull String name, @Nonnull KeywordPreset... presets) { return new PresetKeywordRuleBuilder(name).enablePresets(presets); } + /** + * Creates a {@link AutoModTriggerType#SPAM SPAM} rule. + * + *

Every automod rule must have at least one {@link AutoModResponse} configured. + * + *

Example
+ *

{@code
+     * AutoModRule.createAntiSpamRule("Spam detected")
+     *     .putResponse(AutoModResponse.timeoutMember(Duration.ofMinutes(1))
+     *     .addExemptRoles(modRole)
+     *     .build()
+     * }
+ * + * @param name + * The name of the rule (max {@value #MAX_RULE_NAME_LENGTH} characters) + * + * @throws java.lang.IllegalArgumentException + * If the name is null, empty, or longer than {@value #MAX_RULE_NAME_LENGTH} characters. + * + * @return {@link AntiSpamRuleBuilder} instance to build the rule + */ @Nonnull static AntiSpamRuleBuilder createAntiSpamRule(@Nonnull String name) { diff --git a/src/main/java/net/dv8tion/jda/api/entities/automod/build/AbstractAutoModRuleBuilder.java b/src/main/java/net/dv8tion/jda/api/entities/automod/build/AbstractAutoModRuleBuilder.java index 0a0607e8f9..855b919034 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/automod/build/AbstractAutoModRuleBuilder.java +++ b/src/main/java/net/dv8tion/jda/api/entities/automod/build/AbstractAutoModRuleBuilder.java @@ -21,6 +21,7 @@ import net.dv8tion.jda.api.entities.Role; import net.dv8tion.jda.api.entities.automod.AutoModEventType; import net.dv8tion.jda.api.entities.automod.AutoModResponse; +import net.dv8tion.jda.api.entities.automod.AutoModRule; import net.dv8tion.jda.api.entities.automod.AutoModTriggerType; import net.dv8tion.jda.api.entities.channel.middleman.GuildChannel; import net.dv8tion.jda.internal.utils.Checks; @@ -54,6 +55,7 @@ protected AbstractAutoModRuleBuilder(AutoModTriggerType triggerType, AutoModEven public B setName(@Nonnull String name) { Checks.notEmpty(name, "Name"); + Checks.notLonger(name, AutoModRule.MAX_RULE_NAME_LENGTH, "Name"); this.name = name; return (B) this; } From e0c652bd149a31bbe9cc74627f977c194b96564c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Spie=C3=9F?= Date: Sun, 26 Mar 2023 22:02:26 +0200 Subject: [PATCH 06/39] Add new intents --- .../dv8tion/jda/api/requests/GatewayIntent.java | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/main/java/net/dv8tion/jda/api/requests/GatewayIntent.java b/src/main/java/net/dv8tion/jda/api/requests/GatewayIntent.java index 51db8d7722..dbca752af8 100644 --- a/src/main/java/net/dv8tion/jda/api/requests/GatewayIntent.java +++ b/src/main/java/net/dv8tion/jda/api/requests/GatewayIntent.java @@ -67,6 +67,10 @@ *
  • DIRECT_MESSAGES - This is used to receive incoming messages in private channels (DMs). You can still send private messages without this intent.
  • *
  • DIRECT_MESSAGE_REACTIONS - This is used to track reactions on messages in private channels (DMs).
  • *
  • DIRECT_MESSAGE_TYPING - This is used to track when a user starts typing in private channels (DMs). Almost no bot will have a use for this.
  • + *
  • MESSAGE_CONTENT - This is a privileged gateway intent this is only used to enable access to the user content in messages (also including embeds/attachments/components).
  • + *
  • SCHEDULED_EVENTS - This is used to keep track of scheduled events in guilds.
  • + *
  • AUTO_MODERATION_CONFIGURATION - This is used to keep track of auto-mod rule changes in guilds.
  • + *
  • AUTO_MODERATION_EXECUTION - This is used to receive events related to auto-mod response actions.
  • * * * If an intent is not specifically mentioned to be privileged, it is not required to be on the whitelist to use it (and its related events). @@ -177,7 +181,17 @@ public enum GatewayIntent * Scheduled Events events. */ SCHEDULED_EVENTS(16), - + + /** + * Events related to {@link net.dv8tion.jda.api.entities.automod.AutoModRule AutoModRule} changes. + */ + AUTO_MODERATION_CONFIGURATION(20), + + /** + * Events related to {@link net.dv8tion.jda.api.entities.automod.AutoModResponse AutoModResponse} triggers. + */ + AUTO_MODERATION_EXECUTION(21), + ; /** From 6b528b9bb00084a3107d93c53440ac630f856575 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Spie=C3=9F?= Date: Sun, 26 Mar 2023 22:41:12 +0200 Subject: [PATCH 07/39] Add events --- .../entities/automod/AutoModExecution.java | 81 +++++++++++ .../events/automod/AutoModExecutionEvent.java | 112 +++++++++++++++ .../automod/AutoModRuleCreateEvent.java | 30 ++++ .../automod/AutoModRuleDeleteEvent.java | 30 ++++ .../automod/AutoModRuleUpdateEvent.java | 30 ++++ .../automod/GenericAutoModRuleEvent.java | 40 ++++++ .../jda/api/hooks/ListenerAdapter.java | 10 ++ .../automod/AutoModExecutionImpl.java | 129 ++++++++++++++++++ .../handle/AutoModExecutionHandler.java | 51 +++++++ .../internal/handle/AutoModRuleHandler.java | 76 +++++++++++ .../internal/requests/WebSocketClient.java | 4 + 11 files changed, 593 insertions(+) create mode 100644 src/main/java/net/dv8tion/jda/api/entities/automod/AutoModExecution.java create mode 100644 src/main/java/net/dv8tion/jda/api/events/automod/AutoModExecutionEvent.java create mode 100644 src/main/java/net/dv8tion/jda/api/events/automod/AutoModRuleCreateEvent.java create mode 100644 src/main/java/net/dv8tion/jda/api/events/automod/AutoModRuleDeleteEvent.java create mode 100644 src/main/java/net/dv8tion/jda/api/events/automod/AutoModRuleUpdateEvent.java create mode 100644 src/main/java/net/dv8tion/jda/api/events/automod/GenericAutoModRuleEvent.java create mode 100644 src/main/java/net/dv8tion/jda/internal/entities/automod/AutoModExecutionImpl.java create mode 100644 src/main/java/net/dv8tion/jda/internal/handle/AutoModExecutionHandler.java create mode 100644 src/main/java/net/dv8tion/jda/internal/handle/AutoModRuleHandler.java diff --git a/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModExecution.java b/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModExecution.java new file mode 100644 index 0000000000..8bc6fb24fc --- /dev/null +++ b/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModExecution.java @@ -0,0 +1,81 @@ +/* + * Copyright 2015 Austin Keener, Michael Ritter, Florian Spieß, and the JDA contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.dv8tion.jda.api.entities.automod; + +import net.dv8tion.jda.api.entities.Guild; +import net.dv8tion.jda.api.entities.channel.unions.GuildMessageChannelUnion; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +public interface AutoModExecution +{ + @Nonnull + Guild getGuild(); + + @Nonnull + GuildMessageChannelUnion getChannel(); + + @Nonnull + AutoModResponse getResponse(); + + @Nonnull + AutoModTriggerType getTriggerType(); + + long getUserIdLong(); + + @Nonnull + default String getUserId() + { + return Long.toUnsignedString(getUserIdLong()); + } + + long getRuleIdLong(); + + @Nonnull + default String getRuleId() + { + return Long.toUnsignedString(getRuleIdLong()); + } + + long getMessageIdLong(); + + @Nullable + default String getMessageId() + { + long id = getMessageIdLong(); + return id == 0L ? null : Long.toUnsignedString(getMessageIdLong()); + } + + long getAlertMessageIdLong(); + + @Nullable + default String getAlertMessageId() + { + long id = getAlertMessageIdLong(); + return id == 0L ? null : Long.toUnsignedString(getAlertMessageIdLong()); + } + + @Nonnull + String getContent(); + + @Nullable + String getMatchedContent(); + + @Nullable + String getMatchedKeyword(); +} diff --git a/src/main/java/net/dv8tion/jda/api/events/automod/AutoModExecutionEvent.java b/src/main/java/net/dv8tion/jda/api/events/automod/AutoModExecutionEvent.java new file mode 100644 index 0000000000..6a7f7b731f --- /dev/null +++ b/src/main/java/net/dv8tion/jda/api/events/automod/AutoModExecutionEvent.java @@ -0,0 +1,112 @@ +/* + * Copyright 2015 Austin Keener, Michael Ritter, Florian Spieß, and the JDA contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.dv8tion.jda.api.events.automod; + +import net.dv8tion.jda.api.JDA; +import net.dv8tion.jda.api.entities.Guild; +import net.dv8tion.jda.api.entities.automod.AutoModExecution; +import net.dv8tion.jda.api.entities.automod.AutoModResponse; +import net.dv8tion.jda.api.entities.automod.AutoModTriggerType; +import net.dv8tion.jda.api.entities.channel.unions.GuildMessageChannelUnion; +import net.dv8tion.jda.api.events.Event; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +public class AutoModExecutionEvent extends Event implements AutoModExecution +{ + private final AutoModExecution execution; + + public AutoModExecutionEvent(@Nonnull JDA api, long responseNumber, @Nonnull AutoModExecution execution) + { + super(api, responseNumber); + this.execution = execution; + } + + @Nonnull + @Override + public Guild getGuild() + { + return execution.getGuild(); + } + + @Nonnull + @Override + public GuildMessageChannelUnion getChannel() + { + return execution.getChannel(); + } + + @Nonnull + @Override + public AutoModResponse getResponse() + { + return execution.getResponse(); + } + + @Nonnull + @Override + public AutoModTriggerType getTriggerType() + { + return execution.getTriggerType(); + } + + @Override + public long getUserIdLong() + { + return execution.getUserIdLong(); + } + + @Override + public long getRuleIdLong() + { + return execution.getRuleIdLong(); + } + + @Override + public long getMessageIdLong() + { + return execution.getMessageIdLong(); + } + + @Override + public long getAlertMessageIdLong() + { + return execution.getAlertMessageIdLong(); + } + + @Nonnull + @Override + public String getContent() + { + return execution.getContent(); + } + + @Nullable + @Override + public String getMatchedContent() + { + return execution.getMatchedContent(); + } + + @Nullable + @Override + public String getMatchedKeyword() + { + return execution.getMatchedKeyword(); + } +} diff --git a/src/main/java/net/dv8tion/jda/api/events/automod/AutoModRuleCreateEvent.java b/src/main/java/net/dv8tion/jda/api/events/automod/AutoModRuleCreateEvent.java new file mode 100644 index 0000000000..08a8c10a27 --- /dev/null +++ b/src/main/java/net/dv8tion/jda/api/events/automod/AutoModRuleCreateEvent.java @@ -0,0 +1,30 @@ +/* + * Copyright 2015 Austin Keener, Michael Ritter, Florian Spieß, and the JDA contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.dv8tion.jda.api.events.automod; + +import net.dv8tion.jda.api.JDA; +import net.dv8tion.jda.api.entities.automod.AutoModRule; + +import javax.annotation.Nonnull; + +public class AutoModRuleCreateEvent extends GenericAutoModRuleEvent +{ + public AutoModRuleCreateEvent(@Nonnull JDA api, long responseNumber, @Nonnull AutoModRule rule) + { + super(api, responseNumber, rule); + } +} diff --git a/src/main/java/net/dv8tion/jda/api/events/automod/AutoModRuleDeleteEvent.java b/src/main/java/net/dv8tion/jda/api/events/automod/AutoModRuleDeleteEvent.java new file mode 100644 index 0000000000..9374bcda6d --- /dev/null +++ b/src/main/java/net/dv8tion/jda/api/events/automod/AutoModRuleDeleteEvent.java @@ -0,0 +1,30 @@ +/* + * Copyright 2015 Austin Keener, Michael Ritter, Florian Spieß, and the JDA contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.dv8tion.jda.api.events.automod; + +import net.dv8tion.jda.api.JDA; +import net.dv8tion.jda.api.entities.automod.AutoModRule; + +import javax.annotation.Nonnull; + +public class AutoModRuleDeleteEvent extends GenericAutoModRuleEvent +{ + public AutoModRuleDeleteEvent(@Nonnull JDA api, long responseNumber, @Nonnull AutoModRule rule) + { + super(api, responseNumber, rule); + } +} diff --git a/src/main/java/net/dv8tion/jda/api/events/automod/AutoModRuleUpdateEvent.java b/src/main/java/net/dv8tion/jda/api/events/automod/AutoModRuleUpdateEvent.java new file mode 100644 index 0000000000..025089e0ed --- /dev/null +++ b/src/main/java/net/dv8tion/jda/api/events/automod/AutoModRuleUpdateEvent.java @@ -0,0 +1,30 @@ +/* + * Copyright 2015 Austin Keener, Michael Ritter, Florian Spieß, and the JDA contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.dv8tion.jda.api.events.automod; + +import net.dv8tion.jda.api.JDA; +import net.dv8tion.jda.api.entities.automod.AutoModRule; + +import javax.annotation.Nonnull; + +public class AutoModRuleUpdateEvent extends GenericAutoModRuleEvent +{ + public AutoModRuleUpdateEvent(@Nonnull JDA api, long responseNumber, @Nonnull AutoModRule rule) + { + super(api, responseNumber, rule); + } +} diff --git a/src/main/java/net/dv8tion/jda/api/events/automod/GenericAutoModRuleEvent.java b/src/main/java/net/dv8tion/jda/api/events/automod/GenericAutoModRuleEvent.java new file mode 100644 index 0000000000..02affa39b9 --- /dev/null +++ b/src/main/java/net/dv8tion/jda/api/events/automod/GenericAutoModRuleEvent.java @@ -0,0 +1,40 @@ +/* + * Copyright 2015 Austin Keener, Michael Ritter, Florian Spieß, and the JDA contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.dv8tion.jda.api.events.automod; + +import net.dv8tion.jda.api.JDA; +import net.dv8tion.jda.api.entities.automod.AutoModRule; +import net.dv8tion.jda.api.events.Event; + +import javax.annotation.Nonnull; + +public class GenericAutoModRuleEvent extends Event +{ + private final AutoModRule rule; + + public GenericAutoModRuleEvent(@Nonnull JDA api, long responseNumber, @Nonnull AutoModRule rule) + { + super(api, responseNumber); + this.rule = rule; + } + + @Nonnull + public AutoModRule getRule() + { + return rule; + } +} diff --git a/src/main/java/net/dv8tion/jda/api/hooks/ListenerAdapter.java b/src/main/java/net/dv8tion/jda/api/hooks/ListenerAdapter.java index 0a9e5a3186..979f30468f 100644 --- a/src/main/java/net/dv8tion/jda/api/hooks/ListenerAdapter.java +++ b/src/main/java/net/dv8tion/jda/api/hooks/ListenerAdapter.java @@ -16,6 +16,10 @@ package net.dv8tion.jda.api.hooks; import net.dv8tion.jda.api.events.*; +import net.dv8tion.jda.api.events.automod.AutoModExecutionEvent; +import net.dv8tion.jda.api.events.automod.AutoModRuleCreateEvent; +import net.dv8tion.jda.api.events.automod.AutoModRuleDeleteEvent; +import net.dv8tion.jda.api.events.automod.AutoModRuleUpdateEvent; import net.dv8tion.jda.api.events.channel.ChannelCreateEvent; import net.dv8tion.jda.api.events.channel.ChannelDeleteEvent; import net.dv8tion.jda.api.events.channel.GenericChannelEvent; @@ -314,6 +318,12 @@ public void onGuildVoiceStream(@Nonnull GuildVoiceStreamEvent event) {} public void onGuildVoiceVideo(@Nonnull GuildVoiceVideoEvent event) {} public void onGuildVoiceRequestToSpeak(@Nonnull GuildVoiceRequestToSpeakEvent event) {} + //Guild AutoMod Events + public void onAutoModExecution(@Nonnull AutoModExecutionEvent event) {} + public void onAutoModRuleCreate(@Nonnull AutoModRuleCreateEvent event) {} + public void onAutoModRuleUpdate(@Nonnull AutoModRuleUpdateEvent event) {} + public void onAutoModRuleDelete(@Nonnull AutoModRuleDeleteEvent event) {} + //Role events public void onRoleCreate(@Nonnull RoleCreateEvent event) {} public void onRoleDelete(@Nonnull RoleDeleteEvent event) {} diff --git a/src/main/java/net/dv8tion/jda/internal/entities/automod/AutoModExecutionImpl.java b/src/main/java/net/dv8tion/jda/internal/entities/automod/AutoModExecutionImpl.java new file mode 100644 index 0000000000..60b1887688 --- /dev/null +++ b/src/main/java/net/dv8tion/jda/internal/entities/automod/AutoModExecutionImpl.java @@ -0,0 +1,129 @@ +/* + * Copyright 2015 Austin Keener, Michael Ritter, Florian Spieß, and the JDA contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.dv8tion.jda.internal.entities.automod; + +import net.dv8tion.jda.api.entities.Guild; +import net.dv8tion.jda.api.entities.automod.AutoModExecution; +import net.dv8tion.jda.api.entities.automod.AutoModResponse; +import net.dv8tion.jda.api.entities.automod.AutoModTriggerType; +import net.dv8tion.jda.api.entities.channel.middleman.GuildMessageChannel; +import net.dv8tion.jda.api.entities.channel.unions.GuildMessageChannelUnion; +import net.dv8tion.jda.api.utils.data.DataObject; +import net.dv8tion.jda.internal.entities.EntityBuilder; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +public class AutoModExecutionImpl implements AutoModExecution +{ + private final Guild guild; + private final GuildMessageChannel channel; + private final AutoModResponse response; + private final AutoModTriggerType type; + private final long userId, ruleId, messageId, alertMessageId; + private final String content, matchedContent, matchedKeyword; + + public AutoModExecutionImpl(Guild guild, DataObject json) + { + this.guild = guild; + this.channel = guild.getChannelById(GuildMessageChannel.class, json.getUnsignedLong("channel_id")); + if (this.channel == null) + throw new IllegalStateException(EntityBuilder.MISSING_CHANNEL); + this.response = new AutoModResponseImpl(guild, json.getObject("action")); + this.type = AutoModTriggerType.fromKey(json.getInt("trigger_type", -1)); + this.userId = json.getUnsignedLong("user_id"); + this.ruleId = json.getUnsignedLong("rule_id"); + this.messageId = json.getUnsignedLong("message_id", 0L); + this.alertMessageId = json.getUnsignedLong("alert_message_id", 0L); + this.content = json.getString("content", ""); + this.matchedContent = json.getString("matched_content", null); + this.matchedKeyword = json.getString("matched_keyword", null); + } + + @Nonnull + @Override + public Guild getGuild() + { + return guild; + } + + @Nonnull + @Override + public GuildMessageChannelUnion getChannel() + { + return (GuildMessageChannelUnion) channel; + } + + @Nonnull + @Override + public AutoModResponse getResponse() + { + return response; + } + + @Nonnull + @Override + public AutoModTriggerType getTriggerType() + { + return type; + } + + @Override + public long getUserIdLong() + { + return userId; + } + + @Override + public long getRuleIdLong() + { + return ruleId; + } + + @Override + public long getMessageIdLong() + { + return messageId; + } + + @Override + public long getAlertMessageIdLong() + { + return alertMessageId; + } + + @Nonnull + @Override + public String getContent() + { + return content; + } + + @Nullable + @Override + public String getMatchedContent() + { + return matchedContent; + } + + @Nullable + @Override + public String getMatchedKeyword() + { + return matchedKeyword; + } +} diff --git a/src/main/java/net/dv8tion/jda/internal/handle/AutoModExecutionHandler.java b/src/main/java/net/dv8tion/jda/internal/handle/AutoModExecutionHandler.java new file mode 100644 index 0000000000..7d9215813e --- /dev/null +++ b/src/main/java/net/dv8tion/jda/internal/handle/AutoModExecutionHandler.java @@ -0,0 +1,51 @@ +/* + * Copyright 2015 Austin Keener, Michael Ritter, Florian Spieß, and the JDA contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.dv8tion.jda.internal.handle; + +import net.dv8tion.jda.api.entities.Guild; +import net.dv8tion.jda.api.events.automod.AutoModExecutionEvent; +import net.dv8tion.jda.api.utils.data.DataObject; +import net.dv8tion.jda.internal.JDAImpl; +import net.dv8tion.jda.internal.entities.automod.AutoModExecutionImpl; + +public class AutoModExecutionHandler extends SocketHandler +{ + public AutoModExecutionHandler(JDAImpl api) + { + super(api); + } + + @Override + protected Long handleInternally(DataObject content) + { + long guildId = content.getLong("guild_id"); + Guild guild = api.getGuildById(guildId); + if (guild == null) + { + api.getEventCache().cache(EventCache.Type.GUILD, guildId, responseNumber, allContent, this::handle); + EventCache.LOG.debug("Received a AUTO_MODERATION_ACTION_EXECUTION for a guild that is not yet cached. JSON: {}", content); + return null; + } + + AutoModExecutionImpl execution = new AutoModExecutionImpl(guild, content); + api.getEventManager().handle( + new AutoModExecutionEvent( + api, responseNumber, + execution)); + return null; + } +} diff --git a/src/main/java/net/dv8tion/jda/internal/handle/AutoModRuleHandler.java b/src/main/java/net/dv8tion/jda/internal/handle/AutoModRuleHandler.java new file mode 100644 index 0000000000..3d3f03adb2 --- /dev/null +++ b/src/main/java/net/dv8tion/jda/internal/handle/AutoModRuleHandler.java @@ -0,0 +1,76 @@ +/* + * Copyright 2015 Austin Keener, Michael Ritter, Florian Spieß, and the JDA contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.dv8tion.jda.internal.handle; + +import net.dv8tion.jda.api.entities.Guild; +import net.dv8tion.jda.api.entities.automod.AutoModRule; +import net.dv8tion.jda.api.events.automod.AutoModRuleCreateEvent; +import net.dv8tion.jda.api.events.automod.AutoModRuleDeleteEvent; +import net.dv8tion.jda.api.events.automod.AutoModRuleUpdateEvent; +import net.dv8tion.jda.api.utils.data.DataObject; +import net.dv8tion.jda.internal.JDAImpl; +import net.dv8tion.jda.internal.entities.automod.AutoModRuleImpl; + +public class AutoModRuleHandler extends SocketHandler +{ + private final String type; + + public AutoModRuleHandler(JDAImpl api, String type) + { + super(api); + this.type = type; + } + + @Override + protected Long handleInternally(DataObject content) + { + long guildId = content.getUnsignedLong("guild_id"); + if (api.getGuildSetupController().isLocked(guildId)) + return guildId; + Guild guild = api.getGuildById(guildId); + if (guild == null) + { + api.getEventCache().cache(EventCache.Type.GUILD, guildId, responseNumber, allContent, this::handle); + EventCache.LOG.debug("Received a AUTO_MODERATION_RULE_{} for a guild that is not yet cached. JSON: {}", type, content); + return null; + } + + AutoModRule rule = AutoModRuleImpl.fromData(guild, content); + switch (type) + { + case "CREATE": + api.getEventManager().handle( + new AutoModRuleCreateEvent( + api, responseNumber, + rule)); + break; + case "UPDATE": + api.getEventManager().handle( + new AutoModRuleUpdateEvent( + api, responseNumber, + rule)); + break; + case "DELETE": + api.getEventManager().handle( + new AutoModRuleDeleteEvent( + api, responseNumber, + rule)); + break; + } + return null; + } +} diff --git a/src/main/java/net/dv8tion/jda/internal/requests/WebSocketClient.java b/src/main/java/net/dv8tion/jda/internal/requests/WebSocketClient.java index dcc5726e4f..3287dbe19f 100644 --- a/src/main/java/net/dv8tion/jda/internal/requests/WebSocketClient.java +++ b/src/main/java/net/dv8tion/jda/internal/requests/WebSocketClient.java @@ -1331,6 +1331,10 @@ protected void setupHandlers() { final SocketHandler.NOPHandler nopHandler = new SocketHandler.NOPHandler(api); handlers.put("APPLICATION_COMMAND_PERMISSIONS_UPDATE", new ApplicationCommandPermissionsUpdateHandler(api)); + handlers.put("AUTO_MODERATION_RULE_CREATE", new AutoModRuleHandler(api, "CREATE")); + handlers.put("AUTO_MODERATION_RULE_UPDATE", new AutoModRuleHandler(api, "UPDATE")); + handlers.put("AUTO_MODERATION_RULE_DELETE", new AutoModRuleHandler(api, "DELETE")); + handlers.put("AUTO_MODERATION_ACTION_EXECUTION", new AutoModExecutionHandler(api)); handlers.put("CHANNEL_CREATE", new ChannelCreateHandler(api)); handlers.put("CHANNEL_DELETE", new ChannelDeleteHandler(api)); handlers.put("CHANNEL_UPDATE", new ChannelUpdateHandler(api)); From a2b171d59a0519dbf70303dc45b317ed26316009 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Spie=C3=9F?= Date: Sun, 26 Mar 2023 22:44:17 +0200 Subject: [PATCH 08/39] Use correct dispatch method (copilot moment) --- .../jda/internal/handle/AutoModExecutionHandler.java | 2 +- .../net/dv8tion/jda/internal/handle/AutoModRuleHandler.java | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/net/dv8tion/jda/internal/handle/AutoModExecutionHandler.java b/src/main/java/net/dv8tion/jda/internal/handle/AutoModExecutionHandler.java index 7d9215813e..c9793fb799 100644 --- a/src/main/java/net/dv8tion/jda/internal/handle/AutoModExecutionHandler.java +++ b/src/main/java/net/dv8tion/jda/internal/handle/AutoModExecutionHandler.java @@ -42,7 +42,7 @@ protected Long handleInternally(DataObject content) } AutoModExecutionImpl execution = new AutoModExecutionImpl(guild, content); - api.getEventManager().handle( + api.handleEvent( new AutoModExecutionEvent( api, responseNumber, execution)); diff --git a/src/main/java/net/dv8tion/jda/internal/handle/AutoModRuleHandler.java b/src/main/java/net/dv8tion/jda/internal/handle/AutoModRuleHandler.java index 3d3f03adb2..53f9e78ccf 100644 --- a/src/main/java/net/dv8tion/jda/internal/handle/AutoModRuleHandler.java +++ b/src/main/java/net/dv8tion/jda/internal/handle/AutoModRuleHandler.java @@ -53,19 +53,19 @@ protected Long handleInternally(DataObject content) switch (type) { case "CREATE": - api.getEventManager().handle( + api.handleEvent( new AutoModRuleCreateEvent( api, responseNumber, rule)); break; case "UPDATE": - api.getEventManager().handle( + api.handleEvent( new AutoModRuleUpdateEvent( api, responseNumber, rule)); break; case "DELETE": - api.getEventManager().handle( + api.handleEvent( new AutoModRuleDeleteEvent( api, responseNumber, rule)); From 2de9e1dff26fef0c4affcc52eae441385e41aac4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Spie=C3=9F?= Date: Sun, 26 Mar 2023 23:25:29 +0200 Subject: [PATCH 09/39] Make channel nullable --- .../dv8tion/jda/api/entities/automod/AutoModExecution.java | 2 +- .../jda/api/events/automod/AutoModExecutionEvent.java | 2 +- .../jda/internal/entities/automod/AutoModExecutionImpl.java | 5 +---- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModExecution.java b/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModExecution.java index 8bc6fb24fc..0420ebce23 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModExecution.java +++ b/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModExecution.java @@ -27,7 +27,7 @@ public interface AutoModExecution @Nonnull Guild getGuild(); - @Nonnull + @Nullable GuildMessageChannelUnion getChannel(); @Nonnull diff --git a/src/main/java/net/dv8tion/jda/api/events/automod/AutoModExecutionEvent.java b/src/main/java/net/dv8tion/jda/api/events/automod/AutoModExecutionEvent.java index 6a7f7b731f..ccebe3fe59 100644 --- a/src/main/java/net/dv8tion/jda/api/events/automod/AutoModExecutionEvent.java +++ b/src/main/java/net/dv8tion/jda/api/events/automod/AutoModExecutionEvent.java @@ -44,7 +44,7 @@ public Guild getGuild() return execution.getGuild(); } - @Nonnull + @Nullable @Override public GuildMessageChannelUnion getChannel() { diff --git a/src/main/java/net/dv8tion/jda/internal/entities/automod/AutoModExecutionImpl.java b/src/main/java/net/dv8tion/jda/internal/entities/automod/AutoModExecutionImpl.java index 60b1887688..342ff1407e 100644 --- a/src/main/java/net/dv8tion/jda/internal/entities/automod/AutoModExecutionImpl.java +++ b/src/main/java/net/dv8tion/jda/internal/entities/automod/AutoModExecutionImpl.java @@ -23,7 +23,6 @@ import net.dv8tion.jda.api.entities.channel.middleman.GuildMessageChannel; import net.dv8tion.jda.api.entities.channel.unions.GuildMessageChannelUnion; import net.dv8tion.jda.api.utils.data.DataObject; -import net.dv8tion.jda.internal.entities.EntityBuilder; import javax.annotation.Nonnull; import javax.annotation.Nullable; @@ -41,8 +40,6 @@ public AutoModExecutionImpl(Guild guild, DataObject json) { this.guild = guild; this.channel = guild.getChannelById(GuildMessageChannel.class, json.getUnsignedLong("channel_id")); - if (this.channel == null) - throw new IllegalStateException(EntityBuilder.MISSING_CHANNEL); this.response = new AutoModResponseImpl(guild, json.getObject("action")); this.type = AutoModTriggerType.fromKey(json.getInt("trigger_type", -1)); this.userId = json.getUnsignedLong("user_id"); @@ -61,7 +58,7 @@ public Guild getGuild() return guild; } - @Nonnull + @Nullable @Override public GuildMessageChannelUnion getChannel() { From dd65785642e10594a2c51b1c492224a94a1d0dc2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Spie=C3=9F?= Date: Mon, 27 Mar 2023 16:20:18 +0200 Subject: [PATCH 10/39] Rework builders --- .../net/dv8tion/jda/api/entities/Guild.java | 21 +- .../jda/api/entities/automod/AutoModRule.java | 153 ++----------- .../build/AbstractAutoModRuleBuilder.java | 164 -------------- ...lder.java => AbstractKeywordRuleData.java} | 23 +- .../automod/build/AbstractTriggerData.java | 46 ++++ ...RuleBuilder.java => AntiSpamRuleData.java} | 9 +- .../automod/build/AutoModRuleData.java | 209 +++++++++--------- ...uilder.java => CustomKeywordRuleData.java} | 36 +-- ...mRuleBuilder.java => MentionRuleData.java} | 27 ++- ...uilder.java => PresetKeywordRuleData.java} | 25 ++- .../entities/automod/build/TriggerConfig.java | 52 +++++ .../jda/api/managers/AutoModRuleManager.java | 138 ++++++++++++ .../managers/AutoModRuleManagerImpl.java | 133 +++++++++++ 13 files changed, 568 insertions(+), 468 deletions(-) delete mode 100644 src/main/java/net/dv8tion/jda/api/entities/automod/build/AbstractAutoModRuleBuilder.java rename src/main/java/net/dv8tion/jda/api/entities/automod/build/{AbstractKeywordRuleBuilder.java => AbstractKeywordRuleData.java} (76%) create mode 100644 src/main/java/net/dv8tion/jda/api/entities/automod/build/AbstractTriggerData.java rename src/main/java/net/dv8tion/jda/api/entities/automod/build/{AntiSpamRuleBuilder.java => AntiSpamRuleData.java} (71%) rename src/main/java/net/dv8tion/jda/api/entities/automod/build/{CustomKeywordRuleBuilder.java => CustomKeywordRuleData.java} (77%) rename src/main/java/net/dv8tion/jda/api/entities/automod/build/{MentionSpamRuleBuilder.java => MentionRuleData.java} (55%) rename src/main/java/net/dv8tion/jda/api/entities/automod/build/{PresetKeywordRuleBuilder.java => PresetKeywordRuleData.java} (69%) create mode 100644 src/main/java/net/dv8tion/jda/api/entities/automod/build/TriggerConfig.java create mode 100644 src/main/java/net/dv8tion/jda/api/managers/AutoModRuleManager.java create mode 100644 src/main/java/net/dv8tion/jda/internal/managers/AutoModRuleManagerImpl.java diff --git a/src/main/java/net/dv8tion/jda/api/entities/Guild.java b/src/main/java/net/dv8tion/jda/api/entities/Guild.java index 7d0c5f5999..b9dbcb753e 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/Guild.java +++ b/src/main/java/net/dv8tion/jda/api/entities/Guild.java @@ -43,10 +43,7 @@ import net.dv8tion.jda.api.interactions.commands.build.CommandData; import net.dv8tion.jda.api.interactions.commands.build.Commands; import net.dv8tion.jda.api.interactions.commands.privileges.IntegrationPrivilege; -import net.dv8tion.jda.api.managers.AudioManager; -import net.dv8tion.jda.api.managers.GuildManager; -import net.dv8tion.jda.api.managers.GuildStickerManager; -import net.dv8tion.jda.api.managers.GuildWelcomeScreenManager; +import net.dv8tion.jda.api.managers.*; import net.dv8tion.jda.api.requests.GatewayIntent; import net.dv8tion.jda.api.requests.RestAction; import net.dv8tion.jda.api.requests.restaction.*; @@ -65,6 +62,7 @@ import net.dv8tion.jda.api.utils.cache.SortedSnowflakeCacheView; import net.dv8tion.jda.api.utils.concurrent.Task; import net.dv8tion.jda.internal.interactions.CommandDataImpl; +import net.dv8tion.jda.internal.managers.AutoModRuleManagerImpl; import net.dv8tion.jda.internal.requests.DeferredRestAction; import net.dv8tion.jda.internal.utils.Checks; import net.dv8tion.jda.internal.utils.EntityString; @@ -426,6 +424,21 @@ default RestAction retrieveAutoModRuleById(long id) @CheckReturnValue RestAction createAutoModRule(@Nonnull AutoModRuleData data); + @Nonnull + @CheckReturnValue + default AutoModRuleManager modifyAutoModRuleById(@Nonnull String id) + { + Checks.isSnowflake(id); + return new AutoModRuleManagerImpl(this, id); + } + + @Nonnull + @CheckReturnValue + default AutoModRuleManager modifyAutoModRuleById(long id) + { + return modifyAutoModRuleById(Long.toUnsignedString(id)); + } + @Nonnull @CheckReturnValue RestAction deleteAutoModRuleById(@Nonnull String id); diff --git a/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModRule.java b/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModRule.java index cbe066cb34..10eac0aa69 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModRule.java +++ b/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModRule.java @@ -19,11 +19,13 @@ import net.dv8tion.jda.api.entities.Guild; import net.dv8tion.jda.api.entities.ISnowflake; import net.dv8tion.jda.api.entities.Role; -import net.dv8tion.jda.api.entities.automod.build.*; +import net.dv8tion.jda.api.entities.automod.build.AutoModRuleData; +import net.dv8tion.jda.api.entities.automod.build.TriggerConfig; import net.dv8tion.jda.api.entities.channel.middleman.GuildChannel; +import net.dv8tion.jda.api.managers.AutoModRuleManager; +import net.dv8tion.jda.internal.managers.AutoModRuleManagerImpl; import javax.annotation.Nonnull; -import java.util.Collection; import java.util.EnumSet; import java.util.List; @@ -40,161 +42,34 @@ public interface AutoModRule extends ISnowflake */ int MAX_RULE_NAME_LENGTH = 100; /** - * The maximum length of a keyword in {@link #createCustomKeywordRule(String, String...)}. ({@value}) + * The maximum length of a keyword in {@link TriggerConfig#keywordFilter()}. ({@value}) */ int MAX_KEYWORD_LENGTH = 60; /** - * The maximum amount of keywords in {@link #createCustomKeywordRule(String, String...)}. ({@value}) + * The maximum amount of keywords in {@link TriggerConfig#keywordFilter()}. ({@value}) */ int MAX_KEYWORD_AMOUNT = 1000; /** - * The maximum amount of whitelisted keywords in {@link #createCustomKeywordRule(String, String...)}. ({@value}) + * The maximum amount of whitelisted keywords in {@link TriggerConfig#keywordFilter()}. ({@value}) */ int MAX_ALLOWLIST_CUSTOM_AMOUNT = 100; /** - * The maximum amount of whitelisted keywords in {@link #createPresetKeywordRule(String, KeywordPreset...)}. ({@value}) + * The maximum amount of whitelisted keywords in {@link TriggerConfig#presetKeywordFilter()}. ({@value}) */ int MAX_ALLOWLIST_PRESET_AMOUNT = 1000; /** - * The maximum length of a regex pattern in {@link #createCustomKeywordRule(String, String...)}. ({@value}) + * The maximum length of a regex pattern in {@link TriggerConfig#keywordFilter()}. ({@value}) */ int MAX_PATTERN_LENGTH = 260; /** - * The maximum amount of regex patterns in {@link #createCustomKeywordRule(String, String...)}. ({@value}) + * The maximum amount of regex patterns in {@link TriggerConfig#keywordFilter()}. ({@value}) */ int MAX_PATTERN_AMOUNT = 10; /** - * The maximum limit of mentions in {@link #createMentionSpamRule(String, int)}. ({@value}) + * The maximum limit of mentions in {@link TriggerConfig#mentionSpam(int)}. ({@value}) */ int MAX_MENTION_LIMIT = 50; - /** - * Creates a {@link AutoModTriggerType#MENTION_SPAM MENTION_SPAM} rule. - * - *

    Every automod rule must have at least one {@link AutoModResponse} configured. - * - *

    Example
    - *

    {@code
    -     * AutoModRule.createMentionSpamRule("Mention Spam", 10)
    -     *     .putResponse(AutoModResponse.blockMessage("Don't spam mentions!"))
    -     *     .addExemptRoles(modRole)
    -     *     .build()
    -     * }
    - * - * @param name - * The name of the rule (max {@value #MAX_RULE_NAME_LENGTH} characters) - * @param limit - * The maximum amount of mentions allowed (up to {@value #MAX_MENTION_LIMIT}) - * - * @throws java.lang.IllegalArgumentException - *
      - *
    • If the name is null, empty, or longer than {@value #MAX_RULE_NAME_LENGTH} characters.
    • - *
    • If the limit is not between 1 and {@value #MAX_MENTION_LIMIT}
    • - *
    - * - * @return {@link MentionSpamRuleBuilder} instance to build the rule - */ - @Nonnull - static MentionSpamRuleBuilder createMentionSpamRule(@Nonnull String name, int limit) - { - return new MentionSpamRuleBuilder(name, limit); - } - - /** - * Creates a {@link AutoModTriggerType#KEYWORD KEYWORD} rule. - *
    Keywords may also use wildcards at the beginning and end of the keyword (for example {@code "foo*"} would match {@code "foobar"}). - * Keywords can also contain whitespace to block phrases like {@code "foo bar"}. Additionally, keywords are case-insensitive. - * - *

    Every automod rule must have at least one {@link AutoModResponse} configured. - * - *

    Example
    - *

    {@code
    -     * AutoModRule.createCustomKeywordRule("No morbius memes", "morb*", "*morb")
    -     *     .putResponse(AutoModResponse.blockMessage("This is not a funny meme."))
    -     *     .build()
    -     * }
    - * - * @param name - * The name of the rule (max {@value #MAX_RULE_NAME_LENGTH} characters) - * @param keywords - * The blocked keywords (max {@value #MAX_KEYWORD_AMOUNT} keywords, max {@value #MAX_KEYWORD_LENGTH} characters per keyword) - * - * @throws java.lang.IllegalArgumentException - *
      - *
    • If the name is null, empty, or longer than {@value #MAX_RULE_NAME_LENGTH} characters.
    • - *
    • If any keyword is empty or longer than {@value #MAX_KEYWORD_LENGTH}
    • - *
    • If more than {@value #MAX_KEYWORD_AMOUNT} keywords are provided
    • - *
    - * - * @return {@link CustomKeywordRuleBuilder} instance to build the rule - */ - @Nonnull - static CustomKeywordRuleBuilder createCustomKeywordRule(@Nonnull String name, @Nonnull String... keywords) - { - return new CustomKeywordRuleBuilder(name).addKeywords(keywords); - } - - /** - * Creates a {@link AutoModTriggerType#KEYWORD_PRESET KEYWORD_PRESET} rule. - *
    In the {@link PresetKeywordRuleBuilder#setAllowList(Collection) allowlist}, - * keywords may also use wildcards at the beginning and end of the keyword (for example {@code "foo*"} would match {@code "foobar"}). - * Keywords can also contain whitespace to block phrases like {@code "foo bar"}. Additionally, keywords are case-insensitive. - * - *

    Every automod rule must have at least one {@link AutoModResponse} configured. - * - *

    Example
    - *

    {@code
    -     * AutoModRule.createPresetKeywordRule("No slurs", KeywordPreset.SLURS)
    -     *     .putResponse(AutoModResponse.blockMessage("Please refrain from using this kind of language."))
    -     *     .build()
    -     * }
    - * - * @param name - * The name of the rule (max {@value #MAX_RULE_NAME_LENGTH} characters) - * @param presets - * Preset lists of keywords to block. (Should be at least 1 preset) - * - * @throws java.lang.IllegalArgumentException - *
      - *
    • If the name is null, empty, or longer than {@value #MAX_RULE_NAME_LENGTH} characters.
    • - *
    • If null is provided
    • - *
    - * - * @return {@link PresetKeywordRuleBuilder} instance to build the rule - */ - @Nonnull - static PresetKeywordRuleBuilder createPresetKeywordRule(@Nonnull String name, @Nonnull KeywordPreset... presets) - { - return new PresetKeywordRuleBuilder(name).enablePresets(presets); - } - - /** - * Creates a {@link AutoModTriggerType#SPAM SPAM} rule. - * - *

    Every automod rule must have at least one {@link AutoModResponse} configured. - * - *

    Example
    - *

    {@code
    -     * AutoModRule.createAntiSpamRule("Spam detected")
    -     *     .putResponse(AutoModResponse.timeoutMember(Duration.ofMinutes(1))
    -     *     .addExemptRoles(modRole)
    -     *     .build()
    -     * }
    - * - * @param name - * The name of the rule (max {@value #MAX_RULE_NAME_LENGTH} characters) - * - * @throws java.lang.IllegalArgumentException - * If the name is null, empty, or longer than {@value #MAX_RULE_NAME_LENGTH} characters. - * - * @return {@link AntiSpamRuleBuilder} instance to build the rule - */ - @Nonnull - static AntiSpamRuleBuilder createAntiSpamRule(@Nonnull String name) - { - return new AntiSpamRuleBuilder(name); - } - @Nonnull Guild getGuild(); @@ -240,6 +115,12 @@ default String getOwnerId() int getMentionLimit(); + @Nonnull + default AutoModRuleManager getManager() + { + return new AutoModRuleManagerImpl(getGuild(), getId()); + } + enum KeywordPreset { PROFANITY(1), diff --git a/src/main/java/net/dv8tion/jda/api/entities/automod/build/AbstractAutoModRuleBuilder.java b/src/main/java/net/dv8tion/jda/api/entities/automod/build/AbstractAutoModRuleBuilder.java deleted file mode 100644 index 855b919034..0000000000 --- a/src/main/java/net/dv8tion/jda/api/entities/automod/build/AbstractAutoModRuleBuilder.java +++ /dev/null @@ -1,164 +0,0 @@ -/* - * Copyright 2015 Austin Keener, Michael Ritter, Florian Spieß, and the JDA contributors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.dv8tion.jda.api.entities.automod.build; - -import gnu.trove.list.TLongList; -import gnu.trove.list.array.TLongArrayList; -import net.dv8tion.jda.api.entities.Role; -import net.dv8tion.jda.api.entities.automod.AutoModEventType; -import net.dv8tion.jda.api.entities.automod.AutoModResponse; -import net.dv8tion.jda.api.entities.automod.AutoModRule; -import net.dv8tion.jda.api.entities.automod.AutoModTriggerType; -import net.dv8tion.jda.api.entities.channel.middleman.GuildChannel; -import net.dv8tion.jda.internal.utils.Checks; - -import javax.annotation.Nonnull; -import java.util.ArrayList; -import java.util.Collection; -import java.util.EnumMap; - -public abstract class AbstractAutoModRuleBuilder> -{ - protected final AutoModTriggerType triggerType; - protected final AutoModEventType eventType; - protected String name; - protected boolean enabled = true; - - protected final EnumMap actions = new EnumMap<>(AutoModResponse.Type.class); - protected final TLongList exemptChannels = new TLongArrayList(); - protected final TLongList exemptRoles = new TLongArrayList(); - - protected AbstractAutoModRuleBuilder(AutoModTriggerType triggerType, AutoModEventType eventType, String name) - { - Checks.notNull(triggerType, "Trigger Type"); - Checks.notNull(eventType, "Event Type"); - this.triggerType = triggerType; - this.eventType = eventType; - setName(name); - } - - @Nonnull - public B setName(@Nonnull String name) - { - Checks.notEmpty(name, "Name"); - Checks.notLonger(name, AutoModRule.MAX_RULE_NAME_LENGTH, "Name"); - this.name = name; - return (B) this; - } - - @Nonnull - public B setEnabled(boolean enabled) - { - this.enabled = enabled; - return (B) this; - } - - @Nonnull - public B putResponses(@Nonnull AutoModResponse... responses) - { - Checks.noneNull(responses, "Responses"); - for (AutoModResponse response : responses) - actions.put(response.getType(), response); - return (B) this; - } - - @Nonnull - public B putResponses(@Nonnull Collection responses) - { - Checks.noneNull(responses, "Responses"); - for (AutoModResponse response : responses) - actions.put(response.getType(), response); - return (B) this; - } - - @Nonnull - public B setResponses(@Nonnull Collection responses) - { - Checks.noneNull(responses, "Responses"); - actions.clear(); - for (AutoModResponse response : responses) - actions.put(response.getType(), response); - return (B) this; - } - - @Nonnull - public B addExemptRoles(@Nonnull Role... roles) - { - Checks.noneNull(roles, "Roles"); - for (Role role : roles) - exemptRoles.add(role.getIdLong()); - return (B) this; - } - - @Nonnull - public B addExemptRoles(@Nonnull Collection roles) - { - Checks.noneNull(roles, "Roles"); - for (Role role : roles) - exemptRoles.add(role.getIdLong()); - return (B) this; - } - - @Nonnull - public B setExemptRoles(@Nonnull Collection roles) - { - Checks.noneNull(roles, "Roles"); - exemptRoles.clear(); - for (Role role : roles) - exemptRoles.add(role.getIdLong()); - return (B) this; - } - - @Nonnull - public B addExemptChannels(@Nonnull GuildChannel... channels) - { - Checks.noneNull(channels, "Channels"); - for (GuildChannel channel : channels) - exemptChannels.add(channel.getIdLong()); - return (B) this; - } - - @Nonnull - public B addExemptChannels(@Nonnull Collection channels) - { - Checks.noneNull(channels, "Channels"); - for (GuildChannel channel : channels) - exemptChannels.add(channel.getIdLong()); - return (B) this; - } - - @Nonnull - public B setExemptChannels(@Nonnull Collection channels) - { - Checks.noneNull(channels, "Channels"); - exemptChannels.clear(); - for (GuildChannel channel : channels) - exemptChannels.add(channel.getIdLong()); - return (B) this; - } - - @Nonnull - public AutoModRuleData build() - { - AutoModRuleData rule = new AutoModRuleData(triggerType, eventType, name); - rule.setEnabled(enabled); - rule.setExemptChannels(exemptChannels.toArray()); - rule.setExemptRoles(exemptRoles.toArray()); - rule.setActions(new ArrayList<>(actions.values())); - return rule; - } -} diff --git a/src/main/java/net/dv8tion/jda/api/entities/automod/build/AbstractKeywordRuleBuilder.java b/src/main/java/net/dv8tion/jda/api/entities/automod/build/AbstractKeywordRuleData.java similarity index 76% rename from src/main/java/net/dv8tion/jda/api/entities/automod/build/AbstractKeywordRuleBuilder.java rename to src/main/java/net/dv8tion/jda/api/entities/automod/build/AbstractKeywordRuleData.java index 16a1e2311c..5e82d08aec 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/automod/build/AbstractKeywordRuleBuilder.java +++ b/src/main/java/net/dv8tion/jda/api/entities/automod/build/AbstractKeywordRuleData.java @@ -16,21 +16,22 @@ package net.dv8tion.jda.api.entities.automod.build; -import net.dv8tion.jda.api.entities.automod.AutoModEventType; import net.dv8tion.jda.api.entities.automod.AutoModRule; import net.dv8tion.jda.api.entities.automod.AutoModTriggerType; +import net.dv8tion.jda.api.utils.data.DataArray; +import net.dv8tion.jda.api.utils.data.DataObject; import net.dv8tion.jda.internal.utils.Checks; import javax.annotation.Nonnull; import java.util.*; -public abstract class AbstractKeywordRuleBuilder> extends AbstractAutoModRuleBuilder +public abstract class AbstractKeywordRuleData> extends AbstractTriggerData { protected final List allowList = new ArrayList<>(); - protected AbstractKeywordRuleBuilder(AutoModTriggerType triggerType, AutoModEventType eventType, String name) + protected AbstractKeywordRuleData(AutoModTriggerType triggerType) { - super(triggerType, eventType, name); + super(triggerType); } @Nonnull @@ -38,7 +39,7 @@ public B addAllowList(@Nonnull String... keywords) { Checks.noneNull(keywords, "Keywords"); Checks.check(this.allowList.size() + keywords.length <= maxAllowListAmount(), "Cannot add more than %d keywords!", maxAllowListAmount()); - Arrays.stream(keywords).forEach(AbstractKeywordRuleBuilder::checkKeyword); + Arrays.stream(keywords).forEach(AbstractKeywordRuleData::checkKeyword); Collections.addAll(allowList, keywords); return (B) this; } @@ -48,7 +49,7 @@ public B addAllowList(@Nonnull Collection keywords) { Checks.noneNull(keywords, "Keywords"); Checks.check(this.allowList.size() + keywords.size() <= maxAllowListAmount(), "Cannot add more than %d keywords!", maxAllowListAmount()); - keywords.forEach(AbstractKeywordRuleBuilder::checkKeyword); + keywords.forEach(AbstractKeywordRuleData::checkKeyword); allowList.addAll(keywords); return (B) this; } @@ -58,7 +59,7 @@ public B setAllowList(@Nonnull Collection keywords) { Checks.noneNull(keywords, "Keywords"); Checks.check(keywords.size() <= maxAllowListAmount(), "Cannot add more than %d keywords!", maxAllowListAmount()); - keywords.forEach(AbstractKeywordRuleBuilder::checkKeyword); + keywords.forEach(AbstractKeywordRuleData::checkKeyword); allowList.clear(); allowList.addAll(keywords); return (B) this; @@ -74,10 +75,10 @@ protected static void checkKeyword(String keyword) @Nonnull @Override - public AutoModRuleData build() + public DataObject toData() { - AutoModRuleData rule = super.build(); - rule.setAllowlist(allowList); - return rule; + DataObject data = super.toData(); + data.put("allow_list", DataArray.fromCollection(allowList)); + return data; } } diff --git a/src/main/java/net/dv8tion/jda/api/entities/automod/build/AbstractTriggerData.java b/src/main/java/net/dv8tion/jda/api/entities/automod/build/AbstractTriggerData.java new file mode 100644 index 0000000000..07156731d7 --- /dev/null +++ b/src/main/java/net/dv8tion/jda/api/entities/automod/build/AbstractTriggerData.java @@ -0,0 +1,46 @@ +/* + * Copyright 2015 Austin Keener, Michael Ritter, Florian Spieß, and the JDA contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.dv8tion.jda.api.entities.automod.build; + +import net.dv8tion.jda.api.entities.automod.AutoModTriggerType; +import net.dv8tion.jda.api.utils.data.DataObject; + +import javax.annotation.Nonnull; + +public class AbstractTriggerData> implements TriggerConfig +{ + protected final AutoModTriggerType type; + + protected AbstractTriggerData(AutoModTriggerType type) + { + this.type = type; + } + + @Nonnull + @Override + public AutoModTriggerType getType() + { + return type; + } + + @Nonnull + @Override + public DataObject toData() + { + return DataObject.empty(); + } +} diff --git a/src/main/java/net/dv8tion/jda/api/entities/automod/build/AntiSpamRuleBuilder.java b/src/main/java/net/dv8tion/jda/api/entities/automod/build/AntiSpamRuleData.java similarity index 71% rename from src/main/java/net/dv8tion/jda/api/entities/automod/build/AntiSpamRuleBuilder.java rename to src/main/java/net/dv8tion/jda/api/entities/automod/build/AntiSpamRuleData.java index e36c0074cd..22f0532190 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/automod/build/AntiSpamRuleBuilder.java +++ b/src/main/java/net/dv8tion/jda/api/entities/automod/build/AntiSpamRuleData.java @@ -16,15 +16,12 @@ package net.dv8tion.jda.api.entities.automod.build; -import net.dv8tion.jda.api.entities.automod.AutoModEventType; import net.dv8tion.jda.api.entities.automod.AutoModTriggerType; -import javax.annotation.Nonnull; - -public class AntiSpamRuleBuilder extends AbstractAutoModRuleBuilder +public class AntiSpamRuleData extends AbstractTriggerData { - public AntiSpamRuleBuilder(@Nonnull String name) + protected AntiSpamRuleData() { - super(AutoModTriggerType.SPAM, AutoModEventType.MESSAGE_SEND, name); + super(AutoModTriggerType.SPAM); } } diff --git a/src/main/java/net/dv8tion/jda/api/entities/automod/build/AutoModRuleData.java b/src/main/java/net/dv8tion/jda/api/entities/automod/build/AutoModRuleData.java index a1b117dea0..9fc9cc6219 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/automod/build/AutoModRuleData.java +++ b/src/main/java/net/dv8tion/jda/api/entities/automod/build/AutoModRuleData.java @@ -16,92 +16,152 @@ package net.dv8tion.jda.api.entities.automod.build; +import net.dv8tion.jda.api.entities.Role; import net.dv8tion.jda.api.entities.automod.AutoModEventType; import net.dv8tion.jda.api.entities.automod.AutoModResponse; import net.dv8tion.jda.api.entities.automod.AutoModRule; -import net.dv8tion.jda.api.entities.automod.AutoModTriggerType; +import net.dv8tion.jda.api.entities.channel.middleman.GuildChannel; import net.dv8tion.jda.api.utils.data.DataArray; import net.dv8tion.jda.api.utils.data.DataObject; import net.dv8tion.jda.api.utils.data.SerializableData; +import net.dv8tion.jda.internal.utils.Checks; +import javax.annotation.CheckReturnValue; import javax.annotation.Nonnull; -import java.util.EnumSet; -import java.util.List; +import java.util.ArrayList; +import java.util.Collection; +import java.util.EnumMap; public class AutoModRuleData implements SerializableData { - private final AutoModTriggerType triggerType; - private final AutoModEventType eventType; - private final String name; - - private boolean enabled = true; - private int mentionLimit = -1; - private List actions; - private long[] exemptRoles; - private long[] exemptChannels; - private List filteredKeywords; - private List filteredRegex; - private EnumSet filteredPresets; - private List allowlist; - - protected AutoModRuleData(AutoModTriggerType triggerType, AutoModEventType eventType, String name) + protected final AutoModEventType eventType; + protected String name; + protected boolean enabled = true; + protected TriggerConfig triggerMetadata; + + protected final EnumMap actions = new EnumMap<>(AutoModResponse.Type.class); + protected final Collection exemptChannels = new ArrayList<>(); + protected final Collection exemptRoles = new ArrayList<>(); + + protected AutoModRuleData(AutoModEventType eventType, String name, TriggerConfig triggerMetadata) { - this.triggerType = triggerType; this.eventType = eventType; this.name = name; + this.triggerMetadata = triggerMetadata; } - protected AutoModRuleData setEnabled(boolean enabled) + @Nonnull + public static AutoModRuleData onMessage(@Nonnull String name, @Nonnull TriggerConfig triggerConfig) + { + return new AutoModRuleData(AutoModEventType.MESSAGE_SEND, name, triggerConfig); + } + + @Nonnull + public AutoModRuleData setName(@Nonnull String name) + { + Checks.notEmpty(name, "Name"); + Checks.notLonger(name, AutoModRule.MAX_RULE_NAME_LENGTH, "Name"); + this.name = name; + return this; + } + + @Nonnull + public AutoModRuleData setEnabled(boolean enabled) { this.enabled = enabled; return this; } - protected AutoModRuleData setMentionLimit(int mentionLimit) + @Nonnull + public AutoModRuleData putResponses(@Nonnull AutoModResponse... responses) { - this.mentionLimit = mentionLimit; + Checks.noneNull(responses, "Responses"); + for (AutoModResponse response : responses) + actions.put(response.getType(), response); return this; } - protected AutoModRuleData setActions(List actions) + @Nonnull + public AutoModRuleData putResponses(@Nonnull Collection responses) { - this.actions = actions; + Checks.noneNull(responses, "Responses"); + for (AutoModResponse response : responses) + actions.put(response.getType(), response); return this; } - protected AutoModRuleData setExemptRoles(long... exemptRoles) + @Nonnull + public AutoModRuleData setResponses(@Nonnull Collection responses) { - this.exemptRoles = exemptRoles; + Checks.noneNull(responses, "Responses"); + actions.clear(); + for (AutoModResponse response : responses) + actions.put(response.getType(), response); return this; } - protected AutoModRuleData setExemptChannels(long... exemptChannels) + @Nonnull + public AutoModRuleData addExemptRoles(@Nonnull Role... roles) { - this.exemptChannels = exemptChannels; + Checks.noneNull(roles, "Roles"); + for (Role role : roles) + exemptRoles.add(role.getId()); return this; } - protected AutoModRuleData setFilteredKeywords(List filteredKeywords) + @Nonnull + public AutoModRuleData addExemptRoles(@Nonnull Collection roles) + { + Checks.noneNull(roles, "Roles"); + for (Role role : roles) + exemptRoles.add(role.getId()); + return this; + } + + @Nonnull + public AutoModRuleData setExemptRoles(@Nonnull Collection roles) + { + Checks.noneNull(roles, "Roles"); + exemptRoles.clear(); + for (Role role : roles) + exemptRoles.add(role.getId()); + return this; + } + + @Nonnull + public AutoModRuleData addExemptChannels(@Nonnull GuildChannel... channels) { - this.filteredKeywords = filteredKeywords; + Checks.noneNull(channels, "Channels"); + for (GuildChannel channel : channels) + exemptChannels.add(channel.getId()); return this; } - protected AutoModRuleData setFilteredRegex(List filteredRegex) + @Nonnull + public AutoModRuleData addExemptChannels(@Nonnull Collection channels) { - this.filteredRegex = filteredRegex; + Checks.noneNull(channels, "Channels"); + for (GuildChannel channel : channels) + exemptChannels.add(channel.getId()); return this; } - protected AutoModRuleData setFilteredPresets(EnumSet filteredPresets) + @Nonnull + public AutoModRuleData setExemptChannels(@Nonnull Collection channels) { - this.filteredPresets = filteredPresets; + Checks.noneNull(channels, "Channels"); + exemptChannels.clear(); + for (GuildChannel channel : channels) + exemptChannels.add(channel.getId()); return this; } - protected AutoModRuleData setAllowlist(List allowlist) + @Nonnull + @CheckReturnValue + public AutoModRuleData setTriggerConfig(@Nonnull TriggerConfig config) { - this.allowlist = allowlist; + Checks.notNull(config, "TriggerConfig"); + this.triggerMetadata = config; return this; } @@ -111,77 +171,16 @@ public DataObject toData() { DataObject data = DataObject.empty() .put("name", name) - .put("trigger_type", triggerType.getKey()) + .put("enabled", enabled) .put("event_type", eventType.getKey()); - data.put("enabled", enabled); - - if (actions != null) - data.put("actions", DataArray.fromCollection(actions)); - else - data.put("actions", DataArray.empty()); - - if (exemptRoles != null) - { - DataArray array = DataArray.empty(); - for (long id : exemptRoles) - array.add(id); - data.put("exempt_roles", array); - } - else - { - data.put("exempt_roles", DataArray.empty()); - } - - if (exemptChannels != null) - { - DataArray array = DataArray.empty(); - for (long id : exemptChannels) - array.add(id); - data.put("exempt_channels", array); - } - else - { - data.put("exempt_channels", DataArray.empty()); - } - - DataObject metadata = DataObject.empty(); - - switch (triggerType) - { - case MENTION_SPAM: - if (mentionLimit != -1) - metadata.put("mention_total_limit", mentionLimit); - break; - case SPAM: - break; - case KEYWORD: - if (filteredKeywords != null) - metadata.put("filtered_keywords", DataArray.fromCollection(filteredKeywords)); - else - metadata.put("filtered_keywords", DataArray.empty()); - if (filteredRegex != null) - metadata.put("filtered_regex", DataArray.fromCollection(filteredRegex)); - else - metadata.put("filtered_regex", DataArray.empty()); - if (allowlist != null) - metadata.put("allow_list", DataArray.fromCollection(allowlist)); - else - metadata.put("allow_list", DataArray.empty()); - break; - case KEYWORD_PRESET: - if (filteredPresets != null) - metadata.put("filtered_presets", DataArray.fromCollection(filteredPresets)); - else - metadata.put("filtered_presets", DataArray.empty()); - if (allowlist != null) - metadata.put("allow_list", DataArray.fromCollection(allowlist)); - else - metadata.put("allow_list", DataArray.empty()); - break; - } - - data.put("trigger_metadata", metadata); + data.put("actions", DataArray.fromCollection(actions.values())); + + data.put("exempt_roles", DataArray.fromCollection(exemptRoles)); + data.put("exempt_channels", DataArray.fromCollection(exemptChannels)); + + data.put("trigger_type", triggerMetadata.getType().getKey()); + data.put("trigger_metadata", triggerMetadata.toData()); return data; } diff --git a/src/main/java/net/dv8tion/jda/api/entities/automod/build/CustomKeywordRuleBuilder.java b/src/main/java/net/dv8tion/jda/api/entities/automod/build/CustomKeywordRuleData.java similarity index 77% rename from src/main/java/net/dv8tion/jda/api/entities/automod/build/CustomKeywordRuleBuilder.java rename to src/main/java/net/dv8tion/jda/api/entities/automod/build/CustomKeywordRuleData.java index 43e63c656d..2380079536 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/automod/build/CustomKeywordRuleBuilder.java +++ b/src/main/java/net/dv8tion/jda/api/entities/automod/build/CustomKeywordRuleData.java @@ -16,26 +16,30 @@ package net.dv8tion.jda.api.entities.automod.build; -import net.dv8tion.jda.api.entities.automod.AutoModEventType; import net.dv8tion.jda.api.entities.automod.AutoModRule; import net.dv8tion.jda.api.entities.automod.AutoModTriggerType; +import net.dv8tion.jda.api.utils.data.DataArray; +import net.dv8tion.jda.api.utils.data.DataObject; import net.dv8tion.jda.internal.utils.Checks; import javax.annotation.Nonnull; -import java.util.*; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; -public class CustomKeywordRuleBuilder extends AbstractKeywordRuleBuilder +public class CustomKeywordRuleData extends AbstractKeywordRuleData { protected final Set keywords = new HashSet<>(); protected final Set patterns = new HashSet<>(); - public CustomKeywordRuleBuilder(@Nonnull String name) + protected CustomKeywordRuleData() { - super(AutoModTriggerType.KEYWORD, AutoModEventType.MESSAGE_SEND, name); + super(AutoModTriggerType.KEYWORD); } @Nonnull - public CustomKeywordRuleBuilder addKeywords(@Nonnull String... keywords) + public CustomKeywordRuleData addKeywords(@Nonnull String... keywords) { Checks.noneNull(keywords, "Keywords"); Checks.check(this.keywords.size() + keywords.length <= AutoModRule.MAX_KEYWORD_AMOUNT, "Cannot add more than %d keywords!", AutoModRule.MAX_KEYWORD_AMOUNT); @@ -47,7 +51,7 @@ public CustomKeywordRuleBuilder addKeywords(@Nonnull String... keywords) } @Nonnull - public CustomKeywordRuleBuilder addKeywords(@Nonnull Collection keywords) + public CustomKeywordRuleData addKeywords(@Nonnull Collection keywords) { Checks.noneNull(keywords, "Keywords"); Checks.check(this.keywords.size() + keywords.size() <= AutoModRule.MAX_KEYWORD_AMOUNT, "Cannot add more than %d keywords!", AutoModRule.MAX_KEYWORD_AMOUNT); @@ -59,7 +63,7 @@ public CustomKeywordRuleBuilder addKeywords(@Nonnull Collection keywords } @Nonnull - public CustomKeywordRuleBuilder setKeywords(@Nonnull Collection keywords) + public CustomKeywordRuleData setKeywords(@Nonnull Collection keywords) { Checks.noneNull(keywords, "Keywords"); Checks.check(keywords.size() <= AutoModRule.MAX_KEYWORD_AMOUNT, "Cannot add more than %d keywords!", AutoModRule.MAX_KEYWORD_AMOUNT); @@ -73,7 +77,7 @@ public CustomKeywordRuleBuilder setKeywords(@Nonnull Collection keywords @Nonnull - public CustomKeywordRuleBuilder addPatterns(@Nonnull String... patterns) + public CustomKeywordRuleData addPatterns(@Nonnull String... patterns) { Checks.noneNull(patterns, "Patterns"); Checks.check(this.patterns.size() + patterns.length <= AutoModRule.MAX_PATTERN_AMOUNT, "Cannot add more than %d patterns!", AutoModRule.MAX_PATTERN_AMOUNT); @@ -85,7 +89,7 @@ public CustomKeywordRuleBuilder addPatterns(@Nonnull String... patterns) } @Nonnull - public CustomKeywordRuleBuilder addPatterns(@Nonnull Collection patterns) + public CustomKeywordRuleData addPatterns(@Nonnull Collection patterns) { Checks.noneNull(patterns, "Patterns"); Checks.check(this.patterns.size() + patterns.size() <= AutoModRule.MAX_PATTERN_AMOUNT, "Cannot add more than %d patterns!", AutoModRule.MAX_PATTERN_AMOUNT); @@ -97,7 +101,7 @@ public CustomKeywordRuleBuilder addPatterns(@Nonnull Collection patterns } @Nonnull - public CustomKeywordRuleBuilder setPatterns(@Nonnull Collection patterns) + public CustomKeywordRuleData setPatterns(@Nonnull Collection patterns) { Checks.noneNull(patterns, "Patterns"); Checks.check(patterns.size() <= AutoModRule.MAX_PATTERN_AMOUNT, "Cannot add more than %d patterns!", AutoModRule.MAX_PATTERN_AMOUNT); @@ -123,12 +127,12 @@ protected int maxAllowListAmount() @Nonnull @Override - public AutoModRuleData build() + public DataObject toData() { Checks.check(!keywords.isEmpty() || !patterns.isEmpty(), "Must have at least one keyword or pattern!"); - AutoModRuleData rule = super.build(); - rule.setFilteredKeywords(new ArrayList<>(keywords)); - rule.setFilteredRegex(new ArrayList<>(patterns)); - return rule; + DataObject data = super.toData(); + data.put("keyword_filter", DataArray.fromCollection(keywords)); + data.put("regex_patterns", DataArray.fromCollection(patterns)); + return data; } } diff --git a/src/main/java/net/dv8tion/jda/api/entities/automod/build/MentionSpamRuleBuilder.java b/src/main/java/net/dv8tion/jda/api/entities/automod/build/MentionRuleData.java similarity index 55% rename from src/main/java/net/dv8tion/jda/api/entities/automod/build/MentionSpamRuleBuilder.java rename to src/main/java/net/dv8tion/jda/api/entities/automod/build/MentionRuleData.java index 8e0dfa01e0..0cfbea8ad0 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/automod/build/MentionSpamRuleBuilder.java +++ b/src/main/java/net/dv8tion/jda/api/entities/automod/build/MentionRuleData.java @@ -16,39 +16,38 @@ package net.dv8tion.jda.api.entities.automod.build; -import net.dv8tion.jda.api.entities.automod.AutoModEventType; import net.dv8tion.jda.api.entities.automod.AutoModRule; import net.dv8tion.jda.api.entities.automod.AutoModTriggerType; +import net.dv8tion.jda.api.utils.data.DataObject; import net.dv8tion.jda.internal.utils.Checks; import javax.annotation.Nonnull; -public class MentionSpamRuleBuilder extends AbstractAutoModRuleBuilder +public class MentionRuleData extends AbstractTriggerData implements TriggerConfig { private int mentionLimit; - public MentionSpamRuleBuilder(@Nonnull String name, int limit) + public MentionRuleData(int mentionLimit) { - super(AutoModTriggerType.MENTION_SPAM, AutoModEventType.MESSAGE_SEND, name); - Checks.positive(limit, "Mention Limit"); - this.mentionLimit = limit; + super(AutoModTriggerType.MENTION_SPAM); + this.mentionLimit = mentionLimit; } @Nonnull - public MentionSpamRuleBuilder setMentionLimit(int limit) + public MentionRuleData setMentionLimit(int mentionLimit) { - Checks.positive(limit, "Mention Limit"); - Checks.check(limit <= AutoModRule.MAX_MENTION_LIMIT, "Mention Limit cannot be higher than %d. Provided: %d", AutoModRule.MAX_MENTION_LIMIT, limit); - this.mentionLimit = limit; + Checks.positive(mentionLimit, "Mention Limit"); + Checks.check(mentionLimit <= AutoModRule.MAX_MENTION_LIMIT, "Mention Limit cannot be higher than %d. Provided: %d", AutoModRule.MAX_MENTION_LIMIT, mentionLimit); + this.mentionLimit = mentionLimit; return this; } @Nonnull @Override - public AutoModRuleData build() + public DataObject toData() { - AutoModRuleData rule = super.build(); - rule.setMentionLimit(mentionLimit); - return rule; + DataObject data = super.toData(); + data.put("mention_total_limit", mentionLimit); + return data; } } diff --git a/src/main/java/net/dv8tion/jda/api/entities/automod/build/PresetKeywordRuleBuilder.java b/src/main/java/net/dv8tion/jda/api/entities/automod/build/PresetKeywordRuleData.java similarity index 69% rename from src/main/java/net/dv8tion/jda/api/entities/automod/build/PresetKeywordRuleBuilder.java rename to src/main/java/net/dv8tion/jda/api/entities/automod/build/PresetKeywordRuleData.java index 3875e2f8f9..42163833c1 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/automod/build/PresetKeywordRuleBuilder.java +++ b/src/main/java/net/dv8tion/jda/api/entities/automod/build/PresetKeywordRuleData.java @@ -16,9 +16,10 @@ package net.dv8tion.jda.api.entities.automod.build; -import net.dv8tion.jda.api.entities.automod.AutoModEventType; import net.dv8tion.jda.api.entities.automod.AutoModRule; import net.dv8tion.jda.api.entities.automod.AutoModTriggerType; +import net.dv8tion.jda.api.utils.data.DataArray; +import net.dv8tion.jda.api.utils.data.DataObject; import net.dv8tion.jda.internal.utils.Checks; import javax.annotation.Nonnull; @@ -26,17 +27,17 @@ import java.util.Collections; import java.util.EnumSet; -public class PresetKeywordRuleBuilder extends AbstractKeywordRuleBuilder +public class PresetKeywordRuleData extends AbstractKeywordRuleData { private final EnumSet presets = EnumSet.noneOf(AutoModRule.KeywordPreset.class); - public PresetKeywordRuleBuilder(@Nonnull String name) + protected PresetKeywordRuleData() { - super(AutoModTriggerType.KEYWORD_PRESET, AutoModEventType.MESSAGE_SEND, name); + super(AutoModTriggerType.KEYWORD_PRESET); } @Nonnull - public PresetKeywordRuleBuilder enablePresets(@Nonnull AutoModRule.KeywordPreset... presets) + public PresetKeywordRuleData enablePresets(@Nonnull AutoModRule.KeywordPreset... presets) { Checks.noneNull(presets, "Presets"); Collections.addAll(this.presets, presets); @@ -44,7 +45,7 @@ public PresetKeywordRuleBuilder enablePresets(@Nonnull AutoModRule.KeywordPreset } @Nonnull - public PresetKeywordRuleBuilder enablePresets(@Nonnull Collection presets) + public PresetKeywordRuleData enablePresets(@Nonnull Collection presets) { Checks.noneNull(presets, "Presets"); this.presets.addAll(presets); @@ -52,7 +53,7 @@ public PresetKeywordRuleBuilder enablePresets(@Nonnull Collection presets) + public PresetKeywordRuleData disablePresets(@Nonnull Collection presets) { Checks.noneNull(presets, "Presets"); this.presets.removeAll(presets); @@ -76,11 +77,11 @@ protected int maxAllowListAmount() @Nonnull @Override - public AutoModRuleData build() + public DataObject toData() { - AutoModRuleData rule = super.build(); + DataObject data = super.toData(); presets.remove(AutoModRule.KeywordPreset.UNKNOWN); - rule.setFilteredPresets(presets); - return rule; + data.put("presets", DataArray.fromCollection(presets)); + return data; } } diff --git a/src/main/java/net/dv8tion/jda/api/entities/automod/build/TriggerConfig.java b/src/main/java/net/dv8tion/jda/api/entities/automod/build/TriggerConfig.java new file mode 100644 index 0000000000..87743bb168 --- /dev/null +++ b/src/main/java/net/dv8tion/jda/api/entities/automod/build/TriggerConfig.java @@ -0,0 +1,52 @@ +/* + * Copyright 2015 Austin Keener, Michael Ritter, Florian Spieß, and the JDA contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.dv8tion.jda.api.entities.automod.build; + +import net.dv8tion.jda.api.entities.automod.AutoModTriggerType; +import net.dv8tion.jda.api.utils.data.SerializableData; + +import javax.annotation.Nonnull; + +public interface TriggerConfig extends SerializableData +{ + @Nonnull + AutoModTriggerType getType(); + + @Nonnull + static MentionRuleData mentionSpam(int limit) + { + return new MentionRuleData(limit); + } + + @Nonnull + static AntiSpamRuleData antiSpam() + { + return new AntiSpamRuleData(); + } + + @Nonnull + static CustomKeywordRuleData keywordFilter() + { + return new CustomKeywordRuleData(); + } + + @Nonnull + static PresetKeywordRuleData presetKeywordFilter() + { + return new PresetKeywordRuleData(); + } +} diff --git a/src/main/java/net/dv8tion/jda/api/managers/AutoModRuleManager.java b/src/main/java/net/dv8tion/jda/api/managers/AutoModRuleManager.java new file mode 100644 index 0000000000..7863a8cca3 --- /dev/null +++ b/src/main/java/net/dv8tion/jda/api/managers/AutoModRuleManager.java @@ -0,0 +1,138 @@ +/* + * Copyright 2015 Austin Keener, Michael Ritter, Florian Spieß, and the JDA contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.dv8tion.jda.api.managers; + +import net.dv8tion.jda.api.entities.Role; +import net.dv8tion.jda.api.entities.automod.AutoModResponse; +import net.dv8tion.jda.api.entities.automod.build.TriggerConfig; +import net.dv8tion.jda.api.entities.channel.middleman.GuildChannel; +import net.dv8tion.jda.internal.utils.Checks; + +import javax.annotation.CheckReturnValue; +import javax.annotation.Nonnull; +import java.util.Arrays; +import java.util.Collection; + +public interface AutoModRuleManager extends Manager +{ + long NAME = 1; + long ENABLED = 1 << 1; + long RESPONSE = 1 << 2; + long EXEMPT_ROLES = 1 << 3; + long EXEMPT_CHANNELS = 1 << 4; + long TRIGGER_METADATA = 1 << 5; + + /** + * Resets the fields specified by the provided bit-flag pattern. + * You can specify a combination by using a bitwise OR concat of the flag constants. + *
    Example: {@code manager.reset(AutoModRuleManager.NAME | AutoModRuleManager.RESPONSE);} + * + *

    Flag Constants: + *

      + *
    • {@link #NAME}
    • + *
    • {@link #ENABLED}
    • + *
    • {@link #RESPONSE}
    • + *
    • {@link #EXEMPT_ROLES}
    • + *
    • {@link #EXEMPT_CHANNELS}
    • + *
    • {@link #TRIGGER_METADATA}
    • + *
    + * + * @param fields + * Integer value containing the flags to reset. + * + * @return AutoModRuleManager for chaining convenience + */ + @Nonnull + @Override + AutoModRuleManager reset(long fields); + + /** + * Resets the fields specified by the provided bit-flag pattern. + * You can specify a combination by using a bitwise OR concat of the flag constants. + *
    Example: {@code manager.reset(AutoModRuleManager.NAME, AutoModRuleManager.RESPONSE);} + * + *

    Flag Constants: + *

      + *
    • {@link #NAME}
    • + *
    • {@link #ENABLED}
    • + *
    • {@link #RESPONSE}
    • + *
    • {@link #EXEMPT_ROLES}
    • + *
    • {@link #EXEMPT_CHANNELS}
    • + *
    • {@link #TRIGGER_METADATA}
    • + *
    + * + * @param fields + * Integer value containing the flags to reset. + * + * @return AutoModRuleManager for chaining convenience + */ + @Nonnull + @Override + AutoModRuleManager reset(long... fields); + + @Nonnull + @CheckReturnValue + AutoModRuleManager setName(@Nonnull String name); + + @Nonnull + @CheckReturnValue + AutoModRuleManager setEnabled(boolean enabled); + +// @Nonnull +// @CheckReturnValue +// AutoModRuleManager setEventType(@Nonnull AutoModEventType type); + + @Nonnull + @CheckReturnValue + AutoModRuleManager setResponses(@Nonnull Collection responses); + + @Nonnull + @CheckReturnValue + default AutoModRuleManager setResponses(@Nonnull AutoModResponse... responses) + { + Checks.noneNull(responses, "Responses"); + return setResponses(Arrays.asList(responses)); + } + + @Nonnull + @CheckReturnValue + AutoModRuleManager setExemptRoles(@Nonnull Collection roles); + + @Nonnull + @CheckReturnValue + default AutoModRuleManager setExemptRoles(@Nonnull Role... roles) + { + Checks.noneNull(roles, "Roles"); + return setExemptRoles(Arrays.asList(roles)); + } + + @Nonnull + @CheckReturnValue + AutoModRuleManager setExemptChannels(@Nonnull Collection channels); + + @Nonnull + @CheckReturnValue + default AutoModRuleManager setExemptChannels(@Nonnull GuildChannel... channels) + { + Checks.noneNull(channels, "Channels"); + return setExemptChannels(Arrays.asList(channels)); + } + + @Nonnull + @CheckReturnValue + AutoModRuleManager setTriggerConfig(@Nonnull TriggerConfig config); +} diff --git a/src/main/java/net/dv8tion/jda/internal/managers/AutoModRuleManagerImpl.java b/src/main/java/net/dv8tion/jda/internal/managers/AutoModRuleManagerImpl.java new file mode 100644 index 0000000000..2a7b58307e --- /dev/null +++ b/src/main/java/net/dv8tion/jda/internal/managers/AutoModRuleManagerImpl.java @@ -0,0 +1,133 @@ +/* + * Copyright 2015 Austin Keener, Michael Ritter, Florian Spieß, and the JDA contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.dv8tion.jda.internal.managers; + +import net.dv8tion.jda.api.entities.Guild; +import net.dv8tion.jda.api.entities.Role; +import net.dv8tion.jda.api.entities.automod.AutoModResponse; +import net.dv8tion.jda.api.entities.automod.AutoModTriggerType; +import net.dv8tion.jda.api.entities.automod.build.TriggerConfig; +import net.dv8tion.jda.api.entities.channel.middleman.GuildChannel; +import net.dv8tion.jda.api.managers.AutoModRuleManager; +import net.dv8tion.jda.api.requests.Route; +import net.dv8tion.jda.api.utils.data.DataArray; +import net.dv8tion.jda.api.utils.data.DataObject; +import net.dv8tion.jda.internal.utils.Checks; +import okhttp3.RequestBody; + +import javax.annotation.Nonnull; +import java.util.ArrayList; +import java.util.Collection; +import java.util.EnumMap; +import java.util.List; +import java.util.stream.Collectors; + +public class AutoModRuleManagerImpl extends ManagerBase implements AutoModRuleManager +{ + protected String name; + protected boolean enabled; + protected EnumMap responses; + protected List exemptRoles; + protected List exemptChannels; + protected TriggerConfig triggerConfig; + + public AutoModRuleManagerImpl(Guild guild, String ruleId) + { + super(guild.getJDA(), Route.AutoModeration.UPDATE_RULE.compile(guild.getId(), ruleId)); + } + + @Nonnull + @Override + public AutoModRuleManager setName(@Nonnull String name) + { + this.name = name; + set |= NAME; + return this; + } + + @Nonnull + @Override + public AutoModRuleManager setEnabled(boolean enabled) + { + this.enabled = enabled; + set |= ENABLED; + return this; + } + + @Nonnull + @Override + public AutoModRuleManager setResponses(@Nonnull Collection responses) + { + this.responses = new EnumMap<>(AutoModResponse.Type.class); + set |= RESPONSE; + return this; + } + + @Nonnull + @Override + public AutoModRuleManager setExemptRoles(@Nonnull Collection roles) + { + this.exemptRoles = new ArrayList<>(roles); + set |= EXEMPT_ROLES; + return this; + } + + @Nonnull + @Override + public AutoModRuleManager setExemptChannels(@Nonnull Collection channels) + { + this.exemptChannels = new ArrayList<>(channels); + set |= EXEMPT_CHANNELS; + return this; + } + + @Nonnull + @Override + public AutoModRuleManager setTriggerConfig(@Nonnull TriggerConfig config) + { + Checks.notNull(config, "TriggerConfig"); + Checks.check(config.getType() != AutoModTriggerType.UNKNOWN, "Unknown trigger type!"); + this.triggerConfig = config; + set |= TRIGGER_METADATA; + return this; + } + + @Override + protected RequestBody finalizeData() + { + DataObject body = DataObject.empty(); + + if (shouldUpdate(NAME)) + body.put("name", name); + if (shouldUpdate(ENABLED)) + body.put("enabled", enabled); + if (shouldUpdate(RESPONSE)) + body.put("actions", DataArray.fromCollection(responses.values())); + if (shouldUpdate(EXEMPT_ROLES)) + body.put("exempt_roles", DataArray.fromCollection(exemptRoles.stream().map(Role::getId).collect(Collectors.toList()))); + if (shouldUpdate(EXEMPT_CHANNELS)) + body.put("exempt_channels", DataArray.fromCollection(exemptChannels.stream().map(GuildChannel::getId).collect(Collectors.toList()))); + if (shouldUpdate(TRIGGER_METADATA)) + { + body.put("trigger_type", triggerConfig.getType().getKey()); + body.put("trigger_metadata", triggerConfig.toData()); + } + + reset(); + return getRequestBody(body); + } +} From 0097c21e5195ea0bafdfbea1b9d72cf27076dd2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Spie=C3=9F?= Date: Mon, 27 Mar 2023 16:24:51 +0200 Subject: [PATCH 11/39] Rename types for consistency --- ...ta.java => AbstractKeywordTriggerConfig.java} | 10 +++++----- ...iggerData.java => AbstractTriggerConfig.java} | 4 ++-- ...mRuleData.java => AntiSpamTriggerConfig.java} | 4 ++-- ...Data.java => CustomKeywordTriggerConfig.java} | 16 ++++++++-------- ...leData.java => MentionSpamTriggerConfig.java} | 6 +++--- ...Data.java => PresetKeywordTriggerConfig.java} | 12 ++++++------ .../entities/automod/build/TriggerConfig.java | 16 ++++++++-------- 7 files changed, 34 insertions(+), 34 deletions(-) rename src/main/java/net/dv8tion/jda/api/entities/automod/build/{AbstractKeywordRuleData.java => AbstractKeywordTriggerConfig.java} (85%) rename src/main/java/net/dv8tion/jda/api/entities/automod/build/{AbstractTriggerData.java => AbstractTriggerConfig.java} (88%) rename src/main/java/net/dv8tion/jda/api/entities/automod/build/{AntiSpamRuleData.java => AntiSpamTriggerConfig.java} (86%) rename src/main/java/net/dv8tion/jda/api/entities/automod/build/{CustomKeywordRuleData.java => CustomKeywordTriggerConfig.java} (86%) rename src/main/java/net/dv8tion/jda/api/entities/automod/build/{MentionRuleData.java => MentionSpamTriggerConfig.java} (86%) rename src/main/java/net/dv8tion/jda/api/entities/automod/build/{PresetKeywordRuleData.java => PresetKeywordTriggerConfig.java} (79%) diff --git a/src/main/java/net/dv8tion/jda/api/entities/automod/build/AbstractKeywordRuleData.java b/src/main/java/net/dv8tion/jda/api/entities/automod/build/AbstractKeywordTriggerConfig.java similarity index 85% rename from src/main/java/net/dv8tion/jda/api/entities/automod/build/AbstractKeywordRuleData.java rename to src/main/java/net/dv8tion/jda/api/entities/automod/build/AbstractKeywordTriggerConfig.java index 5e82d08aec..ec4c75f53e 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/automod/build/AbstractKeywordRuleData.java +++ b/src/main/java/net/dv8tion/jda/api/entities/automod/build/AbstractKeywordTriggerConfig.java @@ -25,11 +25,11 @@ import javax.annotation.Nonnull; import java.util.*; -public abstract class AbstractKeywordRuleData> extends AbstractTriggerData +public abstract class AbstractKeywordTriggerConfig> extends AbstractTriggerConfig { protected final List allowList = new ArrayList<>(); - protected AbstractKeywordRuleData(AutoModTriggerType triggerType) + protected AbstractKeywordTriggerConfig(AutoModTriggerType triggerType) { super(triggerType); } @@ -39,7 +39,7 @@ public B addAllowList(@Nonnull String... keywords) { Checks.noneNull(keywords, "Keywords"); Checks.check(this.allowList.size() + keywords.length <= maxAllowListAmount(), "Cannot add more than %d keywords!", maxAllowListAmount()); - Arrays.stream(keywords).forEach(AbstractKeywordRuleData::checkKeyword); + Arrays.stream(keywords).forEach(AbstractKeywordTriggerConfig::checkKeyword); Collections.addAll(allowList, keywords); return (B) this; } @@ -49,7 +49,7 @@ public B addAllowList(@Nonnull Collection keywords) { Checks.noneNull(keywords, "Keywords"); Checks.check(this.allowList.size() + keywords.size() <= maxAllowListAmount(), "Cannot add more than %d keywords!", maxAllowListAmount()); - keywords.forEach(AbstractKeywordRuleData::checkKeyword); + keywords.forEach(AbstractKeywordTriggerConfig::checkKeyword); allowList.addAll(keywords); return (B) this; } @@ -59,7 +59,7 @@ public B setAllowList(@Nonnull Collection keywords) { Checks.noneNull(keywords, "Keywords"); Checks.check(keywords.size() <= maxAllowListAmount(), "Cannot add more than %d keywords!", maxAllowListAmount()); - keywords.forEach(AbstractKeywordRuleData::checkKeyword); + keywords.forEach(AbstractKeywordTriggerConfig::checkKeyword); allowList.clear(); allowList.addAll(keywords); return (B) this; diff --git a/src/main/java/net/dv8tion/jda/api/entities/automod/build/AbstractTriggerData.java b/src/main/java/net/dv8tion/jda/api/entities/automod/build/AbstractTriggerConfig.java similarity index 88% rename from src/main/java/net/dv8tion/jda/api/entities/automod/build/AbstractTriggerData.java rename to src/main/java/net/dv8tion/jda/api/entities/automod/build/AbstractTriggerConfig.java index 07156731d7..0fd29fb2af 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/automod/build/AbstractTriggerData.java +++ b/src/main/java/net/dv8tion/jda/api/entities/automod/build/AbstractTriggerConfig.java @@ -21,11 +21,11 @@ import javax.annotation.Nonnull; -public class AbstractTriggerData> implements TriggerConfig +public class AbstractTriggerConfig> implements TriggerConfig { protected final AutoModTriggerType type; - protected AbstractTriggerData(AutoModTriggerType type) + protected AbstractTriggerConfig(AutoModTriggerType type) { this.type = type; } diff --git a/src/main/java/net/dv8tion/jda/api/entities/automod/build/AntiSpamRuleData.java b/src/main/java/net/dv8tion/jda/api/entities/automod/build/AntiSpamTriggerConfig.java similarity index 86% rename from src/main/java/net/dv8tion/jda/api/entities/automod/build/AntiSpamRuleData.java rename to src/main/java/net/dv8tion/jda/api/entities/automod/build/AntiSpamTriggerConfig.java index 22f0532190..3c9ec7d521 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/automod/build/AntiSpamRuleData.java +++ b/src/main/java/net/dv8tion/jda/api/entities/automod/build/AntiSpamTriggerConfig.java @@ -18,9 +18,9 @@ import net.dv8tion.jda.api.entities.automod.AutoModTriggerType; -public class AntiSpamRuleData extends AbstractTriggerData +public class AntiSpamTriggerConfig extends AbstractTriggerConfig { - protected AntiSpamRuleData() + protected AntiSpamTriggerConfig() { super(AutoModTriggerType.SPAM); } diff --git a/src/main/java/net/dv8tion/jda/api/entities/automod/build/CustomKeywordRuleData.java b/src/main/java/net/dv8tion/jda/api/entities/automod/build/CustomKeywordTriggerConfig.java similarity index 86% rename from src/main/java/net/dv8tion/jda/api/entities/automod/build/CustomKeywordRuleData.java rename to src/main/java/net/dv8tion/jda/api/entities/automod/build/CustomKeywordTriggerConfig.java index 2380079536..723e2da74d 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/automod/build/CustomKeywordRuleData.java +++ b/src/main/java/net/dv8tion/jda/api/entities/automod/build/CustomKeywordTriggerConfig.java @@ -28,18 +28,18 @@ import java.util.HashSet; import java.util.Set; -public class CustomKeywordRuleData extends AbstractKeywordRuleData +public class CustomKeywordTriggerConfig extends AbstractKeywordTriggerConfig { protected final Set keywords = new HashSet<>(); protected final Set patterns = new HashSet<>(); - protected CustomKeywordRuleData() + protected CustomKeywordTriggerConfig() { super(AutoModTriggerType.KEYWORD); } @Nonnull - public CustomKeywordRuleData addKeywords(@Nonnull String... keywords) + public CustomKeywordTriggerConfig addKeywords(@Nonnull String... keywords) { Checks.noneNull(keywords, "Keywords"); Checks.check(this.keywords.size() + keywords.length <= AutoModRule.MAX_KEYWORD_AMOUNT, "Cannot add more than %d keywords!", AutoModRule.MAX_KEYWORD_AMOUNT); @@ -51,7 +51,7 @@ public CustomKeywordRuleData addKeywords(@Nonnull String... keywords) } @Nonnull - public CustomKeywordRuleData addKeywords(@Nonnull Collection keywords) + public CustomKeywordTriggerConfig addKeywords(@Nonnull Collection keywords) { Checks.noneNull(keywords, "Keywords"); Checks.check(this.keywords.size() + keywords.size() <= AutoModRule.MAX_KEYWORD_AMOUNT, "Cannot add more than %d keywords!", AutoModRule.MAX_KEYWORD_AMOUNT); @@ -63,7 +63,7 @@ public CustomKeywordRuleData addKeywords(@Nonnull Collection keywords) } @Nonnull - public CustomKeywordRuleData setKeywords(@Nonnull Collection keywords) + public CustomKeywordTriggerConfig setKeywords(@Nonnull Collection keywords) { Checks.noneNull(keywords, "Keywords"); Checks.check(keywords.size() <= AutoModRule.MAX_KEYWORD_AMOUNT, "Cannot add more than %d keywords!", AutoModRule.MAX_KEYWORD_AMOUNT); @@ -77,7 +77,7 @@ public CustomKeywordRuleData setKeywords(@Nonnull Collection keywords) @Nonnull - public CustomKeywordRuleData addPatterns(@Nonnull String... patterns) + public CustomKeywordTriggerConfig addPatterns(@Nonnull String... patterns) { Checks.noneNull(patterns, "Patterns"); Checks.check(this.patterns.size() + patterns.length <= AutoModRule.MAX_PATTERN_AMOUNT, "Cannot add more than %d patterns!", AutoModRule.MAX_PATTERN_AMOUNT); @@ -89,7 +89,7 @@ public CustomKeywordRuleData addPatterns(@Nonnull String... patterns) } @Nonnull - public CustomKeywordRuleData addPatterns(@Nonnull Collection patterns) + public CustomKeywordTriggerConfig addPatterns(@Nonnull Collection patterns) { Checks.noneNull(patterns, "Patterns"); Checks.check(this.patterns.size() + patterns.size() <= AutoModRule.MAX_PATTERN_AMOUNT, "Cannot add more than %d patterns!", AutoModRule.MAX_PATTERN_AMOUNT); @@ -101,7 +101,7 @@ public CustomKeywordRuleData addPatterns(@Nonnull Collection patterns) } @Nonnull - public CustomKeywordRuleData setPatterns(@Nonnull Collection patterns) + public CustomKeywordTriggerConfig setPatterns(@Nonnull Collection patterns) { Checks.noneNull(patterns, "Patterns"); Checks.check(patterns.size() <= AutoModRule.MAX_PATTERN_AMOUNT, "Cannot add more than %d patterns!", AutoModRule.MAX_PATTERN_AMOUNT); diff --git a/src/main/java/net/dv8tion/jda/api/entities/automod/build/MentionRuleData.java b/src/main/java/net/dv8tion/jda/api/entities/automod/build/MentionSpamTriggerConfig.java similarity index 86% rename from src/main/java/net/dv8tion/jda/api/entities/automod/build/MentionRuleData.java rename to src/main/java/net/dv8tion/jda/api/entities/automod/build/MentionSpamTriggerConfig.java index 0cfbea8ad0..349e12c3a1 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/automod/build/MentionRuleData.java +++ b/src/main/java/net/dv8tion/jda/api/entities/automod/build/MentionSpamTriggerConfig.java @@ -23,18 +23,18 @@ import javax.annotation.Nonnull; -public class MentionRuleData extends AbstractTriggerData implements TriggerConfig +public class MentionSpamTriggerConfig extends AbstractTriggerConfig implements TriggerConfig { private int mentionLimit; - public MentionRuleData(int mentionLimit) + public MentionSpamTriggerConfig(int mentionLimit) { super(AutoModTriggerType.MENTION_SPAM); this.mentionLimit = mentionLimit; } @Nonnull - public MentionRuleData setMentionLimit(int mentionLimit) + public MentionSpamTriggerConfig setMentionLimit(int mentionLimit) { Checks.positive(mentionLimit, "Mention Limit"); Checks.check(mentionLimit <= AutoModRule.MAX_MENTION_LIMIT, "Mention Limit cannot be higher than %d. Provided: %d", AutoModRule.MAX_MENTION_LIMIT, mentionLimit); diff --git a/src/main/java/net/dv8tion/jda/api/entities/automod/build/PresetKeywordRuleData.java b/src/main/java/net/dv8tion/jda/api/entities/automod/build/PresetKeywordTriggerConfig.java similarity index 79% rename from src/main/java/net/dv8tion/jda/api/entities/automod/build/PresetKeywordRuleData.java rename to src/main/java/net/dv8tion/jda/api/entities/automod/build/PresetKeywordTriggerConfig.java index 42163833c1..00aaff7904 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/automod/build/PresetKeywordRuleData.java +++ b/src/main/java/net/dv8tion/jda/api/entities/automod/build/PresetKeywordTriggerConfig.java @@ -27,17 +27,17 @@ import java.util.Collections; import java.util.EnumSet; -public class PresetKeywordRuleData extends AbstractKeywordRuleData +public class PresetKeywordTriggerConfig extends AbstractKeywordTriggerConfig { private final EnumSet presets = EnumSet.noneOf(AutoModRule.KeywordPreset.class); - protected PresetKeywordRuleData() + protected PresetKeywordTriggerConfig() { super(AutoModTriggerType.KEYWORD_PRESET); } @Nonnull - public PresetKeywordRuleData enablePresets(@Nonnull AutoModRule.KeywordPreset... presets) + public PresetKeywordTriggerConfig enablePresets(@Nonnull AutoModRule.KeywordPreset... presets) { Checks.noneNull(presets, "Presets"); Collections.addAll(this.presets, presets); @@ -45,7 +45,7 @@ public PresetKeywordRuleData enablePresets(@Nonnull AutoModRule.KeywordPreset... } @Nonnull - public PresetKeywordRuleData enablePresets(@Nonnull Collection presets) + public PresetKeywordTriggerConfig enablePresets(@Nonnull Collection presets) { Checks.noneNull(presets, "Presets"); this.presets.addAll(presets); @@ -53,7 +53,7 @@ public PresetKeywordRuleData enablePresets(@Nonnull Collection presets) + public PresetKeywordTriggerConfig disablePresets(@Nonnull Collection presets) { Checks.noneNull(presets, "Presets"); this.presets.removeAll(presets); diff --git a/src/main/java/net/dv8tion/jda/api/entities/automod/build/TriggerConfig.java b/src/main/java/net/dv8tion/jda/api/entities/automod/build/TriggerConfig.java index 87743bb168..1bb79af42f 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/automod/build/TriggerConfig.java +++ b/src/main/java/net/dv8tion/jda/api/entities/automod/build/TriggerConfig.java @@ -27,26 +27,26 @@ public interface TriggerConfig extends SerializableData AutoModTriggerType getType(); @Nonnull - static MentionRuleData mentionSpam(int limit) + static MentionSpamTriggerConfig mentionSpam(int limit) { - return new MentionRuleData(limit); + return new MentionSpamTriggerConfig(limit); } @Nonnull - static AntiSpamRuleData antiSpam() + static AntiSpamTriggerConfig antiSpam() { - return new AntiSpamRuleData(); + return new AntiSpamTriggerConfig(); } @Nonnull - static CustomKeywordRuleData keywordFilter() + static CustomKeywordTriggerConfig keywordFilter() { - return new CustomKeywordRuleData(); + return new CustomKeywordTriggerConfig(); } @Nonnull - static PresetKeywordRuleData presetKeywordFilter() + static PresetKeywordTriggerConfig presetKeywordFilter() { - return new PresetKeywordRuleData(); + return new PresetKeywordTriggerConfig(); } } From 9c88e62e46678947d8130dc267e7e86b340b3827 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Spie=C3=9F?= Date: Mon, 27 Mar 2023 16:53:44 +0200 Subject: [PATCH 12/39] Add permission checks --- .../net/dv8tion/jda/api/entities/Guild.java | 13 +++------ .../jda/api/entities/automod/AutoModRule.java | 3 +- .../jda/internal/entities/GuildImpl.java | 29 +++++++++++-------- 3 files changed, 22 insertions(+), 23 deletions(-) diff --git a/src/main/java/net/dv8tion/jda/api/entities/Guild.java b/src/main/java/net/dv8tion/jda/api/entities/Guild.java index b9dbcb753e..11f396b050 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/Guild.java +++ b/src/main/java/net/dv8tion/jda/api/entities/Guild.java @@ -62,7 +62,6 @@ import net.dv8tion.jda.api.utils.cache.SortedSnowflakeCacheView; import net.dv8tion.jda.api.utils.concurrent.Task; import net.dv8tion.jda.internal.interactions.CommandDataImpl; -import net.dv8tion.jda.internal.managers.AutoModRuleManagerImpl; import net.dv8tion.jda.internal.requests.DeferredRestAction; import net.dv8tion.jda.internal.utils.Checks; import net.dv8tion.jda.internal.utils.EntityString; @@ -422,15 +421,11 @@ default RestAction retrieveAutoModRuleById(long id) @Nonnull @CheckReturnValue - RestAction createAutoModRule(@Nonnull AutoModRuleData data); + AuditableRestAction createAutoModRule(@Nonnull AutoModRuleData data); @Nonnull @CheckReturnValue - default AutoModRuleManager modifyAutoModRuleById(@Nonnull String id) - { - Checks.isSnowflake(id); - return new AutoModRuleManagerImpl(this, id); - } + AutoModRuleManager modifyAutoModRuleById(@Nonnull String id); @Nonnull @CheckReturnValue @@ -441,11 +436,11 @@ default AutoModRuleManager modifyAutoModRuleById(long id) @Nonnull @CheckReturnValue - RestAction deleteAutoModRuleById(@Nonnull String id); + AuditableRestAction deleteAutoModRuleById(@Nonnull String id); @Nonnull @CheckReturnValue - default RestAction deleteAutoModRuleById(long id) + default AuditableRestAction deleteAutoModRuleById(long id) { return deleteAutoModRuleById(Long.toUnsignedString(id)); } diff --git a/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModRule.java b/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModRule.java index 10eac0aa69..28218138e2 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModRule.java +++ b/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModRule.java @@ -23,7 +23,6 @@ import net.dv8tion.jda.api.entities.automod.build.TriggerConfig; import net.dv8tion.jda.api.entities.channel.middleman.GuildChannel; import net.dv8tion.jda.api.managers.AutoModRuleManager; -import net.dv8tion.jda.internal.managers.AutoModRuleManagerImpl; import javax.annotation.Nonnull; import java.util.EnumSet; @@ -118,7 +117,7 @@ default String getOwnerId() @Nonnull default AutoModRuleManager getManager() { - return new AutoModRuleManagerImpl(getGuild(), getId()); + return getGuild().modifyAutoModRuleById(getId()); } enum KeywordPreset diff --git a/src/main/java/net/dv8tion/jda/internal/entities/GuildImpl.java b/src/main/java/net/dv8tion/jda/internal/entities/GuildImpl.java index fb11eb2371..055a3bd50f 100644 --- a/src/main/java/net/dv8tion/jda/internal/entities/GuildImpl.java +++ b/src/main/java/net/dv8tion/jda/internal/entities/GuildImpl.java @@ -45,10 +45,7 @@ import net.dv8tion.jda.api.interactions.commands.PrivilegeConfig; import net.dv8tion.jda.api.interactions.commands.build.CommandData; import net.dv8tion.jda.api.interactions.commands.privileges.IntegrationPrivilege; -import net.dv8tion.jda.api.managers.AudioManager; -import net.dv8tion.jda.api.managers.GuildManager; -import net.dv8tion.jda.api.managers.GuildStickerManager; -import net.dv8tion.jda.api.managers.GuildWelcomeScreenManager; +import net.dv8tion.jda.api.managers.*; import net.dv8tion.jda.api.requests.GatewayIntent; import net.dv8tion.jda.api.requests.RestAction; import net.dv8tion.jda.api.requests.Route; @@ -67,10 +64,7 @@ import net.dv8tion.jda.internal.handle.EventCache; import net.dv8tion.jda.internal.interactions.CommandDataImpl; import net.dv8tion.jda.internal.interactions.command.CommandImpl; -import net.dv8tion.jda.internal.managers.AudioManagerImpl; -import net.dv8tion.jda.internal.managers.GuildManagerImpl; -import net.dv8tion.jda.internal.managers.GuildStickerManagerImpl; -import net.dv8tion.jda.internal.managers.GuildWelcomeScreenManagerImpl; +import net.dv8tion.jda.internal.managers.*; import net.dv8tion.jda.internal.requests.*; import net.dv8tion.jda.internal.requests.restaction.*; import net.dv8tion.jda.internal.requests.restaction.order.CategoryOrderActionImpl; @@ -397,20 +391,31 @@ public RestAction retrieveAutoModRuleById(@Nonnull String id) @Nonnull @Override - public RestAction createAutoModRule(@Nonnull AutoModRuleData rule) + public AuditableRestAction createAutoModRule(@Nonnull AutoModRuleData rule) { Checks.notNull(rule, "AutoMod Rule"); + checkPermission(Permission.MANAGE_SERVER); Route.CompiledRoute route = Route.AutoModeration.CREATE_RULE.compile(getId()); - return new RestActionImpl<>(api, route, rule.toData(), (response, request) -> AutoModRuleImpl.fromData(this, response.getObject())); + return new AuditableRestActionImpl<>(api, route, rule.toData(), (response, request) -> AutoModRuleImpl.fromData(this, response.getObject())); + } + + @Nonnull + @Override + public AutoModRuleManager modifyAutoModRuleById(@Nonnull String id) + { + Checks.isSnowflake(id); + checkPermission(Permission.MANAGE_SERVER); + return new AutoModRuleManagerImpl(this, id); } @Nonnull @Override - public RestAction deleteAutoModRuleById(@Nonnull String id) + public AuditableRestAction deleteAutoModRuleById(@Nonnull String id) { Checks.isSnowflake(id); + checkPermission(Permission.MANAGE_SERVER); Route.CompiledRoute route = Route.AutoModeration.DELETE_RULE.compile(getId(), id); - return new RestActionImpl<>(api, route); + return new AuditableRestActionImpl<>(api, route); } @Nonnull From 008096b93086c3be9d7a0e46b8e6310a1afeb072 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Spie=C3=9F?= Date: Mon, 27 Mar 2023 17:08:36 +0200 Subject: [PATCH 13/39] Add some more checks --- .../api/entities/automod/AutoModResponse.java | 23 ++++++++++++++++++- .../automod/build/AutoModRuleData.java | 21 ++++++++++++++++- .../jda/internal/entities/GuildImpl.java | 2 +- 3 files changed, 43 insertions(+), 3 deletions(-) diff --git a/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModResponse.java b/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModResponse.java index 62dcec2c26..593fa0d422 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModResponse.java +++ b/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModResponse.java @@ -24,6 +24,7 @@ import javax.annotation.Nonnull; import javax.annotation.Nullable; import java.time.Duration; +import java.util.EnumSet; public interface AutoModResponse extends SerializableData { @@ -64,15 +65,23 @@ enum Type { BLOCK_MESSAGE(1), SEND_ALERT_MESSAGE(2), - TIMEOUT(3), + TIMEOUT(3, EnumSet.of(AutoModTriggerType.KEYWORD, AutoModTriggerType.MENTION_SPAM)), UNKNOWN(-1) ; private final int key; + private final EnumSet supportedTypes; Type(int key) { this.key = key; + this.supportedTypes = EnumSet.complementOf(EnumSet.of(AutoModTriggerType.UNKNOWN)); + } + + Type(int key, EnumSet supportedTypes) + { + this.key = key; + this.supportedTypes = supportedTypes; } public int getKey() @@ -80,6 +89,18 @@ public int getKey() return key; } + @Nonnull + public EnumSet getSupportedTypes() + { + return EnumSet.copyOf(supportedTypes); + } + + public boolean isSupportedTrigger(@Nonnull AutoModTriggerType type) + { + Checks.notNull(type, "AutoModTriggerType"); + return supportedTypes.contains(type); + } + @Nonnull public static Type fromKey(int key) { diff --git a/src/main/java/net/dv8tion/jda/api/entities/automod/build/AutoModRuleData.java b/src/main/java/net/dv8tion/jda/api/entities/automod/build/AutoModRuleData.java index 9fc9cc6219..dff421887d 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/automod/build/AutoModRuleData.java +++ b/src/main/java/net/dv8tion/jda/api/entities/automod/build/AutoModRuleData.java @@ -16,10 +16,12 @@ package net.dv8tion.jda.api.entities.automod.build; +import net.dv8tion.jda.api.Permission; import net.dv8tion.jda.api.entities.Role; import net.dv8tion.jda.api.entities.automod.AutoModEventType; import net.dv8tion.jda.api.entities.automod.AutoModResponse; import net.dv8tion.jda.api.entities.automod.AutoModRule; +import net.dv8tion.jda.api.entities.automod.AutoModTriggerType; import net.dv8tion.jda.api.entities.channel.middleman.GuildChannel; import net.dv8tion.jda.api.utils.data.DataArray; import net.dv8tion.jda.api.utils.data.DataObject; @@ -31,6 +33,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.EnumMap; +import java.util.EnumSet; public class AutoModRuleData implements SerializableData { @@ -165,10 +168,26 @@ public AutoModRuleData setTriggerConfig(@Nonnull TriggerConfig config) return this; } + @Nonnull + public EnumSet getRequiredPermissions() + { + if (actions.containsKey(AutoModResponse.Type.TIMEOUT)) + return EnumSet.of(Permission.MANAGE_SERVER, Permission.MODERATE_MEMBERS); + else + return EnumSet.of(Permission.MANAGE_SERVER); + } + @Nonnull @Override public DataObject toData() { + AutoModTriggerType triggerType = triggerMetadata.getType(); + for (AutoModResponse response : actions.values()) + { + if (!response.getType().isSupportedTrigger(triggerType)) + throw new IllegalStateException("Cannot create a rule of trigger type " + triggerType + " with response type " + response.getType()); + } + DataObject data = DataObject.empty() .put("name", name) .put("enabled", enabled) @@ -179,7 +198,7 @@ public DataObject toData() data.put("exempt_roles", DataArray.fromCollection(exemptRoles)); data.put("exempt_channels", DataArray.fromCollection(exemptChannels)); - data.put("trigger_type", triggerMetadata.getType().getKey()); + data.put("trigger_type", triggerType.getKey()); data.put("trigger_metadata", triggerMetadata.toData()); return data; diff --git a/src/main/java/net/dv8tion/jda/internal/entities/GuildImpl.java b/src/main/java/net/dv8tion/jda/internal/entities/GuildImpl.java index 055a3bd50f..aa14fd5c9a 100644 --- a/src/main/java/net/dv8tion/jda/internal/entities/GuildImpl.java +++ b/src/main/java/net/dv8tion/jda/internal/entities/GuildImpl.java @@ -394,7 +394,7 @@ public RestAction retrieveAutoModRuleById(@Nonnull String id) public AuditableRestAction createAutoModRule(@Nonnull AutoModRuleData rule) { Checks.notNull(rule, "AutoMod Rule"); - checkPermission(Permission.MANAGE_SERVER); + rule.getRequiredPermissions().forEach(this::checkPermission); Route.CompiledRoute route = Route.AutoModeration.CREATE_RULE.compile(getId()); return new AuditableRestActionImpl<>(api, route, rule.toData(), (response, request) -> AutoModRuleImpl.fromData(this, response.getObject())); } From 33a1b52dc6a44c6867b51c827afc988a446be13e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Spie=C3=9F?= Date: Wed, 29 Mar 2023 14:38:16 +0200 Subject: [PATCH 14/39] Update GatewayIntent#fromEvents --- .../java/net/dv8tion/jda/api/requests/GatewayIntent.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/main/java/net/dv8tion/jda/api/requests/GatewayIntent.java b/src/main/java/net/dv8tion/jda/api/requests/GatewayIntent.java index dbca752af8..c7eb6f6a9f 100644 --- a/src/main/java/net/dv8tion/jda/api/requests/GatewayIntent.java +++ b/src/main/java/net/dv8tion/jda/api/requests/GatewayIntent.java @@ -22,6 +22,8 @@ import net.dv8tion.jda.api.entities.Member; import net.dv8tion.jda.api.entities.Message; import net.dv8tion.jda.api.events.GenericEvent; +import net.dv8tion.jda.api.events.automod.AutoModExecutionEvent; +import net.dv8tion.jda.api.events.automod.GenericAutoModRuleEvent; import net.dv8tion.jda.api.events.emoji.GenericEmojiEvent; import net.dv8tion.jda.api.events.guild.GuildAuditLogEntryCreateEvent; import net.dv8tion.jda.api.events.guild.GuildBanEvent; @@ -425,6 +427,11 @@ else if (GenericMessageEvent.class.isAssignableFrom(event)) else if (UserTypingEvent.class.isAssignableFrom(event)) Collections.addAll(intents, GUILD_MESSAGE_TYPING, DIRECT_MESSAGE_TYPING); + + else if (AutoModExecutionEvent.class.isAssignableFrom(event)) + intents.add(AUTO_MODERATION_EXECUTION); + else if (GenericAutoModRuleEvent.class.isAssignableFrom(event)) + intents.add(AUTO_MODERATION_CONFIGURATION); } return intents; } From 9ababb8d08fb2062afee5d37dd105212e2c0862e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Spie=C3=9F?= Date: Wed, 29 Mar 2023 14:41:29 +0200 Subject: [PATCH 15/39] Allow passing keywords and presets in factory --- .../entities/automod/build/TriggerConfig.java | 22 +++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/src/main/java/net/dv8tion/jda/api/entities/automod/build/TriggerConfig.java b/src/main/java/net/dv8tion/jda/api/entities/automod/build/TriggerConfig.java index 1bb79af42f..1d951d7545 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/automod/build/TriggerConfig.java +++ b/src/main/java/net/dv8tion/jda/api/entities/automod/build/TriggerConfig.java @@ -16,10 +16,12 @@ package net.dv8tion.jda.api.entities.automod.build; +import net.dv8tion.jda.api.entities.automod.AutoModRule; import net.dv8tion.jda.api.entities.automod.AutoModTriggerType; import net.dv8tion.jda.api.utils.data.SerializableData; import javax.annotation.Nonnull; +import java.util.Collection; public interface TriggerConfig extends SerializableData { @@ -39,14 +41,26 @@ static AntiSpamTriggerConfig antiSpam() } @Nonnull - static CustomKeywordTriggerConfig keywordFilter() + static CustomKeywordTriggerConfig keywordFilter(@Nonnull Collection keywords) { - return new CustomKeywordTriggerConfig(); + return new CustomKeywordTriggerConfig().addKeywords(keywords); } @Nonnull - static PresetKeywordTriggerConfig presetKeywordFilter() + static CustomKeywordTriggerConfig keywordFilter(@Nonnull String... keywords) { - return new PresetKeywordTriggerConfig(); + return new CustomKeywordTriggerConfig().addKeywords(keywords); + } + + @Nonnull + static PresetKeywordTriggerConfig presetKeywordFilter(@Nonnull Collection presets) + { + return new PresetKeywordTriggerConfig().enablePresets(presets); + } + + @Nonnull + static PresetKeywordTriggerConfig presetKeywordFilter(@Nonnull AutoModRule.KeywordPreset... presets) + { + return new PresetKeywordTriggerConfig().enablePresets(presets); } } From cd711e43871cb41d947cb9e8735b73d5e490ea3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Spie=C3=9F?= Date: Wed, 29 Mar 2023 14:58:49 +0200 Subject: [PATCH 16/39] Add check for unknown preset --- .../build/PresetKeywordTriggerConfig.java | 18 +++++++++++++----- .../dv8tion/jda/internal/utils/Helpers.java | 5 +++++ 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/src/main/java/net/dv8tion/jda/api/entities/automod/build/PresetKeywordTriggerConfig.java b/src/main/java/net/dv8tion/jda/api/entities/automod/build/PresetKeywordTriggerConfig.java index 00aaff7904..0b04bafece 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/automod/build/PresetKeywordTriggerConfig.java +++ b/src/main/java/net/dv8tion/jda/api/entities/automod/build/PresetKeywordTriggerConfig.java @@ -18,9 +18,9 @@ import net.dv8tion.jda.api.entities.automod.AutoModRule; import net.dv8tion.jda.api.entities.automod.AutoModTriggerType; -import net.dv8tion.jda.api.utils.data.DataArray; import net.dv8tion.jda.api.utils.data.DataObject; import net.dv8tion.jda.internal.utils.Checks; +import net.dv8tion.jda.internal.utils.Helpers; import javax.annotation.Nonnull; import java.util.Collection; @@ -39,7 +39,9 @@ protected PresetKeywordTriggerConfig() @Nonnull public PresetKeywordTriggerConfig enablePresets(@Nonnull AutoModRule.KeywordPreset... presets) { - Checks.noneNull(presets, "Presets"); + Checks.notNull(presets, "Presets"); + for (AutoModRule.KeywordPreset preset : presets) + checkKnown(preset); Collections.addAll(this.presets, presets); return this; } @@ -47,7 +49,8 @@ public PresetKeywordTriggerConfig enablePresets(@Nonnull AutoModRule.KeywordPres @Nonnull public PresetKeywordTriggerConfig enablePresets(@Nonnull Collection presets) { - Checks.noneNull(presets, "Presets"); + Checks.notNull(presets, "Presets"); + presets.forEach(PresetKeywordTriggerConfig::checkKnown); this.presets.addAll(presets); return this; } @@ -75,13 +78,18 @@ protected int maxAllowListAmount() return AutoModRule.MAX_ALLOWLIST_PRESET_AMOUNT; } + private static void checkKnown(AutoModRule.KeywordPreset preset) + { + Checks.notNull(preset, "Presets"); + Checks.check(preset != AutoModRule.KeywordPreset.UNKNOWN, "Cannot use unknown preset"); + } + @Nonnull @Override public DataObject toData() { DataObject data = super.toData(); - presets.remove(AutoModRule.KeywordPreset.UNKNOWN); - data.put("presets", DataArray.fromCollection(presets)); + data.put("presets", presets.stream().map(AutoModRule.KeywordPreset::getKey).collect(Helpers.toDataArray())); return data; } } diff --git a/src/main/java/net/dv8tion/jda/internal/utils/Helpers.java b/src/main/java/net/dv8tion/jda/internal/utils/Helpers.java index 05b7f0f5b3..84fa4ab311 100644 --- a/src/main/java/net/dv8tion/jda/internal/utils/Helpers.java +++ b/src/main/java/net/dv8tion/jda/internal/utils/Helpers.java @@ -316,4 +316,9 @@ public static boolean hasCause(Throwable throwable, Class c { return Collectors.collectingAndThen(Collectors.toList(), Collections::unmodifiableList); } + + public static Collector toDataArray() + { + return Collector.of(DataArray::empty, DataArray::add, DataArray::addAll); + } } From c5f2efae052010bfd6e8a44c566b9f87afc6b38a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Spie=C3=9F?= Date: Wed, 29 Mar 2023 15:01:43 +0200 Subject: [PATCH 17/39] Add TriggerConfig#patternFilter --- .../jda/api/entities/automod/AutoModRule.java | 12 ++++++------ .../api/entities/automod/build/TriggerConfig.java | 12 ++++++++++++ 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModRule.java b/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModRule.java index 28218138e2..f67bfc6546 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModRule.java +++ b/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModRule.java @@ -41,27 +41,27 @@ public interface AutoModRule extends ISnowflake */ int MAX_RULE_NAME_LENGTH = 100; /** - * The maximum length of a keyword in {@link TriggerConfig#keywordFilter()}. ({@value}) + * The maximum length of a keyword in {@link TriggerConfig#keywordFilter(String...)}. ({@value}) */ int MAX_KEYWORD_LENGTH = 60; /** - * The maximum amount of keywords in {@link TriggerConfig#keywordFilter()}. ({@value}) + * The maximum amount of keywords in {@link TriggerConfig#keywordFilter(String...)}. ({@value}) */ int MAX_KEYWORD_AMOUNT = 1000; /** - * The maximum amount of whitelisted keywords in {@link TriggerConfig#keywordFilter()}. ({@value}) + * The maximum amount of whitelisted keywords in {@link TriggerConfig#keywordFilter(String...)}. ({@value}) */ int MAX_ALLOWLIST_CUSTOM_AMOUNT = 100; /** - * The maximum amount of whitelisted keywords in {@link TriggerConfig#presetKeywordFilter()}. ({@value}) + * The maximum amount of whitelisted keywords in {@link TriggerConfig#presetKeywordFilter(KeywordPreset...)}. ({@value}) */ int MAX_ALLOWLIST_PRESET_AMOUNT = 1000; /** - * The maximum length of a regex pattern in {@link TriggerConfig#keywordFilter()}. ({@value}) + * The maximum length of a regex pattern in {@link TriggerConfig#patternFilter(String...)}. ({@value}) */ int MAX_PATTERN_LENGTH = 260; /** - * The maximum amount of regex patterns in {@link TriggerConfig#keywordFilter()}. ({@value}) + * The maximum amount of regex patterns in {@link TriggerConfig#patternFilter(String...)}. ({@value}) */ int MAX_PATTERN_AMOUNT = 10; /** diff --git a/src/main/java/net/dv8tion/jda/api/entities/automod/build/TriggerConfig.java b/src/main/java/net/dv8tion/jda/api/entities/automod/build/TriggerConfig.java index 1d951d7545..21fdd9371d 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/automod/build/TriggerConfig.java +++ b/src/main/java/net/dv8tion/jda/api/entities/automod/build/TriggerConfig.java @@ -52,6 +52,18 @@ static CustomKeywordTriggerConfig keywordFilter(@Nonnull String... keywords) return new CustomKeywordTriggerConfig().addKeywords(keywords); } + @Nonnull + static CustomKeywordTriggerConfig patternFilter(@Nonnull Collection keywords) + { + return new CustomKeywordTriggerConfig().addPatterns(keywords); + } + + @Nonnull + static CustomKeywordTriggerConfig patternFilter(@Nonnull String... keywords) + { + return new CustomKeywordTriggerConfig().addPatterns(keywords); + } + @Nonnull static PresetKeywordTriggerConfig presetKeywordFilter(@Nonnull Collection presets) { From ebbdf9a35fa707daf2fd3e1859e68805f742ea1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Spie=C3=9F?= Date: Wed, 29 Mar 2023 15:26:04 +0200 Subject: [PATCH 18/39] Add relevant audit-log features --- .../net/dv8tion/jda/api/audit/ActionType.java | 30 +++++++++++++++++++ .../dv8tion/jda/api/audit/AuditLogKey.java | 22 +++++++++++++- .../net/dv8tion/jda/api/audit/TargetType.java | 1 + 3 files changed, 52 insertions(+), 1 deletion(-) diff --git a/src/main/java/net/dv8tion/jda/api/audit/ActionType.java b/src/main/java/net/dv8tion/jda/api/audit/ActionType.java index c77764b6ca..014fd1713a 100644 --- a/src/main/java/net/dv8tion/jda/api/audit/ActionType.java +++ b/src/main/java/net/dv8tion/jda/api/audit/ActionType.java @@ -586,6 +586,36 @@ public enum ActionType */ APPLICATION_COMMAND_PRIVILEGES_UPDATE(121, TargetType.INTEGRATION), + /** + * A moderator created a new {@link net.dv8tion.jda.api.entities.automod.AutoModRule AutoModRule} + */ + AUTO_MODERATION_RULE_CREATE(140, TargetType.AUTO_MODERATION_RULE), + + /** + * A moderator updated an existing {@link net.dv8tion.jda.api.entities.automod.AutoModRule AutoModRule} + */ + AUTO_MODERATION_RULE_UPDATE(141, TargetType.AUTO_MODERATION_RULE), + + /** + * A moderator deleted an existing {@link net.dv8tion.jda.api.entities.automod.AutoModRule AutoModRule} + */ + AUTO_MODERATION_RULE_DELETE(142, TargetType.AUTO_MODERATION_RULE), + + /** + * An automod rule blocked a message from being sent + */ + AUTO_MODERATION_RULE_BLOCK_MESSAGE( 143, TargetType.UNKNOWN), + + /** + * An automod rule sent an alert to a channel + */ + AUTO_MODERATION_FLAG_TO_CHANNEL( 144, TargetType.UNKNOWN), + + /** + * An automod rule put a user in {@link Member#isTimedOut() timeout} + */ + AUTO_MODERATION_USER_COMMUNICATION_DISABLED(145, TargetType.UNKNOWN), + UNKNOWN(-1, TargetType.UNKNOWN); private final int key; diff --git a/src/main/java/net/dv8tion/jda/api/audit/AuditLogKey.java b/src/main/java/net/dv8tion/jda/api/audit/AuditLogKey.java index 3c2b45da6e..d2bdb356b6 100644 --- a/src/main/java/net/dv8tion/jda/api/audit/AuditLogKey.java +++ b/src/main/java/net/dv8tion/jda/api/audit/AuditLogKey.java @@ -20,6 +20,8 @@ import net.dv8tion.jda.annotations.ForRemoval; import net.dv8tion.jda.annotations.ReplaceWith; import net.dv8tion.jda.api.entities.Guild; +import net.dv8tion.jda.api.entities.automod.AutoModRule; +import net.dv8tion.jda.api.entities.automod.AutoModTriggerType; import net.dv8tion.jda.api.entities.channel.Channel; import net.dv8tion.jda.api.entities.channel.ChannelType; import net.dv8tion.jda.api.entities.channel.attribute.ICategorizableChannel; @@ -657,7 +659,25 @@ public enum AuditLogKey * *

    Expected type: int */ - INVITE_MAX_USES("max_uses"); + INVITE_MAX_USES("max_uses"), + + // AUTO MODERATION + /** + * Change of the {@link AutoModRule#getName()} for the target {@link AutoModRule} + * + *

    Expected type: String + */ + AUTO_MODERATION_RULE_NAME("auto_moderation_rule_name"), + + /** + * The {@link AutoModRule#getTriggerType()} for an {@link AutoModRule} trigger + * + *

    Use with {@link AutoModTriggerType#fromKey(int)} + * + *

    Expected type: int + */ + AUTO_MODERATION_RULE_TRIGGER_TYPE("auto_moderation_rule_trigger_type"), + ; private final String key; diff --git a/src/main/java/net/dv8tion/jda/api/audit/TargetType.java b/src/main/java/net/dv8tion/jda/api/audit/TargetType.java index 98c5918365..5007405fb2 100644 --- a/src/main/java/net/dv8tion/jda/api/audit/TargetType.java +++ b/src/main/java/net/dv8tion/jda/api/audit/TargetType.java @@ -43,5 +43,6 @@ public enum TargetType STICKER, THREAD, SCHEDULED_EVENT, + AUTO_MODERATION_RULE, UNKNOWN } From 0870ddf4b076f8c5e6c250db5b05f7ae8accabdb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Spie=C3=9F?= Date: Wed, 29 Mar 2023 18:29:30 +0200 Subject: [PATCH 19/39] Add docs to trigger configs --- .../jda/api/entities/automod/AutoModRule.java | 7 + .../entities/automod/AutoModTriggerType.java | 36 ++++ .../build/AbstractKeywordTriggerConfig.java | 67 +++++++ .../automod/build/AbstractTriggerConfig.java | 11 ++ .../automod/build/AntiSpamTriggerConfig.java | 3 + .../build/CustomKeywordTriggerConfig.java | 137 +++++++++++++- .../build/MentionSpamTriggerConfig.java | 14 ++ .../build/PresetKeywordTriggerConfig.java | 47 +++++ .../entities/automod/build/TriggerConfig.java | 167 +++++++++++++++++- 9 files changed, 482 insertions(+), 7 deletions(-) diff --git a/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModRule.java b/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModRule.java index f67bfc6546..81c287675e 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModRule.java +++ b/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModRule.java @@ -23,6 +23,7 @@ import net.dv8tion.jda.api.entities.automod.build.TriggerConfig; import net.dv8tion.jda.api.entities.channel.middleman.GuildChannel; import net.dv8tion.jda.api.managers.AutoModRuleManager; +import net.dv8tion.jda.api.requests.restaction.AuditableRestAction; import javax.annotation.Nonnull; import java.util.EnumSet; @@ -120,6 +121,12 @@ default AutoModRuleManager getManager() return getGuild().modifyAutoModRuleById(getId()); } + @Nonnull + default AuditableRestAction delete() + { + return getGuild().deleteAutoModRuleById(getId()); + } + enum KeywordPreset { PROFANITY(1), diff --git a/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModTriggerType.java b/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModTriggerType.java index 27c9f030ba..ccc932582e 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModTriggerType.java +++ b/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModTriggerType.java @@ -18,12 +18,30 @@ import javax.annotation.Nonnull; +/** + * The type which defines what triggers an {@link AutoModRule}. + */ public enum AutoModTriggerType { + /** + * The rule is triggered by user content containing specific keywords or phrases. + */ KEYWORD(1, 6), + /** + * The rule is triggered by user content containing classified spam content. + */ SPAM(3, 1), + /** + * The rule is triggered by user content containing keywords from a predefined list (such as {@link AutoModRule.KeywordPreset#SLURS slurs}). + */ KEYWORD_PRESET(4, 1), + /** + * The rule is triggered by user content containing more than the allowed number of mentions. + */ MENTION_SPAM(5, 1), + /** + * Placeholder for unknown trigger types that haven't been added yet. + */ UNKNOWN(-1, 1), ; @@ -36,16 +54,34 @@ public enum AutoModTriggerType this.maxPerGuild = maxPerGuild; } + /** + * The raw API key used to indicate this type. + * + * @return The int key + */ public int getKey() { return key; } + /** + * The maximum number of rules that can use this trigger type in a guild. + * + * @return The maximum number of rules + */ public int getMaxPerGuild() { return maxPerGuild; } + /** + * The {@link AutoModTriggerType} that matches the provided key. + * + * @param key + * The key to match + * + * @return The matching {@link AutoModTriggerType} or {@link #UNKNOWN} + */ @Nonnull public static AutoModTriggerType fromKey(int key) { diff --git a/src/main/java/net/dv8tion/jda/api/entities/automod/build/AbstractKeywordTriggerConfig.java b/src/main/java/net/dv8tion/jda/api/entities/automod/build/AbstractKeywordTriggerConfig.java index ec4c75f53e..ae7047d4e1 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/automod/build/AbstractKeywordTriggerConfig.java +++ b/src/main/java/net/dv8tion/jda/api/entities/automod/build/AbstractKeywordTriggerConfig.java @@ -25,6 +25,13 @@ import javax.annotation.Nonnull; import java.util.*; +/** + * Abstract for all keyword trigger types. + * + * @param + * The builder type + */ +@SuppressWarnings("unchecked") public abstract class AbstractKeywordTriggerConfig> extends AbstractTriggerConfig { protected final List allowList = new ArrayList<>(); @@ -34,6 +41,26 @@ protected AbstractKeywordTriggerConfig(AutoModTriggerType triggerType) super(triggerType); } + /** + * Add keywords to the allow list. + *

    Keywords added to the allow list will not be considered as a match and won't trigger the rule execution. + * + *

    Keywords follow the same rules as {@link CustomKeywordTriggerConfig#addKeywords(String...)}. + * + * @param keywords + * The keywords to allow + * + * @throws IllegalArgumentException + *

      + *
    • If any of the keywords is empty, blank, or null
    • + *
    • If more than the allowed number of keywords are added to the list + * ({@value AutoModRule#MAX_ALLOWLIST_CUSTOM_AMOUNT} for custom keyword lists, + * {@value AutoModRule#MAX_ALLOWLIST_PRESET_AMOUNT} for preset keyword lists)
    • + *
    • If any keyword is longer than {@link AutoModRule#MAX_KEYWORD_LENGTH}
    • + *
    + * + * @return The current config for chaining convenience + */ @Nonnull public B addAllowList(@Nonnull String... keywords) { @@ -44,6 +71,26 @@ public B addAllowList(@Nonnull String... keywords) return (B) this; } + /** + * Add keywords to the allow list. + *

    Keywords added to the allow list will not be considered as a match and won't trigger the rule execution. + * + *

    Keywords follow the same rules as {@link CustomKeywordTriggerConfig#addKeywords(String...)}. + * + * @param keywords + * The keywords to allow + * + * @throws IllegalArgumentException + *

      + *
    • If any of the keywords is empty, blank, or null
    • + *
    • If more than the allowed number of keywords are added to the list + * ({@value AutoModRule#MAX_ALLOWLIST_CUSTOM_AMOUNT} for custom keyword lists, + * {@value AutoModRule#MAX_ALLOWLIST_PRESET_AMOUNT} for preset keyword lists)
    • + *
    • If any keyword is longer than {@link AutoModRule#MAX_KEYWORD_LENGTH}
    • + *
    + * + * @return The current config for chaining convenience + */ @Nonnull public B addAllowList(@Nonnull Collection keywords) { @@ -54,6 +101,26 @@ public B addAllowList(@Nonnull Collection keywords) return (B) this; } + /** + * Change the allow list to the provided keywords. + *

    Keywords added to the allow list will not be considered as a match and won't trigger the rule execution. + * + *

    Keywords follow the same rules as {@link CustomKeywordTriggerConfig#addKeywords(String...)}. + * + * @param keywords + * The keywords to allow + * + * @throws IllegalArgumentException + *

      + *
    • If any of the keywords is empty, blank, or null
    • + *
    • If more than the allowed number of keywords are added to the list + * ({@value AutoModRule#MAX_ALLOWLIST_CUSTOM_AMOUNT} for custom keyword lists, + * {@value AutoModRule#MAX_ALLOWLIST_PRESET_AMOUNT} for preset keyword lists)
    • + *
    • If any keyword is longer than {@link AutoModRule#MAX_KEYWORD_LENGTH}
    • + *
    + * + * @return The current config for chaining convenience + */ @Nonnull public B setAllowList(@Nonnull Collection keywords) { diff --git a/src/main/java/net/dv8tion/jda/api/entities/automod/build/AbstractTriggerConfig.java b/src/main/java/net/dv8tion/jda/api/entities/automod/build/AbstractTriggerConfig.java index 0fd29fb2af..fc524a9186 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/automod/build/AbstractTriggerConfig.java +++ b/src/main/java/net/dv8tion/jda/api/entities/automod/build/AbstractTriggerConfig.java @@ -21,6 +21,12 @@ import javax.annotation.Nonnull; +/** + * Abstract base class for all trigger configurations. + * + * @param + * The builder type + */ public class AbstractTriggerConfig> implements TriggerConfig { protected final AutoModTriggerType type; @@ -30,6 +36,11 @@ protected AbstractTriggerConfig(AutoModTriggerType type) this.type = type; } + /** + * The type of trigger this config applies to. + * + * @return {@link AutoModTriggerType} + */ @Nonnull @Override public AutoModTriggerType getType() diff --git a/src/main/java/net/dv8tion/jda/api/entities/automod/build/AntiSpamTriggerConfig.java b/src/main/java/net/dv8tion/jda/api/entities/automod/build/AntiSpamTriggerConfig.java index 3c9ec7d521..c730f55d08 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/automod/build/AntiSpamTriggerConfig.java +++ b/src/main/java/net/dv8tion/jda/api/entities/automod/build/AntiSpamTriggerConfig.java @@ -18,6 +18,9 @@ import net.dv8tion.jda.api.entities.automod.AutoModTriggerType; +/** + * Configuration for the {@link net.dv8tion.jda.api.entities.automod.AutoModTriggerType#SPAM SPAM} trigger. + */ public class AntiSpamTriggerConfig extends AbstractTriggerConfig { protected AntiSpamTriggerConfig() diff --git a/src/main/java/net/dv8tion/jda/api/entities/automod/build/CustomKeywordTriggerConfig.java b/src/main/java/net/dv8tion/jda/api/entities/automod/build/CustomKeywordTriggerConfig.java index 723e2da74d..33031cfc93 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/automod/build/CustomKeywordTriggerConfig.java +++ b/src/main/java/net/dv8tion/jda/api/entities/automod/build/CustomKeywordTriggerConfig.java @@ -28,6 +28,9 @@ import java.util.HashSet; import java.util.Set; +/** + * Configuration for a {@link net.dv8tion.jda.api.entities.automod.AutoModTriggerType#KEYWORD KEYWORD} trigger. + */ public class CustomKeywordTriggerConfig extends AbstractKeywordTriggerConfig { protected final Set keywords = new HashSet<>(); @@ -38,6 +41,29 @@ protected CustomKeywordTriggerConfig() super(AutoModTriggerType.KEYWORD); } + /** + * Add more keywords match against. + *
    Keywords are matched case-insensitively, and may also contain whitespace. + * + *

    You can use wildcards at the keyword boundaries to extend the matches: + *
    {@code "foo*"} can match {@code "foo"}, {@code "foobar"}, {@code "foo-bar"}, etc. + *
    {@code "*foo*"} can match {@code "foo"}, {@code "foobar"}, {@code "barfoo"}, etc. + *
    {@code "*foo"} can match {@code "foo"}, {@code "barfoo"}, {@code "bar-foo"}, etc. + * + *

    You can also use regex patterns using {@link #patternFilter(String...)}. + * + * @param keywords + * The keywords to match + * + * @throws IllegalArgumentException + *

      + *
    • If any of the keywords are empty, blank, or null
    • + *
    • If more than {@value AutoModRule#MAX_KEYWORD_AMOUNT} keywords are added
    • + *
    • If any of the keywords is longer than {@value AutoModRule#MAX_KEYWORD_LENGTH} characters
    • + *
    + * + * @return The current config for chaining convenience + */ @Nonnull public CustomKeywordTriggerConfig addKeywords(@Nonnull String... keywords) { @@ -50,6 +76,29 @@ public CustomKeywordTriggerConfig addKeywords(@Nonnull String... keywords) return this; } + /** + * Add more keywords match against. + *
    Keywords are matched case-insensitively, and may also contain whitespace. + * + *

    You can use wildcards at the keyword boundaries to extend the matches: + *
    {@code "foo*"} can match {@code "foo"}, {@code "foobar"}, {@code "foo-bar"}, etc. + *
    {@code "*foo*"} can match {@code "foo"}, {@code "foobar"}, {@code "barfoo"}, etc. + *
    {@code "*foo"} can match {@code "foo"}, {@code "barfoo"}, {@code "bar-foo"}, etc. + * + *

    You can also use regex patterns using {@link #patternFilter(Collection)}. + * + * @param keywords + * The keywords to match + * + * @throws IllegalArgumentException + *

      + *
    • If any of the keywords are empty, blank, or null
    • + *
    • If more than {@value AutoModRule#MAX_KEYWORD_AMOUNT} keywords are added
    • + *
    • If any of the keywords is longer than {@value AutoModRule#MAX_KEYWORD_LENGTH} characters
    • + *
    + * + * @return The current config for chaining convenience + */ @Nonnull public CustomKeywordTriggerConfig addKeywords(@Nonnull Collection keywords) { @@ -62,6 +111,29 @@ public CustomKeywordTriggerConfig addKeywords(@Nonnull Collection keywor return this; } + /** + * Changes the keywords to match against to the new list. + *
    Keywords are matched case-insensitively, and may also contain whitespace. + * + *

    You can use wildcards at the keyword boundaries to extend the matches: + *
    {@code "foo*"} can match {@code "foo"}, {@code "foobar"}, {@code "foo-bar"}, etc. + *
    {@code "*foo*"} can match {@code "foo"}, {@code "foobar"}, {@code "barfoo"}, etc. + *
    {@code "*foo"} can match {@code "foo"}, {@code "barfoo"}, {@code "bar-foo"}, etc. + * + *

    You can also use regex patterns using {@link #patternFilter(Collection)}. + * + * @param keywords + * The keywords to match + * + * @throws IllegalArgumentException + *

      + *
    • If any of the keywords are empty, blank, or null
    • + *
    • If more than {@value AutoModRule#MAX_KEYWORD_AMOUNT} keywords are added
    • + *
    • If any of the keywords is longer than {@value AutoModRule#MAX_KEYWORD_LENGTH} characters
    • + *
    + * + * @return The current config for chaining convenience + */ @Nonnull public CustomKeywordTriggerConfig setKeywords(@Nonnull Collection keywords) { @@ -76,6 +148,27 @@ public CustomKeywordTriggerConfig setKeywords(@Nonnull Collection keywor } + /** + * Add keywords regex patterns to match against. + *
    Keyword patterns are matched case-insensitively, and may also contain whitespace. + * + *

    Patterns may use anything supported by the rust regex crate. + * You can use a validator such as Rustexp to validate your pattern. + * + *

    You can also use simple substring keywords using {@link #keywordFilter(String...)}. + * + * @param patterns + * The keyword patterns to match + * + * @throws IllegalArgumentException + *

      + *
    • If any of the patterns are empty, blank, or null
    • + *
    • If more than {@value AutoModRule#MAX_PATTERN_AMOUNT} patterns are added
    • + *
    • If any of the patterns is longer than {@value AutoModRule#MAX_PATTERN_LENGTH} characters
    • + *
    + * + * @return The current config for chaining convenience + */ @Nonnull public CustomKeywordTriggerConfig addPatterns(@Nonnull String... patterns) { @@ -88,6 +181,27 @@ public CustomKeywordTriggerConfig addPatterns(@Nonnull String... patterns) return this; } + /** + * Add keywords regex patterns to match against. + *
    Keyword patterns are matched case-insensitively, and may also contain whitespace. + * + *

    Patterns may use anything supported by the rust regex crate. + * You can use a validator such as Rustexp to validate your pattern. + * + *

    You can also use simple substring keywords using {@link #keywordFilter(String...)}. + * + * @param patterns + * The keyword patterns to match + * + * @throws IllegalArgumentException + *

      + *
    • If any of the patterns are empty, blank, or null
    • + *
    • If more than {@value AutoModRule#MAX_PATTERN_AMOUNT} patterns are added
    • + *
    • If any of the patterns is longer than {@value AutoModRule#MAX_PATTERN_LENGTH} characters
    • + *
    + * + * @return The current config for chaining convenience + */ @Nonnull public CustomKeywordTriggerConfig addPatterns(@Nonnull Collection patterns) { @@ -100,6 +214,27 @@ public CustomKeywordTriggerConfig addPatterns(@Nonnull Collection patter return this; } + /** + * Change the list of keywords regex patterns to match against. + *
    Keyword patterns are matched case-insensitively, and may also contain whitespace. + * + *

    Patterns may use anything supported by the rust regex crate. + * You can use a validator such as Rustexp to validate your pattern. + * + *

    You can also use simple substring keywords using {@link #keywordFilter(String...)}. + * + * @param patterns + * The keyword patterns to match + * + * @throws IllegalArgumentException + *

      + *
    • If any of the patterns are empty, blank, or null
    • + *
    • If more than {@value AutoModRule#MAX_PATTERN_AMOUNT} patterns are added
    • + *
    • If any of the patterns is longer than {@value AutoModRule#MAX_PATTERN_LENGTH} characters
    • + *
    + * + * @return The current config for chaining convenience + */ @Nonnull public CustomKeywordTriggerConfig setPatterns(@Nonnull Collection patterns) { @@ -115,7 +250,7 @@ public CustomKeywordTriggerConfig setPatterns(@Nonnull Collection patter protected static void checkPattern(String pattern) { - Checks.notEmpty(pattern, "Pattern"); + Checks.notBlank(pattern, "Pattern"); Checks.notLonger(pattern, AutoModRule.MAX_PATTERN_LENGTH, "Pattern"); } diff --git a/src/main/java/net/dv8tion/jda/api/entities/automod/build/MentionSpamTriggerConfig.java b/src/main/java/net/dv8tion/jda/api/entities/automod/build/MentionSpamTriggerConfig.java index 349e12c3a1..9a9c11a439 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/automod/build/MentionSpamTriggerConfig.java +++ b/src/main/java/net/dv8tion/jda/api/entities/automod/build/MentionSpamTriggerConfig.java @@ -23,6 +23,9 @@ import javax.annotation.Nonnull; +/** + * Configuration for {@link AutoModTriggerType#MENTION_SPAM MENTION_SPAM} trigger. + */ public class MentionSpamTriggerConfig extends AbstractTriggerConfig implements TriggerConfig { private int mentionLimit; @@ -33,6 +36,17 @@ public MentionSpamTriggerConfig(int mentionLimit) this.mentionLimit = mentionLimit; } + /** + * Configure the maximum number of unique mentions allowed in a message. + * + * @param mentionLimit + * The maximum number of unique mentions allowed in a message (1-{@value AutoModRule#MAX_MENTION_LIMIT}) + * + * @throws IllegalArgumentException + * If the provided mention limit is not between 1 and {@value AutoModRule#MAX_MENTION_LIMIT} + * + * @return The current config for chaining convenience + */ @Nonnull public MentionSpamTriggerConfig setMentionLimit(int mentionLimit) { diff --git a/src/main/java/net/dv8tion/jda/api/entities/automod/build/PresetKeywordTriggerConfig.java b/src/main/java/net/dv8tion/jda/api/entities/automod/build/PresetKeywordTriggerConfig.java index 0b04bafece..828b6b25c3 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/automod/build/PresetKeywordTriggerConfig.java +++ b/src/main/java/net/dv8tion/jda/api/entities/automod/build/PresetKeywordTriggerConfig.java @@ -27,6 +27,9 @@ import java.util.Collections; import java.util.EnumSet; +/** + * Configuration for a {@link AutoModTriggerType#KEYWORD_PRESET KEYWORD_PRESET} trigger. + */ public class PresetKeywordTriggerConfig extends AbstractKeywordTriggerConfig { private final EnumSet presets = EnumSet.noneOf(AutoModRule.KeywordPreset.class); @@ -36,6 +39,17 @@ protected PresetKeywordTriggerConfig() super(AutoModTriggerType.KEYWORD_PRESET); } + /** + * Enable the provided keyword preset lists. + * + * @param presets + * The keyword presets to enable + * + * @throws IllegalArgumentException + * If any of the provided presets is null or {@link net.dv8tion.jda.api.entities.automod.AutoModRule.KeywordPreset#UNKNOWN UNKNOWN} + * + * @return The current config for chaining convenience + */ @Nonnull public PresetKeywordTriggerConfig enablePresets(@Nonnull AutoModRule.KeywordPreset... presets) { @@ -46,6 +60,17 @@ public PresetKeywordTriggerConfig enablePresets(@Nonnull AutoModRule.KeywordPres return this; } + /** + * Enable the provided keyword preset lists. + * + * @param presets + * The keyword presets to enable + * + * @throws IllegalArgumentException + * If any of the provided presets is null or {@link net.dv8tion.jda.api.entities.automod.AutoModRule.KeywordPreset#UNKNOWN UNKNOWN} + * + * @return The current config for chaining convenience + */ @Nonnull public PresetKeywordTriggerConfig enablePresets(@Nonnull Collection presets) { @@ -55,6 +80,17 @@ public PresetKeywordTriggerConfig enablePresets(@Nonnull Collection presets) { diff --git a/src/main/java/net/dv8tion/jda/api/entities/automod/build/TriggerConfig.java b/src/main/java/net/dv8tion/jda/api/entities/automod/build/TriggerConfig.java index 21fdd9371d..f2155f863c 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/automod/build/TriggerConfig.java +++ b/src/main/java/net/dv8tion/jda/api/entities/automod/build/TriggerConfig.java @@ -17,59 +17,214 @@ package net.dv8tion.jda.api.entities.automod.build; import net.dv8tion.jda.api.entities.automod.AutoModRule; +import net.dv8tion.jda.api.entities.automod.AutoModRule.KeywordPreset; import net.dv8tion.jda.api.entities.automod.AutoModTriggerType; import net.dv8tion.jda.api.utils.data.SerializableData; import javax.annotation.Nonnull; import java.util.Collection; +/** + * Configuration for {@link AutoModRule}, which defines under what conditions the rule should be triggered. + * + *

    Each rule is limited to a single trigger type. You can use the various factory methods on this interface to create a config. + * + *

    Supported factories: + *

      + *
    • {@link #mentionSpam(int)} - Trigger on mention thresholds in messages
    • + *
    • {@link #antiSpam()} - Trigger on spam content in messages (classified by Discord magic)
    • + *
    • {@link #keywordFilter(Collection)}/{@link #patternFilter(Collection)} - Trigger on messages containing certain keywords or regex patterns
    • + *
    • {@link #presetKeywordFilter(AutoModRule.KeywordPreset...)} - Trigger on messages containing words from predefined lists
    • + *
    + * + *

    Example
    + *

    {@code
    + * AutoModRuleData rule = AutoModRule.onMessage("Invite Links",
    + *   TriggerConfig.keywordFilter("discord.gg/*") // trigger on all invite links
    + *     .setAllowList("discord.gg/discord-api")   // except certain whitelisted ones
    + * );
    + * }
    + * + * @see AutoModRule + */ public interface TriggerConfig extends SerializableData { + /** + * The type of trigger for this config. + * + * @return {@link AutoModTriggerType} + */ @Nonnull AutoModTriggerType getType(); + /** + * Trigger on mention thresholds in messages. + * + * @param mentionLimit + * The maximum number of unique mentions allowed in a message (1-{@value AutoModRule#MAX_MENTION_LIMIT}) + * + * @throws IllegalArgumentException + * If the provided mention limit is not between 1 and {@value AutoModRule#MAX_MENTION_LIMIT} + * + * @return {@link MentionSpamTriggerConfig} + */ @Nonnull - static MentionSpamTriggerConfig mentionSpam(int limit) + static MentionSpamTriggerConfig mentionSpam(int mentionLimit) { - return new MentionSpamTriggerConfig(limit); + return new MentionSpamTriggerConfig(mentionLimit); } + /** + * Trigger on spam content in messages (classified by Discord magic). + * + * @return {@link AntiSpamTriggerConfig} + */ @Nonnull static AntiSpamTriggerConfig antiSpam() { return new AntiSpamTriggerConfig(); } + /** + * Trigger on messages containing certain keywords or regex patterns. + *
    Keywords are matched case-insensitively, and may also contain whitespace. + * + *

    You can use wildcards at the keyword boundaries to extend the matches: + *
    {@code "foo*"} can match {@code "foo"}, {@code "foobar"}, {@code "foo-bar"}, etc. + *
    {@code "*foo*"} can match {@code "foo"}, {@code "foobar"}, {@code "barfoo"}, etc. + *
    {@code "*foo"} can match {@code "foo"}, {@code "barfoo"}, {@code "bar-foo"}, etc. + * + *

    You can also use regex patterns using {@link #patternFilter(Collection)} or {@link CustomKeywordTriggerConfig#addPatterns(Collection)}. + * + * @param keywords + * The keywords to match (case-insensitive) + * + * @throws IllegalArgumentException + *

      + *
    • If any of the keywords are empty, blank, or null
    • + *
    • If more than {@value AutoModRule#MAX_KEYWORD_AMOUNT} keywords are added
    • + *
    • If any of the keywords is longer than {@value AutoModRule#MAX_KEYWORD_LENGTH} characters
    • + *
    + * + * @return {@link CustomKeywordTriggerConfig} + */ @Nonnull static CustomKeywordTriggerConfig keywordFilter(@Nonnull Collection keywords) { return new CustomKeywordTriggerConfig().addKeywords(keywords); } + /** + * Trigger on messages containing certain keywords or regex patterns. + *
    Keywords are matched case-insensitively, and may also contain whitespace. + * + *

    You can use wildcards at the keyword boundaries to extend the matches: + *
    {@code "foo*"} can match {@code "foo"}, {@code "foobar"}, {@code "foo-bar"}, etc. + *
    {@code "*foo*"} can match {@code "foo"}, {@code "foobar"}, {@code "barfoo"}, etc. + *
    {@code "*foo"} can match {@code "foo"}, {@code "barfoo"}, {@code "bar-foo"}, etc. + * + *

    You can also use regex patterns using {@link #patternFilter(String...)} or {@link CustomKeywordTriggerConfig#addPatterns(String...)}. + * + * @param keywords + * The keywords to match (case-insensitive) + * + * @throws IllegalArgumentException + *

      + *
    • If any of the keywords are empty, blank, or null
    • + *
    • If more than {@value AutoModRule#MAX_KEYWORD_AMOUNT} keywords are added
    • + *
    • If any of the keywords is longer than {@value AutoModRule#MAX_KEYWORD_LENGTH} characters
    • + *
    + * + * @return {@link CustomKeywordTriggerConfig} + */ @Nonnull static CustomKeywordTriggerConfig keywordFilter(@Nonnull String... keywords) { return new CustomKeywordTriggerConfig().addKeywords(keywords); } + /** + * Trigger on messages containing certain keywords regex patterns. + *
    Keyword patterns are matched case-insensitively, and may also contain whitespace. + * + *

    Patterns may use anything supported by the rust regex crate. + * You can use a validator such as Rustexp to validate your pattern. + * + *

    You can also use simple substring keywords using {@link #keywordFilter(String...)} or {@link CustomKeywordTriggerConfig#addKeywords(String...)}. + * + * @param patterns + * The keyword patterns to match + * + * @throws IllegalArgumentException + *

      + *
    • If any of the patterns are empty, blank, or null
    • + *
    • If more than {@value AutoModRule#MAX_PATTERN_AMOUNT} patterns are added
    • + *
    • If any of the patterns is longer than {@value AutoModRule#MAX_PATTERN_LENGTH} characters
    • + *
    + * + * @return {@link CustomKeywordTriggerConfig} + */ @Nonnull - static CustomKeywordTriggerConfig patternFilter(@Nonnull Collection keywords) + static CustomKeywordTriggerConfig patternFilter(@Nonnull Collection patterns) { - return new CustomKeywordTriggerConfig().addPatterns(keywords); + return new CustomKeywordTriggerConfig().addPatterns(patterns); } + /** + * Trigger on messages containing certain keywords regex patterns. + *
    Keyword patterns are matched case-insensitively, and may also contain whitespace. + * + *

    Patterns may use anything supported by the rust regex crate. + * You can use a validator such as Rustexp to validate your pattern. + * + *

    You can also use simple substring keywords using {@link #keywordFilter(String...)} or {@link CustomKeywordTriggerConfig#addKeywords(String...)}. + * + * @param patterns + * The keyword patterns to match + * + * @throws IllegalArgumentException + *

      + *
    • If any of the patterns are empty, blank, or null
    • + *
    • If more than {@value AutoModRule#MAX_PATTERN_AMOUNT} patterns are added
    • + *
    • If any of the patterns is longer than {@value AutoModRule#MAX_PATTERN_LENGTH} characters
    • + *
    + * + * @return {@link CustomKeywordTriggerConfig} + */ @Nonnull - static CustomKeywordTriggerConfig patternFilter(@Nonnull String... keywords) + static CustomKeywordTriggerConfig patternFilter(@Nonnull String... patterns) { - return new CustomKeywordTriggerConfig().addPatterns(keywords); + return new CustomKeywordTriggerConfig().addPatterns(patterns); } + /** + * Trigger on keywords from predefined lists. + * + * @param presets + * The presets to enable + * + * @throws IllegalArgumentException + * If null or {@link KeywordPreset#UNKNOWN} is provided + * + * @return {@link PresetKeywordTriggerConfig} + */ @Nonnull static PresetKeywordTriggerConfig presetKeywordFilter(@Nonnull Collection presets) { return new PresetKeywordTriggerConfig().enablePresets(presets); } + /** + * Trigger on keywords from predefined lists. + * + * @param presets + * The presets to enable + * + * @throws IllegalArgumentException + * If null or {@link KeywordPreset#UNKNOWN} is provided + * + * @return {@link PresetKeywordTriggerConfig} + */ @Nonnull static PresetKeywordTriggerConfig presetKeywordFilter(@Nonnull AutoModRule.KeywordPreset... presets) { From e8ba84d4bdb7689578fe5454638fca3e6f9fd6f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Spie=C3=9F?= Date: Wed, 29 Mar 2023 23:13:25 +0200 Subject: [PATCH 20/39] Add docs to AutoModRuleData --- .../api/entities/automod/AutoModResponse.java | 6 + .../jda/api/entities/automod/AutoModRule.java | 8 + .../automod/build/AutoModRuleData.java | 193 ++++++++++++++++++ 3 files changed, 207 insertions(+) diff --git a/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModResponse.java b/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModResponse.java index 593fa0d422..2996dba38a 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModResponse.java +++ b/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModResponse.java @@ -40,6 +40,12 @@ public interface AutoModResponse extends SerializableData @Nullable Duration getTimeoutDuration(); + @Nonnull + static AutoModResponse blockMessage() + { + return blockMessage(null); + } + @Nonnull static AutoModResponse blockMessage(@Nullable String customMessage) { diff --git a/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModRule.java b/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModRule.java index 81c287675e..667a8ddce0 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModRule.java +++ b/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModRule.java @@ -69,6 +69,14 @@ public interface AutoModRule extends ISnowflake * The maximum limit of mentions in {@link TriggerConfig#mentionSpam(int)}. ({@value}) */ int MAX_MENTION_LIMIT = 50; + /** + * The maximum amount of roles that can be added to {@link AutoModRule#getExemptRoles()}. ({@value}) + */ + int MAX_EXEMPT_ROLES = 20; + /** + * The maximum amount of channels that can be added to {@link AutoModRule#getExemptChannels()}. ({@value}) + */ + int MAX_EXEMPT_CHANNELS = 50; @Nonnull Guild getGuild(); diff --git a/src/main/java/net/dv8tion/jda/api/entities/automod/build/AutoModRuleData.java b/src/main/java/net/dv8tion/jda/api/entities/automod/build/AutoModRuleData.java index dff421887d..e6ba1833a9 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/automod/build/AutoModRuleData.java +++ b/src/main/java/net/dv8tion/jda/api/entities/automod/build/AutoModRuleData.java @@ -35,6 +35,28 @@ import java.util.EnumMap; import java.util.EnumSet; +/** + * Data class used to create new {@link AutoModRule AutoModRules}. + * + *

    Example
    + * + *

    {@code
    + * TriggerConfig config = TriggerConfig.keywordFilter("discord.gg/*").addAllowList("gateway.discord.gg/*");
    + * AutoModRuleData data = AutoModRuleData.onMessage("Invite Block", config);
    + * data.addExemptRoles(guild.getRolesByName("Moderator", true));
    + * data.putResponse(AutoModResponse.blockMessage());
    + * }
    + * + *
      + *
    1. The {@link TriggerConfig} defines under what conditions the rule should be triggered and execute a response. + * It should trigger on all invite links, but not trigger on the gateway subdomain.
    2. + *
    3. The rule is then created with this trigger config and we name it {@code "Invite Block"}.
    4. + *
    5. Using {@link #addExemptRoles(Role...)}, the moderator role has been excluded to allow moderators to post links.
    6. + *
    7. With {@link #putResponses(AutoModResponse...)}, an automatic action is enabled to block the message, whenever it triggers the rule.
    8. + *
    + * + * @see net.dv8tion.jda.api.entities.Guild#createAutoModRule(AutoModRuleData) + */ public class AutoModRuleData implements SerializableData { protected final AutoModEventType eventType; @@ -53,12 +75,36 @@ protected AutoModRuleData(AutoModEventType eventType, String name, TriggerConfig this.triggerMetadata = triggerMetadata; } + /** + * Create a new {@link AutoModRule} which triggers on a message being sent in a channel. + * + * @param name + * The name of the rule (1-{@value AutoModRule#MAX_RULE_NAME_LENGTH} characters) + * @param triggerConfig + * The trigger configuration for this rule + * + * @throws IllegalArgumentException + * If null is provided or the name is not between 1 and {@value AutoModRule#MAX_RULE_NAME_LENGTH} characters + * + * @return The new {@link AutoModRuleData} instance + */ @Nonnull public static AutoModRuleData onMessage(@Nonnull String name, @Nonnull TriggerConfig triggerConfig) { return new AutoModRuleData(AutoModEventType.MESSAGE_SEND, name, triggerConfig); } + /** + * Change the name of the rule. + * + * @param name + * The new name (1-{@value AutoModRule#MAX_RULE_NAME_LENGTH} characters) + * + * @throws IllegalArgumentException + * If the name is not between 1 and {@value AutoModRule#MAX_RULE_NAME_LENGTH} characters + * + * @return The same {@link AutoModRuleData} instance + */ @Nonnull public AutoModRuleData setName(@Nonnull String name) { @@ -75,6 +121,21 @@ public AutoModRuleData setEnabled(boolean enabled) return this; } + /** + * Configure what the rule should do upon triggering. + *
    This is accumulative and adds ontop of the currently configured responses. + * + *

    Note that each response type can only be used once. + * If multiple responses of the same type are provided, the last one is used. + * + * @param responses + * The responses to configure + * + * @throws IllegalArgumentException + * If null is provided + * + * @return The same {@link AutoModRuleData} instance + */ @Nonnull public AutoModRuleData putResponses(@Nonnull AutoModResponse... responses) { @@ -84,6 +145,21 @@ public AutoModRuleData putResponses(@Nonnull AutoModResponse... responses) return this; } + /** + * Configure what the rule should do upon triggering. + *
    This is accumulative and adds ontop of the currently configured responses. + * + *

    Note that each response type can only be used once. + * If multiple responses of the same type are provided, the last one is used. + * + * @param responses + * The responses to configure + * + * @throws IllegalArgumentException + * If null is provided + * + * @return The same {@link AutoModRuleData} instance + */ @Nonnull public AutoModRuleData putResponses(@Nonnull Collection responses) { @@ -93,6 +169,21 @@ public AutoModRuleData putResponses(@Nonnull CollectionThis replaces the currently configured responses, removing all previously configured responses. + * + *

    Note that each response type can only be used once. + * If multiple responses of the same type are provided, the last one is used. + * + * @param responses + * The responses to configure + * + * @throws IllegalArgumentException + * If null is provided + * + * @return The same {@link AutoModRuleData} instance + */ @Nonnull public AutoModRuleData setResponses(@Nonnull Collection responses) { @@ -103,62 +194,157 @@ public AutoModRuleData setResponses(@Nonnull CollectionRoles added to the exemptions will allow all of its members to bypass this rule. + * + * @param roles + * The roles to add (up to {@value AutoModRule#MAX_EXEMPT_ROLES} roles) + * + * @throws IllegalArgumentException + * If null is provided or the number of roles exceeds {@value AutoModRule#MAX_EXEMPT_ROLES} + * + * @return The same {@link AutoModRuleData} instance + */ @Nonnull public AutoModRuleData addExemptRoles(@Nonnull Role... roles) { Checks.noneNull(roles, "Roles"); + Checks.check(roles.length + exemptRoles.size() <= AutoModRule.MAX_EXEMPT_ROLES, "Cannot add more than %d roles", AutoModRule.MAX_EXEMPT_ROLES); for (Role role : roles) exemptRoles.add(role.getId()); return this; } + /** + * Add roles which can bypass this rule. + * + *

    Roles added to the exemptions will allow all of its members to bypass this rule. + * + * @param roles + * The roles to add (up to {@value AutoModRule#MAX_EXEMPT_ROLES} roles) + * + * @throws IllegalArgumentException + * If null is provided or the number of roles exceeds {@value AutoModRule#MAX_EXEMPT_ROLES} + * + * @return The same {@link AutoModRuleData} instance + */ @Nonnull public AutoModRuleData addExemptRoles(@Nonnull Collection roles) { Checks.noneNull(roles, "Roles"); + Checks.check(roles.size() + exemptRoles.size() <= AutoModRule.MAX_EXEMPT_ROLES, "Cannot add more than %d roles", AutoModRule.MAX_EXEMPT_ROLES); for (Role role : roles) exemptRoles.add(role.getId()); return this; } + /** + * Set which roles can bypass this rule. + * + *

    Roles added to the exemptions will allow all of its members to bypass this rule. + * + * @param roles + * The roles to exempt (up to {@value AutoModRule#MAX_EXEMPT_ROLES} roles) + * + * @throws IllegalArgumentException + * If null is provided or the number of roles exceeds {@value AutoModRule#MAX_EXEMPT_ROLES} + * + * @return The same {@link AutoModRuleData} instance + */ @Nonnull public AutoModRuleData setExemptRoles(@Nonnull Collection roles) { Checks.noneNull(roles, "Roles"); + Checks.check(roles.size() <= AutoModRule.MAX_EXEMPT_ROLES, "Cannot add more than %d roles", AutoModRule.MAX_EXEMPT_ROLES); exemptRoles.clear(); for (Role role : roles) exemptRoles.add(role.getId()); return this; } + /** + * Add channels which can bypass this rule. + * + *

    No messages sent in this channel will trigger the rule. + * + * @param channels + * The channels to add (up to {@value AutoModRule#MAX_EXEMPT_CHANNELS} channels) + * + * @throws IllegalArgumentException + * If null is provided or the number of channels exceeds {@value AutoModRule#MAX_EXEMPT_CHANNELS} + * + * @return The same {@link AutoModRuleData} instance + */ @Nonnull public AutoModRuleData addExemptChannels(@Nonnull GuildChannel... channels) { Checks.noneNull(channels, "Channels"); + Checks.check(channels.length + exemptChannels.size() <= AutoModRule.MAX_EXEMPT_CHANNELS, "Cannot add more than %d channels", AutoModRule.MAX_EXEMPT_CHANNELS); for (GuildChannel channel : channels) exemptChannels.add(channel.getId()); return this; } + /** + * Add channels which can bypass this rule. + * + *

    No messages sent in this channel will trigger the rule. + * + * @param channels + * The channels to add (up to {@value AutoModRule#MAX_EXEMPT_CHANNELS} channels) + * + * @throws IllegalArgumentException + * If null is provided or the number of channels exceeds {@value AutoModRule#MAX_EXEMPT_CHANNELS} + * + * @return The same {@link AutoModRuleData} instance + */ @Nonnull public AutoModRuleData addExemptChannels(@Nonnull Collection channels) { Checks.noneNull(channels, "Channels"); + Checks.check(channels.size() + exemptChannels.size() <= AutoModRule.MAX_EXEMPT_CHANNELS, "Cannot add more than %d channels", AutoModRule.MAX_EXEMPT_CHANNELS); for (GuildChannel channel : channels) exemptChannels.add(channel.getId()); return this; } + /** + * Set which channels can bypass this rule. + * + *

    No messages sent in this channel will trigger the rule. + * + * @param channels + * The channels to add (up to {@value AutoModRule#MAX_EXEMPT_CHANNELS} channels) + * + * @throws IllegalArgumentException + * If null is provided or the number of channels exceeds {@value AutoModRule#MAX_EXEMPT_CHANNELS} + * + * @return The same {@link AutoModRuleData} instance + */ @Nonnull public AutoModRuleData setExemptChannels(@Nonnull Collection channels) { Checks.noneNull(channels, "Channels"); + Checks.check(channels.size() <= AutoModRule.MAX_EXEMPT_CHANNELS, "Cannot add more than %d channels", AutoModRule.MAX_EXEMPT_CHANNELS); exemptChannels.clear(); for (GuildChannel channel : channels) exemptChannels.add(channel.getId()); return this; } + /** + * Change the {@link TriggerConfig} for this rule. + * + * @param config + * The new config + * + * @throws IllegalArgumentException + * If null is provided + * + * @return The same {@link AutoModRuleData} instance + */ @Nonnull @CheckReturnValue public AutoModRuleData setTriggerConfig(@Nonnull TriggerConfig config) @@ -168,6 +354,13 @@ public AutoModRuleData setTriggerConfig(@Nonnull TriggerConfig config) return this; } + /** + * Returns the {@link Permission Permissions} required to create this rule. + *
    Certain {@link AutoModResponse.Type Types} require additional permissions, such as {@link AutoModResponse.Type#TIMEOUT}. + * All rules require {@link Permission#MANAGE_SERVER} to be created. + * + * @return The required permissions to create this rule + */ @Nonnull public EnumSet getRequiredPermissions() { From bb8eea11bde9f7f1a0e4828f06b057f97f8f7a23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Spie=C3=9F?= Date: Thu, 30 Mar 2023 21:48:53 +0200 Subject: [PATCH 21/39] Update audit-logs --- .../net/dv8tion/jda/api/audit/ActionType.java | 21 ++++++++++++++++++- .../dv8tion/jda/api/audit/AuditLogKey.java | 7 +++++++ .../automod/build/AutoModRuleData.java | 8 +++++++ 3 files changed, 35 insertions(+), 1 deletion(-) diff --git a/src/main/java/net/dv8tion/jda/api/audit/ActionType.java b/src/main/java/net/dv8tion/jda/api/audit/ActionType.java index 014fd1713a..2a08999fa1 100644 --- a/src/main/java/net/dv8tion/jda/api/audit/ActionType.java +++ b/src/main/java/net/dv8tion/jda/api/audit/ActionType.java @@ -603,16 +603,35 @@ public enum ActionType /** * An automod rule blocked a message from being sent + * + *

    Possible Keys
    + *

      + *
    • {@link AuditLogKey#AUTO_MODERATION_RULE_NAME AUTO_MODERATION_RULE_NAME}
    • + *
    • {@link AuditLogKey#AUTO_MODERATION_RULE_TRIGGER_TYPE AUTO_MODERATION_RULE_TRIGGER_TYPE}
    • + *
    • {@link AuditLogKey#CHANNEL_ID CHANNEL_ID}
    • + *
    */ - AUTO_MODERATION_RULE_BLOCK_MESSAGE( 143, TargetType.UNKNOWN), + AUTO_MODERATION_RULE_BLOCK_MESSAGE( 143, TargetType.MEMBER), /** * An automod rule sent an alert to a channel + * + *

    Possible Keys
    + *

      + *
    • {@link AuditLogKey#AUTO_MODERATION_RULE_NAME AUTO_MODERATION_RULE_NAME}
    • + *
    • {@link AuditLogKey#AUTO_MODERATION_RULE_TRIGGER_TYPE AUTO_MODERATION_RULE_TRIGGER_TYPE}
    • + *
    */ AUTO_MODERATION_FLAG_TO_CHANNEL( 144, TargetType.UNKNOWN), /** * An automod rule put a user in {@link Member#isTimedOut() timeout} + * + *

    Possible Keys
    + *

      + *
    • {@link AuditLogKey#AUTO_MODERATION_RULE_NAME AUTO_MODERATION_RULE_NAME}
    • + *
    • {@link AuditLogKey#AUTO_MODERATION_RULE_TRIGGER_TYPE AUTO_MODERATION_RULE_TRIGGER_TYPE}
    • + *
    */ AUTO_MODERATION_USER_COMMUNICATION_DISABLED(145, TargetType.UNKNOWN), diff --git a/src/main/java/net/dv8tion/jda/api/audit/AuditLogKey.java b/src/main/java/net/dv8tion/jda/api/audit/AuditLogKey.java index d2bdb356b6..848a42eb88 100644 --- a/src/main/java/net/dv8tion/jda/api/audit/AuditLogKey.java +++ b/src/main/java/net/dv8tion/jda/api/audit/AuditLogKey.java @@ -314,6 +314,13 @@ public enum AuditLogKey */ CHANNEL_AVAILABLE_TAGS("available_tags"), + /** + * The relevant channel for the audit log entry. + * + *

    Expected type: String + */ + CHANNEL_ID("channel_id"), + // /** // * The {@link ForumChannel#getDefaultSortOrder()} value. // *
    Only for {@link ChannelType#FORUM}. diff --git a/src/main/java/net/dv8tion/jda/api/entities/automod/build/AutoModRuleData.java b/src/main/java/net/dv8tion/jda/api/entities/automod/build/AutoModRuleData.java index e6ba1833a9..f999b00709 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/automod/build/AutoModRuleData.java +++ b/src/main/java/net/dv8tion/jda/api/entities/automod/build/AutoModRuleData.java @@ -114,6 +114,14 @@ public AutoModRuleData setName(@Nonnull String name) return this; } + /** + * Enable or disable the rule. + * + * @param enabled + * True, if the rule should be enabled + * + * @return The same {@link AutoModRuleData} instance + */ @Nonnull public AutoModRuleData setEnabled(boolean enabled) { From 9caf9a34dfa8e2a5123984f015d9ae21a2005882 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Spie=C3=9F?= Date: Thu, 30 Mar 2023 21:50:50 +0200 Subject: [PATCH 22/39] Fix indentation --- src/main/java/net/dv8tion/jda/api/audit/TargetType.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/net/dv8tion/jda/api/audit/TargetType.java b/src/main/java/net/dv8tion/jda/api/audit/TargetType.java index 5007405fb2..7ef8b38967 100644 --- a/src/main/java/net/dv8tion/jda/api/audit/TargetType.java +++ b/src/main/java/net/dv8tion/jda/api/audit/TargetType.java @@ -42,7 +42,7 @@ public enum TargetType STAGE_INSTANCE, STICKER, THREAD, - SCHEDULED_EVENT, + SCHEDULED_EVENT, AUTO_MODERATION_RULE, UNKNOWN } From e90818baa4bd551073f79b7185666e7fab565127 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Spie=C3=9F?= Date: Fri, 31 Mar 2023 21:33:44 +0200 Subject: [PATCH 23/39] Add docs for response and event type --- .../entities/automod/AutoModEventType.java | 29 +++++ .../api/entities/automod/AutoModResponse.java | 117 ++++++++++++++++++ 2 files changed, 146 insertions(+) diff --git a/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModEventType.java b/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModEventType.java index 2d7304b6c4..173d839d8b 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModEventType.java +++ b/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModEventType.java @@ -16,11 +16,27 @@ package net.dv8tion.jda.api.entities.automod; +import net.dv8tion.jda.api.entities.automod.build.AutoModRuleData; +import net.dv8tion.jda.api.entities.automod.build.TriggerConfig; + import javax.annotation.Nonnull; +/** + * The type of event an {@link AutoModRule} is triggered by. + * + * @see AutoModRule#getEventType() + * @see AutoModRuleData#onMessage(String, TriggerConfig) + */ public enum AutoModEventType { + /** + * The rule is triggered by a message being sent in a guild channel. + */ MESSAGE_SEND(1), + + /** + * Placeholder for unknown types which haven't been added yet. + */ UNKNOWN(-1); private final int key; @@ -30,11 +46,24 @@ public enum AutoModEventType this.key = key; } + /** + * The raw value used by Discord to represent this type. + * + * @return The raw value + */ public int getKey() { return key; } + /** + * The {@link AutoModEventType} represented by the provided key. + * + * @param key + * The raw key + * + * @return The {@link AutoModEventType} or {@link #UNKNOWN} + */ @Nonnull public static AutoModEventType fromKey(int key) { diff --git a/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModResponse.java b/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModResponse.java index 2996dba38a..edcbf4f25e 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModResponse.java +++ b/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModResponse.java @@ -26,32 +26,90 @@ import java.time.Duration; import java.util.EnumSet; +/** + * An automated response to an {@link AutoModRule}. + */ public interface AutoModResponse extends SerializableData { + /** + * The maximum length of a custom message. ({@value}) + */ + int MAX_CUSTOM_MESSAGE_LENGTH = 150; + + /** + * The type of response. + * + * @return The type of response + */ @Nonnull Type getType(); + /** + * The channel to send the alert message to. + * + * @return The channel to send the alert message to, or null if this is not a {@link Type#SEND_ALERT_MESSAGE} response + */ @Nullable GuildMessageChannel getChannel(); + /** + * The custom message to send to the user. + * + * @return The custom message to send to the user, or null if this is not a {@link Type#BLOCK_MESSAGE} response + */ @Nullable String getCustomMessage(); + /** + * The duration to timeout the user for. + * + * @return The duration to timeout the user for, or null if this is not a {@link Type#TIMEOUT} response + */ @Nullable Duration getTimeoutDuration(); + /** + * Create a response that will block the message. + *

    You can optionally pass a custom message to send to the user. + * + * @return The response instance + * + * @see #blockMessage(String) + */ @Nonnull static AutoModResponse blockMessage() { return blockMessage(null); } + /** + * Create a response that will block the message. + * + * @param customMessage + * The custom message to send to the user, or null to send the default message + * + * @throws IllegalArgumentException + * If the provided custom message is longer than {@value #MAX_CUSTOM_MESSAGE_LENGTH} characters + * + * @return The response instance + */ @Nonnull static AutoModResponse blockMessage(@Nullable String customMessage) { return new AutoModResponseImpl(Type.BLOCK_MESSAGE, customMessage); } + /** + * Create a response that will send an alert message to the specified channel. + * + * @param channel + * The channel to send the alert message to + * + * @throws IllegalArgumentException + * If the provided channel is {@code null} + * + * @return The response instance + */ @Nonnull static AutoModResponse sendAlert(@Nonnull GuildMessageChannel channel) { @@ -59,6 +117,19 @@ static AutoModResponse sendAlert(@Nonnull GuildMessageChannel channel) return new AutoModResponseImpl(Type.SEND_ALERT_MESSAGE, channel); } + /** + * Create a response that will timeout the user for the specified duration. + * + *

    To create a rule with this response, the creator must also have the {@link net.dv8tion.jda.api.Permission#MODERATE_MEMBERS MODERATE_MEMBERS} permission. + * + * @param duration + * The duration to timeout the user for + * + * @throws IllegalArgumentException + * If the provided duration is not positive or longer than {@value net.dv8tion.jda.api.entities.Member#MAX_TIME_OUT_LENGTH} days + * + * @return The response instance + */ @Nonnull static AutoModResponse timeoutMember(@Nonnull Duration duration) { @@ -67,11 +138,28 @@ static AutoModResponse timeoutMember(@Nonnull Duration duration) return new AutoModResponseImpl(Type.TIMEOUT, duration); } + /** + * The type of response. + */ enum Type { + /** + * Blocks the message from being sent. + */ BLOCK_MESSAGE(1), + /** + * Sends an alert message to the specified channel. + */ SEND_ALERT_MESSAGE(2), + /** + * Times out the user for the specified duration. + * + *

    To create a rule with this response, the creator must also have the {@link net.dv8tion.jda.api.Permission#MODERATE_MEMBERS MODERATE_MEMBERS} permission. + */ TIMEOUT(3, EnumSet.of(AutoModTriggerType.KEYWORD, AutoModTriggerType.MENTION_SPAM)), + /** + * Placeholder for unknown types. + */ UNKNOWN(-1) ; @@ -90,23 +178,52 @@ enum Type this.supportedTypes = supportedTypes; } + /** + * The raw value used by Discord to represent this type. + * + * @return The raw value + */ public int getKey() { return key; } + /** + * The {@link AutoModTriggerType AutoModTriggerTypes} that this response supports. + * + * @return The supported trigger types + */ @Nonnull public EnumSet getSupportedTypes() { return EnumSet.copyOf(supportedTypes); } + /** + * Whether this response supports the provided trigger type. + * + * @param type + * The trigger type + * + * @throws IllegalArgumentException + * If the provided trigger type is {@code null} + * + * @return True, if this response supports the provided trigger type + */ public boolean isSupportedTrigger(@Nonnull AutoModTriggerType type) { Checks.notNull(type, "AutoModTriggerType"); return supportedTypes.contains(type); } + /** + * The {@link Type} represented by the provided key. + * + * @param key + * The raw key + * + * @return The {@link Type} or {@link #UNKNOWN} + */ @Nonnull public static Type fromKey(int key) { From 8b2f9ec1d1e26e8df29f2cb6fda0f86d24b8d4b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Spie=C3=9F?= Date: Fri, 31 Mar 2023 21:36:46 +0200 Subject: [PATCH 24/39] Fix wrong json keys --- .../jda/internal/entities/automod/AutoModExecutionImpl.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/net/dv8tion/jda/internal/entities/automod/AutoModExecutionImpl.java b/src/main/java/net/dv8tion/jda/internal/entities/automod/AutoModExecutionImpl.java index 342ff1407e..8eb6e97a87 100644 --- a/src/main/java/net/dv8tion/jda/internal/entities/automod/AutoModExecutionImpl.java +++ b/src/main/java/net/dv8tion/jda/internal/entities/automod/AutoModExecutionImpl.java @@ -41,11 +41,11 @@ public AutoModExecutionImpl(Guild guild, DataObject json) this.guild = guild; this.channel = guild.getChannelById(GuildMessageChannel.class, json.getUnsignedLong("channel_id")); this.response = new AutoModResponseImpl(guild, json.getObject("action")); - this.type = AutoModTriggerType.fromKey(json.getInt("trigger_type", -1)); + this.type = AutoModTriggerType.fromKey(json.getInt("rule_trigger_type", -1)); this.userId = json.getUnsignedLong("user_id"); this.ruleId = json.getUnsignedLong("rule_id"); this.messageId = json.getUnsignedLong("message_id", 0L); - this.alertMessageId = json.getUnsignedLong("alert_message_id", 0L); + this.alertMessageId = json.getUnsignedLong("alert_system_message_id", 0L); this.content = json.getString("content", ""); this.matchedContent = json.getString("matched_content", null); this.matchedKeyword = json.getString("matched_keyword", null); From 858a835b06b6b093aeda904059a96677f848b5bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Spie=C3=9F?= Date: Fri, 31 Mar 2023 21:46:06 +0200 Subject: [PATCH 25/39] Add docs to AutoModExecution --- .../entities/automod/AutoModExecution.java | 87 +++++++++++++++++++ 1 file changed, 87 insertions(+) diff --git a/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModExecution.java b/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModExecution.java index 0420ebce23..50a4ac1807 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModExecution.java +++ b/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModExecution.java @@ -18,42 +18,98 @@ import net.dv8tion.jda.api.entities.Guild; import net.dv8tion.jda.api.entities.channel.unions.GuildMessageChannelUnion; +import net.dv8tion.jda.api.requests.GatewayIntent; import javax.annotation.Nonnull; import javax.annotation.Nullable; +/** + * Event triggered by an {@link AutoModRule} activation. + */ public interface AutoModExecution { + /** + * The {@link Guild} that this execution occurred in. + * + * @return The {@link Guild} + */ @Nonnull Guild getGuild(); + /** + * The {@link GuildMessageChannelUnion} that this execution occurred in. + * + *

    This might be {@code null} if the execution occurred by future event types. + * + * @return The {@link GuildMessageChannelUnion} + */ @Nullable GuildMessageChannelUnion getChannel(); + /** + * The {@link AutoModResponse} that has been triggered by this execution. + * + * @return The {@link AutoModResponse} + */ @Nonnull AutoModResponse getResponse(); + /** + * The {@link AutoModTriggerType} for the execution. + * + * @return The {@link AutoModTriggerType} + */ @Nonnull AutoModTriggerType getTriggerType(); + /** + * The id of the user that triggered this execution. + * + * @return The id of the user + */ long getUserIdLong(); + /** + * The id of the user that triggered this execution. + * + * @return The id of the user + */ @Nonnull default String getUserId() { return Long.toUnsignedString(getUserIdLong()); } + /** + * The id of the {@link AutoModRule} which has been triggered. + * + * @return The id of the rule + */ long getRuleIdLong(); + /** + * The id of the {@link AutoModRule} which has been triggered. + * + * @return The id of the rule + */ @Nonnull default String getRuleId() { return Long.toUnsignedString(getRuleIdLong()); } + /** + * The id of the {@link net.dv8tion.jda.api.entities.Message Message} which triggered the rule. + * + * @return The id of the message, or 0 if the message has been blocked + */ long getMessageIdLong(); + /** + * The id of the {@link net.dv8tion.jda.api.entities.Message Message} which triggered the rule. + * + * @return The id of the message, or {@code null} if the message has been blocked + */ @Nullable default String getMessageId() { @@ -61,8 +117,18 @@ default String getMessageId() return id == 0L ? null : Long.toUnsignedString(getMessageIdLong()); } + /** + * The id of the alert {@link net.dv8tion.jda.api.entities.Message Message} sent to the alert channel. + * + * @return The id of the alert message, or 0 if {@link AutoModResponse#getType()} is not {@link AutoModResponse.Type#SEND_ALERT_MESSAGE} + */ long getAlertMessageIdLong(); + /** + * The id of the alert {@link net.dv8tion.jda.api.entities.Message Message} sent to the alert channel. + * + * @return The id of the alert message, or {@code null} if {@link AutoModResponse#getType()} is not {@link AutoModResponse.Type#SEND_ALERT_MESSAGE} + */ @Nullable default String getAlertMessageId() { @@ -70,12 +136,33 @@ default String getAlertMessageId() return id == 0L ? null : Long.toUnsignedString(getAlertMessageIdLong()); } + /** + * The user content that triggered this rule. + * + *

    This is empty if {@link GatewayIntent#MESSAGE_CONTENT} is not enabled. + * However, you can still use {@link #getMatchedKeyword()} regardless. + * + * @return The user content + */ @Nonnull String getContent(); + /** + * The substring match of the user content that triggered this rule. + * + *

    This is empty if {@link GatewayIntent#MESSAGE_CONTENT} is not enabled. + * However, you can still use {@link #getMatchedKeyword()} regardless. + * + * @return The user content substring + */ @Nullable String getMatchedContent(); + /** + * The keyword that was found in the {@link #getContent()}. + * + * @return The keyword that was found in the content + */ @Nullable String getMatchedKeyword(); } From 54944d2f1095c35470210acbc1ebd735e34b1b1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Spie=C3=9F?= Date: Fri, 31 Mar 2023 22:52:27 +0200 Subject: [PATCH 26/39] Add event docs --- .../api/events/automod/AutoModExecutionEvent.java | 9 +++++++++ .../api/events/automod/AutoModRuleCreateEvent.java | 7 +++++++ .../api/events/automod/AutoModRuleDeleteEvent.java | 7 +++++++ .../api/events/automod/AutoModRuleUpdateEvent.java | 7 +++++++ .../api/events/automod/GenericAutoModRuleEvent.java | 12 ++++++++++++ 5 files changed, 42 insertions(+) diff --git a/src/main/java/net/dv8tion/jda/api/events/automod/AutoModExecutionEvent.java b/src/main/java/net/dv8tion/jda/api/events/automod/AutoModExecutionEvent.java index ccebe3fe59..fbb160d7b3 100644 --- a/src/main/java/net/dv8tion/jda/api/events/automod/AutoModExecutionEvent.java +++ b/src/main/java/net/dv8tion/jda/api/events/automod/AutoModExecutionEvent.java @@ -20,13 +20,22 @@ import net.dv8tion.jda.api.entities.Guild; import net.dv8tion.jda.api.entities.automod.AutoModExecution; import net.dv8tion.jda.api.entities.automod.AutoModResponse; +import net.dv8tion.jda.api.entities.automod.AutoModRule; import net.dv8tion.jda.api.entities.automod.AutoModTriggerType; import net.dv8tion.jda.api.entities.channel.unions.GuildMessageChannelUnion; import net.dv8tion.jda.api.events.Event; +import net.dv8tion.jda.api.requests.GatewayIntent; import javax.annotation.Nonnull; import javax.annotation.Nullable; +/** + * Indicates that an automated {@link AutoModResponse} has been triggered through an {@link AutoModRule}. + * + *

    Requirements
    + * This event requires the {@link GatewayIntent#AUTO_MODERATION_EXECUTION AUTO_MODERATION_EXECUTION} intent to be enabled. + * Additionally, access to {@link #getContent()} and {@link #getMatchedContent()} requires the {@link GatewayIntent#MESSAGE_CONTENT MESSAGE_CONTENT} intent to be enabled. + */ public class AutoModExecutionEvent extends Event implements AutoModExecution { private final AutoModExecution execution; diff --git a/src/main/java/net/dv8tion/jda/api/events/automod/AutoModRuleCreateEvent.java b/src/main/java/net/dv8tion/jda/api/events/automod/AutoModRuleCreateEvent.java index 08a8c10a27..40e19d0372 100644 --- a/src/main/java/net/dv8tion/jda/api/events/automod/AutoModRuleCreateEvent.java +++ b/src/main/java/net/dv8tion/jda/api/events/automod/AutoModRuleCreateEvent.java @@ -21,6 +21,13 @@ import javax.annotation.Nonnull; +/** + * Indicates that a {@link AutoModRule} was created. + * + *

    Requirements
    + * + *

    These events require the {@link net.dv8tion.jda.api.requests.GatewayIntent#AUTO_MODERATION_CONFIGURATION AUTO_MODERATION_CONFIGURATION} intent to be enabled. + */ public class AutoModRuleCreateEvent extends GenericAutoModRuleEvent { public AutoModRuleCreateEvent(@Nonnull JDA api, long responseNumber, @Nonnull AutoModRule rule) diff --git a/src/main/java/net/dv8tion/jda/api/events/automod/AutoModRuleDeleteEvent.java b/src/main/java/net/dv8tion/jda/api/events/automod/AutoModRuleDeleteEvent.java index 9374bcda6d..67b65ab229 100644 --- a/src/main/java/net/dv8tion/jda/api/events/automod/AutoModRuleDeleteEvent.java +++ b/src/main/java/net/dv8tion/jda/api/events/automod/AutoModRuleDeleteEvent.java @@ -21,6 +21,13 @@ import javax.annotation.Nonnull; +/** + * Indicates that a {@link AutoModRule} was deleted. + * + *

    Requirements
    + * + *

    These events require the {@link net.dv8tion.jda.api.requests.GatewayIntent#AUTO_MODERATION_CONFIGURATION AUTO_MODERATION_CONFIGURATION} intent to be enabled. + */ public class AutoModRuleDeleteEvent extends GenericAutoModRuleEvent { public AutoModRuleDeleteEvent(@Nonnull JDA api, long responseNumber, @Nonnull AutoModRule rule) diff --git a/src/main/java/net/dv8tion/jda/api/events/automod/AutoModRuleUpdateEvent.java b/src/main/java/net/dv8tion/jda/api/events/automod/AutoModRuleUpdateEvent.java index 025089e0ed..3714dc8f6e 100644 --- a/src/main/java/net/dv8tion/jda/api/events/automod/AutoModRuleUpdateEvent.java +++ b/src/main/java/net/dv8tion/jda/api/events/automod/AutoModRuleUpdateEvent.java @@ -21,6 +21,13 @@ import javax.annotation.Nonnull; +/** + * Indicates that a {@link AutoModRule} was updated. + * + *

    Requirements
    + * + *

    These events require the {@link net.dv8tion.jda.api.requests.GatewayIntent#AUTO_MODERATION_CONFIGURATION AUTO_MODERATION_CONFIGURATION} intent to be enabled. + */ public class AutoModRuleUpdateEvent extends GenericAutoModRuleEvent { public AutoModRuleUpdateEvent(@Nonnull JDA api, long responseNumber, @Nonnull AutoModRule rule) diff --git a/src/main/java/net/dv8tion/jda/api/events/automod/GenericAutoModRuleEvent.java b/src/main/java/net/dv8tion/jda/api/events/automod/GenericAutoModRuleEvent.java index 02affa39b9..4126257e6f 100644 --- a/src/main/java/net/dv8tion/jda/api/events/automod/GenericAutoModRuleEvent.java +++ b/src/main/java/net/dv8tion/jda/api/events/automod/GenericAutoModRuleEvent.java @@ -22,6 +22,13 @@ import javax.annotation.Nonnull; +/** + * Indicates that na {@link AutoModRule} was created/removed/updated. + * + *

    Requirements
    + * + *

    These events require the {@link net.dv8tion.jda.api.requests.GatewayIntent#AUTO_MODERATION_CONFIGURATION AUTO_MODERATION_CONFIGURATION} intent to be enabled. + */ public class GenericAutoModRuleEvent extends Event { private final AutoModRule rule; @@ -32,6 +39,11 @@ public GenericAutoModRuleEvent(@Nonnull JDA api, long responseNumber, @Nonnull A this.rule = rule; } + /** + * The {@link AutoModRule} that was created/removed/updated. + * + * @return The {@link AutoModRule} + */ @Nonnull public AutoModRule getRule() { From 4d89d37ef44966abd277e739a3e46c867e852fb7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Spie=C3=9F?= Date: Fri, 31 Mar 2023 22:56:01 +0200 Subject: [PATCH 27/39] Handle guild lock in execution handler --- .../dv8tion/jda/internal/handle/AutoModExecutionHandler.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/net/dv8tion/jda/internal/handle/AutoModExecutionHandler.java b/src/main/java/net/dv8tion/jda/internal/handle/AutoModExecutionHandler.java index c9793fb799..4edd95f1dd 100644 --- a/src/main/java/net/dv8tion/jda/internal/handle/AutoModExecutionHandler.java +++ b/src/main/java/net/dv8tion/jda/internal/handle/AutoModExecutionHandler.java @@ -32,7 +32,9 @@ public AutoModExecutionHandler(JDAImpl api) @Override protected Long handleInternally(DataObject content) { - long guildId = content.getLong("guild_id"); + long guildId = content.getUnsignedLong("guild_id"); + if (api.getGuildSetupController().isLocked(guildId)) + return guildId; Guild guild = api.getGuildById(guildId); if (guild == null) { From 7775523b69f23d3849c87a0dfa9d387212d918c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Spie=C3=9F?= Date: Sun, 2 Apr 2023 12:49:26 +0200 Subject: [PATCH 28/39] Add docs to AutoModRule --- .../jda/api/entities/automod/AutoModRule.java | 135 +++++++++++++++++- .../entities/automod/AutoModRuleImpl.java | 2 +- 2 files changed, 133 insertions(+), 4 deletions(-) diff --git a/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModRule.java b/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModRule.java index 667a8ddce0..cf59c0ba95 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModRule.java +++ b/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModRule.java @@ -22,6 +22,7 @@ import net.dv8tion.jda.api.entities.automod.build.AutoModRuleData; import net.dv8tion.jda.api.entities.automod.build.TriggerConfig; import net.dv8tion.jda.api.entities.channel.middleman.GuildChannel; +import net.dv8tion.jda.api.exceptions.InsufficientPermissionException; import net.dv8tion.jda.api.managers.AutoModRuleManager; import net.dv8tion.jda.api.requests.restaction.AuditableRestAction; @@ -78,68 +79,183 @@ public interface AutoModRule extends ISnowflake */ int MAX_EXEMPT_CHANNELS = 50; + /** + * The {@link Guild} this rule belongs to. + * + * @return The guild + */ @Nonnull Guild getGuild(); - long getOwnerIdLong(); + /** + * The user id of the creator of this rule. + * + * @return The owner id + */ + long getCreatorIdLong(); + /** + * The user id of the creator of this rule. + * + * @return The owner id + */ @Nonnull - default String getOwnerId() + default String getCreatorId() { - return Long.toUnsignedString(getOwnerIdLong()); + return Long.toUnsignedString(getCreatorIdLong()); } + /** + * The name of this rule. + * + * @return The name + */ @Nonnull String getName(); + /** + * The type of event that triggers this rule. + * + * @return The event type + */ @Nonnull AutoModEventType getEventType(); + /** + * The type of trigger that this rule uses. + * + * @return The trigger type + */ @Nonnull AutoModTriggerType getTriggerType(); + /** + * Whether this rule is enabled. + * + * @return True, if enabled + */ boolean isEnabled(); + /** + * The roles which are exempt from the rule. + *

    All members of the exempt roles will bypass the rule. + * + * @return The exempt roles + */ @Nonnull List getExemptRoles(); + /** + * The channels which are exempt from the rule. + *

    All messages in the listed channels will bypass the rule. + * + * @return The exempt channels + */ @Nonnull List getExemptChannels(); + /** + * The automated {@link AutoModResponse AutoModResponses} that will be activated when the rule is triggered. + * + * @return The {@link AutoModResponse AutoModResponses} + */ @Nonnull List getActions(); + /** + * The keywords that are blocked by this rule. + *

    Only applies to {@link AutoModTriggerType#KEYWORD}. + * + * @return The blocked keywords + */ @Nonnull List getFilteredKeywords(); + /** + * The regex patterns that are blocked by this rule. + *

    Only applies to {@link AutoModTriggerType#KEYWORD}. + * + * @return The blocked regex patterns + */ @Nonnull List getFilteredRegex(); + /** + * The keyword presets that are blocked by this rule. + *

    Only applies to {@link AutoModTriggerType#KEYWORD_PRESET}. + * + * @return The blocked keyword presets + */ @Nonnull EnumSet getFilteredPresets(); + /** + * The whitelisted keywords that are allowed by this rule. + *

    Only applies to {@link AutoModTriggerType#KEYWORD} and {@link AutoModTriggerType#KEYWORD_PRESET}. + * + * @return The whitelisted keywords + */ @Nonnull List getAllowlist(); + /** + * The maximum amount of mentions that are allowed in a message. + *

    Only applies to {@link AutoModTriggerType#MENTION_SPAM}. + * + * @return The mention limit, or 0 if this is not using {@link AutoModTriggerType#MENTION_SPAM} + */ int getMentionLimit(); + /** + * Returns an {@link AutoModRuleManager}, which can be used to modify this rule. + *

    The manager allows modifying multiple fields in a single request. + *
    You modify multiple fields in one request by chaining setters before calling {@link net.dv8tion.jda.api.requests.RestAction#queue() RestAction.queue()}. + * + * @throws InsufficientPermissionException + * If the currently logged in account does not have the {@link net.dv8tion.jda.api.Permission#MANAGE_SERVER MANAGE_SERVER} permission. + * + * @return The manager instance + */ @Nonnull default AutoModRuleManager getManager() { return getGuild().modifyAutoModRuleById(getId()); } + /** + * Deletes this rule. + * + * @throws InsufficientPermissionException + * If the currently logged in account does not have the {@link net.dv8tion.jda.api.Permission#MANAGE_SERVER MANAGE_SERVER} permission. + * + * @return {@link net.dv8tion.jda.api.requests.RestAction RestAction} - Type: {@link Void} + */ @Nonnull default AuditableRestAction delete() { return getGuild().deleteAutoModRuleById(getId()); } + /** + * Keyword presets that can be used in {@link AutoModRule#getFilteredPresets()}. + */ enum KeywordPreset { + /** + * Words that can be considered as swearing or cursing. + */ PROFANITY(1), + /** + * Words that can be considered as sexual in nature. + */ SEXUAL_CONTENT(2), + /** + * Words that can be considered as slurs or insults. + */ SLURS(3), + /** + * Placeholder for unknown values. + */ UNKNOWN(-1); private final int key; @@ -149,11 +265,24 @@ enum KeywordPreset this.key = key; } + /** + * The raw value used by Discord to represent this preset. + * + * @return The raw value + */ public int getKey() { return key; } + /** + * The {@link KeywordPreset} represented by the provided key. + * + * @param key + * The raw key + * + * @return The {@link KeywordPreset} or {@link #UNKNOWN} + */ @Nonnull public static KeywordPreset fromKey(int key) { diff --git a/src/main/java/net/dv8tion/jda/internal/entities/automod/AutoModRuleImpl.java b/src/main/java/net/dv8tion/jda/internal/entities/automod/AutoModRuleImpl.java index dfc61dcea0..b57e6e122a 100644 --- a/src/main/java/net/dv8tion/jda/internal/entities/automod/AutoModRuleImpl.java +++ b/src/main/java/net/dv8tion/jda/internal/entities/automod/AutoModRuleImpl.java @@ -78,7 +78,7 @@ public Guild getGuild() } @Override - public long getOwnerIdLong() + public long getCreatorIdLong() { return ownerId; } From 536f355c8f29310b5b2024d7db976d370a8481a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Spie=C3=9F?= Date: Sun, 2 Apr 2023 14:58:05 +0200 Subject: [PATCH 29/39] Add docs to AutoModRuleManager --- .../net/dv8tion/jda/api/entities/Guild.java | 20 +++ .../jda/api/managers/AutoModRuleManager.java | 140 ++++++++++++++++++ 2 files changed, 160 insertions(+) diff --git a/src/main/java/net/dv8tion/jda/api/entities/Guild.java b/src/main/java/net/dv8tion/jda/api/entities/Guild.java index 11f396b050..d4dc257013 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/Guild.java +++ b/src/main/java/net/dv8tion/jda/api/entities/Guild.java @@ -423,10 +423,30 @@ default RestAction retrieveAutoModRuleById(long id) @CheckReturnValue AuditableRestAction createAutoModRule(@Nonnull AutoModRuleData data); + /** + * Returns an {@link AutoModRuleManager}, which can be used to modify the rule for the provided id. + *

    The manager allows modifying multiple fields in a single request. + *
    You modify multiple fields in one request by chaining setters before calling {@link net.dv8tion.jda.api.requests.RestAction#queue() RestAction.queue()}. + * + * @throws InsufficientPermissionException + * If the currently logged in account does not have the {@link net.dv8tion.jda.api.Permission#MANAGE_SERVER MANAGE_SERVER} permission. + * + * @return The manager instance + */ @Nonnull @CheckReturnValue AutoModRuleManager modifyAutoModRuleById(@Nonnull String id); + /** + * Returns an {@link AutoModRuleManager}, which can be used to modify the rule for the provided id. + *

    The manager allows modifying multiple fields in a single request. + *
    You modify multiple fields in one request by chaining setters before calling {@link net.dv8tion.jda.api.requests.RestAction#queue() RestAction.queue()}. + * + * @throws InsufficientPermissionException + * If the currently logged in account does not have the {@link net.dv8tion.jda.api.Permission#MANAGE_SERVER MANAGE_SERVER} permission. + * + * @return The manager instance + */ @Nonnull @CheckReturnValue default AutoModRuleManager modifyAutoModRuleById(long id) diff --git a/src/main/java/net/dv8tion/jda/api/managers/AutoModRuleManager.java b/src/main/java/net/dv8tion/jda/api/managers/AutoModRuleManager.java index 7863a8cca3..5d6654369f 100644 --- a/src/main/java/net/dv8tion/jda/api/managers/AutoModRuleManager.java +++ b/src/main/java/net/dv8tion/jda/api/managers/AutoModRuleManager.java @@ -16,8 +16,10 @@ package net.dv8tion.jda.api.managers; +import net.dv8tion.jda.api.entities.Guild; import net.dv8tion.jda.api.entities.Role; import net.dv8tion.jda.api.entities.automod.AutoModResponse; +import net.dv8tion.jda.api.entities.automod.AutoModRule; import net.dv8tion.jda.api.entities.automod.build.TriggerConfig; import net.dv8tion.jda.api.entities.channel.middleman.GuildChannel; import net.dv8tion.jda.internal.utils.Checks; @@ -27,13 +29,37 @@ import java.util.Arrays; import java.util.Collection; +/** + * Manager providing functionality to update one or more fields for an {@link AutoModRule}. + * + *

    Example + *

    {@code
    + * manager.setName("Discord Invites")
    + *        .setEnables(false)
    + *        .queue();
    + * manager.reset(AutoModRuleManager.NAME | AutoModRuleManager.ENABLED)
    + *        .setName("Invites")
    + *        .setEnabled(true)
    + *        .queue();
    + * }
    + * + * @see Guild#modifyAutoModRuleById(long) + * @see Guild#modifyAutoModRuleById(String) + * @see AutoModRule#getManager() + */ public interface AutoModRuleManager extends Manager { + /** Used to reset the name field. */ long NAME = 1; + /** Used to reset the enabled field. */ long ENABLED = 1 << 1; + /** Used to reset the response field. */ long RESPONSE = 1 << 2; + /** Used to reset the exempt roles field. */ long EXEMPT_ROLES = 1 << 3; + /** Used to reset the exempt channels field. */ long EXEMPT_CHANNELS = 1 << 4; + /** Used to reset the trigger metadata field. */ long TRIGGER_METADATA = 1 << 5; /** @@ -84,10 +110,33 @@ public interface AutoModRuleManager extends Manager @Override AutoModRuleManager reset(long... fields); + /** + * Sets the name of the selected {@link AutoModRule}. + * + *

    A rule name must be between 1-{@value AutoModRule#MAX_RULE_NAME_LENGTH} characters long! + * + * @param name + * The new name for the selected {@link AutoModRule} + * + * @throws IllegalArgumentException + * If the provided name is {@code null} or not between 1-{@value AutoModRule#MAX_RULE_NAME_LENGTH} characters long + * + * @return AutoModRuleManager for chaining convenience + */ @Nonnull @CheckReturnValue AutoModRuleManager setName(@Nonnull String name); + /** + * Sets the enabled state of the selected {@link AutoModRule}. + * + *

    When a rule is disabled, it will not be applied to any messages. + * + * @param enabled + * True, if the selected {@link AutoModRule} should be enabled + * + * @return AutoModRuleManager for chaining convenience + */ @Nonnull @CheckReturnValue AutoModRuleManager setEnabled(boolean enabled); @@ -96,10 +145,38 @@ public interface AutoModRuleManager extends Manager // @CheckReturnValue // AutoModRuleManager setEventType(@Nonnull AutoModEventType type); + /** + * Sets what the rule should do upon triggering. + * + *

    Note that each response type can only be used once. + * If multiple responses of the same type are provided, the last one is used. + * + * @param responses + * The responses to configure + * + * @throws IllegalArgumentException + * If null is provided + * + * @return AutoModRuleManager for chaining convenience + */ @Nonnull @CheckReturnValue AutoModRuleManager setResponses(@Nonnull Collection responses); + /** + * Sets what the rule should do upon triggering. + * + *

    Note that each response type can only be used once. + * If multiple responses of the same type are provided, the last one is used. + * + * @param responses + * The responses to configure + * + * @throws IllegalArgumentException + * If null is provided + * + * @return AutoModRuleManager for chaining convenience + */ @Nonnull @CheckReturnValue default AutoModRuleManager setResponses(@Nonnull AutoModResponse... responses) @@ -108,10 +185,36 @@ default AutoModRuleManager setResponses(@Nonnull AutoModResponse... responses) return setResponses(Arrays.asList(responses)); } + /** + * Set which roles can bypass this rule. + * + *

    Roles added to the exemptions will allow all of its members to bypass this rule. + * + * @param roles + * The roles to exempt (up to {@value AutoModRule#MAX_EXEMPT_ROLES} roles) + * + * @throws IllegalArgumentException + * If null is provided or the number of roles exceeds {@value AutoModRule#MAX_EXEMPT_ROLES} + * + * @return AutoModRuleManager for chaining convenience + */ @Nonnull @CheckReturnValue AutoModRuleManager setExemptRoles(@Nonnull Collection roles); + /** + * Set which roles can bypass this rule. + * + *

    Roles added to the exemptions will allow all of its members to bypass this rule. + * + * @param roles + * The roles to exempt (up to {@value AutoModRule#MAX_EXEMPT_ROLES} roles) + * + * @throws IllegalArgumentException + * If null is provided or the number of roles exceeds {@value AutoModRule#MAX_EXEMPT_ROLES} + * + * @return AutoModRuleManager for chaining convenience + */ @Nonnull @CheckReturnValue default AutoModRuleManager setExemptRoles(@Nonnull Role... roles) @@ -120,10 +223,36 @@ default AutoModRuleManager setExemptRoles(@Nonnull Role... roles) return setExemptRoles(Arrays.asList(roles)); } + /** + * Set which channels can bypass this rule. + * + *

    No messages sent in this channel will trigger the rule. + * + * @param channels + * The channels to add (up to {@value AutoModRule#MAX_EXEMPT_CHANNELS} channels) + * + * @throws IllegalArgumentException + * If null is provided or the number of channels exceeds {@value AutoModRule#MAX_EXEMPT_CHANNELS} + * + * @return AutoModRuleManager for chaining convenience + */ @Nonnull @CheckReturnValue AutoModRuleManager setExemptChannels(@Nonnull Collection channels); + /** + * Set which channels can bypass this rule. + * + *

    No messages sent in this channel will trigger the rule. + * + * @param channels + * The channels to add (up to {@value AutoModRule#MAX_EXEMPT_CHANNELS} channels) + * + * @throws IllegalArgumentException + * If null is provided or the number of channels exceeds {@value AutoModRule#MAX_EXEMPT_CHANNELS} + * + * @return AutoModRuleManager for chaining convenience + */ @Nonnull @CheckReturnValue default AutoModRuleManager setExemptChannels(@Nonnull GuildChannel... channels) @@ -132,6 +261,17 @@ default AutoModRuleManager setExemptChannels(@Nonnull GuildChannel... channels) return setExemptChannels(Arrays.asList(channels)); } + /** + * Change the {@link TriggerConfig} for this rule. + * + * @param config + * The new config + * + * @throws IllegalArgumentException + * If null is provided + * + * @return AutoModRuleManager for chaining convenience + */ @Nonnull @CheckReturnValue AutoModRuleManager setTriggerConfig(@Nonnull TriggerConfig config); From 6c5b1ba57648100b59cf6220992aa75685c219fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Spie=C3=9F?= Date: Sun, 2 Apr 2023 15:02:46 +0200 Subject: [PATCH 30/39] Add checks to manager --- .../managers/AutoModRuleManagerImpl.java | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/main/java/net/dv8tion/jda/internal/managers/AutoModRuleManagerImpl.java b/src/main/java/net/dv8tion/jda/internal/managers/AutoModRuleManagerImpl.java index 2a7b58307e..d4edabbd1f 100644 --- a/src/main/java/net/dv8tion/jda/internal/managers/AutoModRuleManagerImpl.java +++ b/src/main/java/net/dv8tion/jda/internal/managers/AutoModRuleManagerImpl.java @@ -19,6 +19,7 @@ import net.dv8tion.jda.api.entities.Guild; import net.dv8tion.jda.api.entities.Role; import net.dv8tion.jda.api.entities.automod.AutoModResponse; +import net.dv8tion.jda.api.entities.automod.AutoModRule; import net.dv8tion.jda.api.entities.automod.AutoModTriggerType; import net.dv8tion.jda.api.entities.automod.build.TriggerConfig; import net.dv8tion.jda.api.entities.channel.middleman.GuildChannel; @@ -38,6 +39,7 @@ public class AutoModRuleManagerImpl extends ManagerBase implements AutoModRuleManager { + protected final Guild guild; protected String name; protected boolean enabled; protected EnumMap responses; @@ -48,12 +50,15 @@ public class AutoModRuleManagerImpl extends ManagerBase impl public AutoModRuleManagerImpl(Guild guild, String ruleId) { super(guild.getJDA(), Route.AutoModeration.UPDATE_RULE.compile(guild.getId(), ruleId)); + this.guild = guild; } @Nonnull @Override public AutoModRuleManager setName(@Nonnull String name) { + Checks.notEmpty(name, "Name"); + Checks.notLonger(name, AutoModRule.MAX_RULE_NAME_LENGTH, "Name"); this.name = name; set |= NAME; return this; @@ -72,7 +77,14 @@ public AutoModRuleManager setEnabled(boolean enabled) @Override public AutoModRuleManager setResponses(@Nonnull Collection responses) { + Checks.noneNull(responses, "Responses"); this.responses = new EnumMap<>(AutoModResponse.Type.class); + for (AutoModResponse response : responses) + { + AutoModResponse.Type type = response.getType(); + Checks.check(type != AutoModResponse.Type.UNKNOWN, "Cannot add response with unknown response type!"); + this.responses.put(type, response); + } set |= RESPONSE; return this; } @@ -81,6 +93,10 @@ public AutoModRuleManager setResponses(@Nonnull Collection roles) { + Checks.noneNull(roles, "Roles"); + Checks.check(roles.size() <= AutoModRule.MAX_EXEMPT_ROLES, "Cannot have more than %d exempt roles!", AutoModRule.MAX_EXEMPT_ROLES); + for (Role role : roles) + Checks.check(role.getGuild().equals(guild), "Role %s is not from the same guild as this rule!", role); this.exemptRoles = new ArrayList<>(roles); set |= EXEMPT_ROLES; return this; @@ -90,6 +106,10 @@ public AutoModRuleManager setExemptRoles(@Nonnull Collection roles) @Override public AutoModRuleManager setExemptChannels(@Nonnull Collection channels) { + Checks.noneNull(channels, "Channels"); + Checks.check(channels.size() <= AutoModRule.MAX_EXEMPT_CHANNELS, "Cannot have more than %d exempt channels!", AutoModRule.MAX_EXEMPT_CHANNELS); + for (GuildChannel channel : channels) + Checks.check(channel.getGuild().equals(guild), "Channel %s is not from the same guild as this rule!", channel); this.exemptChannels = new ArrayList<>(channels); set |= EXEMPT_CHANNELS; return this; From 5430394e57ec49c07ba21bced53b9e09091940e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Spie=C3=9F?= Date: Sun, 2 Apr 2023 15:32:15 +0200 Subject: [PATCH 31/39] Improve checks --- .../automod/build/AutoModRuleData.java | 29 +++++++++++++++---- .../jda/api/managers/AutoModRuleManager.java | 10 +++++-- .../managers/AutoModRuleManagerImpl.java | 1 + 3 files changed, 32 insertions(+), 8 deletions(-) diff --git a/src/main/java/net/dv8tion/jda/api/entities/automod/build/AutoModRuleData.java b/src/main/java/net/dv8tion/jda/api/entities/automod/build/AutoModRuleData.java index f999b00709..33461ff153 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/automod/build/AutoModRuleData.java +++ b/src/main/java/net/dv8tion/jda/api/entities/automod/build/AutoModRuleData.java @@ -38,6 +38,8 @@ /** * Data class used to create new {@link AutoModRule AutoModRules}. * + *

    Every rule must configure at least one {@link #putResponses(AutoModResponse...) response}. + * *

    Example
    * *

    {@code
    @@ -140,7 +142,7 @@ public AutoModRuleData setEnabled(boolean enabled)
          *         The responses to configure
          *
          * @throws IllegalArgumentException
    -     *         If null is provided
    +     *         If null is provided or any of the responses has an {@link AutoModResponse.Type#UNKNOWN unknown type}
          *
          * @return The same {@link AutoModRuleData} instance
          */
    @@ -149,7 +151,11 @@ public AutoModRuleData putResponses(@Nonnull AutoModResponse... responses)
         {
             Checks.noneNull(responses, "Responses");
             for (AutoModResponse response : responses)
    -            actions.put(response.getType(), response);
    +        {
    +            AutoModResponse.Type type = response.getType();
    +            Checks.check(type != AutoModResponse.Type.UNKNOWN, "Cannot create response with unknown response type");
    +            actions.put(type, response);
    +        }
             return this;
         }
     
    @@ -164,7 +170,7 @@ public AutoModRuleData putResponses(@Nonnull AutoModResponse... responses)
          *         The responses to configure
          *
          * @throws IllegalArgumentException
    -     *         If null is provided
    +     *         If null is provided or any of the responses has an {@link AutoModResponse.Type#UNKNOWN unknown type}
          *
          * @return The same {@link AutoModRuleData} instance
          */
    @@ -173,7 +179,11 @@ public AutoModRuleData putResponses(@Nonnull Collection
          *         The responses to configure
          *
          * @throws IllegalArgumentException
    -     *         If null is provided
    +     *         
      + *
    • If {@code null} or {@link AutoModResponse.Type#UNKNOWN} is provided
    • + *
    • If the collection is empty
    • + *
    * * @return AutoModRuleManager for chaining convenience */ @@ -173,7 +176,10 @@ public interface AutoModRuleManager extends Manager * The responses to configure * * @throws IllegalArgumentException - * If null is provided + *
      + *
    • If {@code null} or {@link AutoModResponse.Type#UNKNOWN} is provided
    • + *
    • If the collection is empty
    • + *
    * * @return AutoModRuleManager for chaining convenience */ diff --git a/src/main/java/net/dv8tion/jda/internal/managers/AutoModRuleManagerImpl.java b/src/main/java/net/dv8tion/jda/internal/managers/AutoModRuleManagerImpl.java index d4edabbd1f..ce6d34c85b 100644 --- a/src/main/java/net/dv8tion/jda/internal/managers/AutoModRuleManagerImpl.java +++ b/src/main/java/net/dv8tion/jda/internal/managers/AutoModRuleManagerImpl.java @@ -78,6 +78,7 @@ public AutoModRuleManager setEnabled(boolean enabled) public AutoModRuleManager setResponses(@Nonnull Collection responses) { Checks.noneNull(responses, "Responses"); + Checks.notEmpty(responses, "Responses"); this.responses = new EnumMap<>(AutoModResponse.Type.class); for (AutoModResponse response : responses) { From 97a4221500a99c03a073e5f98c55b708d5021ef0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Spie=C3=9F?= Date: Sun, 2 Apr 2023 15:41:25 +0200 Subject: [PATCH 32/39] Add new ErrorResponses --- .../net/dv8tion/jda/api/entities/Message.java | 146 +++++++++++++++++- .../jda/api/entities/WebhookClient.java | 72 +++++++++ .../channel/concrete/ForumChannel.java | 10 ++ .../channel/middleman/MessageChannel.java | 60 +++++++ .../callbacks/IReplyCallback.java | 115 ++++++++++++++ .../jda/api/requests/ErrorResponse.java | 4 + 6 files changed, 400 insertions(+), 7 deletions(-) diff --git a/src/main/java/net/dv8tion/jda/api/entities/Message.java b/src/main/java/net/dv8tion/jda/api/entities/Message.java index b8a2fa7f13..0363a416cc 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/Message.java +++ b/src/main/java/net/dv8tion/jda/api/entities/Message.java @@ -1129,6 +1129,18 @@ default MessageEditAction editMessageAttachments(@Nonnull AttachedFile... attach * *

    For further info, see {@link GuildMessageChannel#sendStickers(Collection)} and {@link MessageCreateAction#setMessageReference(Message)}. * + *

    Possible {@link net.dv8tion.jda.api.requests.ErrorResponse ErrorResponses} include: + *

      + *
    • {@link net.dv8tion.jda.api.requests.ErrorResponse#UNKNOWN_MESSAGE UNKNOWN_MESSAGE} + *
      If this message no longer exists
    • + * + *
    • {@link net.dv8tion.jda.api.requests.ErrorResponse#MESSAGE_BLOCKED_BY_AUTOMOD MESSAGE_BLOCKED_BY_AUTOMOD} + *
      If this message was blocked by an {@link net.dv8tion.jda.api.entities.automod.AutoModRule AutoModRule}
    • + * + *
    • {@link net.dv8tion.jda.api.requests.ErrorResponse#MESSAGE_BLOCKED_BY_HARMFUL_LINK_FILTER MESSAGE_BLOCKED_BY_HARMFUL_LINK_FILTER} + *
      If this message was blocked by the harmful link filter
    • + *
    + * * @param stickers * The 1-3 stickers to send * @@ -1169,6 +1181,18 @@ default MessageCreateAction replyStickers(@Nonnull CollectionFor further info, see {@link GuildMessageChannel#sendStickers(Collection)} and {@link MessageCreateAction#setMessageReference(Message)}. * + *

    Possible {@link net.dv8tion.jda.api.requests.ErrorResponse ErrorResponses} include: + *

      + *
    • {@link net.dv8tion.jda.api.requests.ErrorResponse#UNKNOWN_MESSAGE UNKNOWN_MESSAGE} + *
      If this message no longer exists
    • + * + *
    • {@link net.dv8tion.jda.api.requests.ErrorResponse#MESSAGE_BLOCKED_BY_AUTOMOD MESSAGE_BLOCKED_BY_AUTOMOD} + *
      If this message was blocked by an {@link net.dv8tion.jda.api.entities.automod.AutoModRule AutoModRule}
    • + * + *
    • {@link net.dv8tion.jda.api.requests.ErrorResponse#MESSAGE_BLOCKED_BY_HARMFUL_LINK_FILTER MESSAGE_BLOCKED_BY_HARMFUL_LINK_FILTER} + *
      If this message was blocked by the harmful link filter
    • + *
    + * * @param stickers * The 1-3 stickers to send * @@ -1201,7 +1225,19 @@ default MessageCreateAction replyStickers(@Nonnull StickerSnowflake... stickers) } /** - * Shortcut for {@code getChannel().sendMessage(content).setMessageReference(this)}- + * Shortcut for {@code getChannel().sendMessage(content).setMessageReference(this)}. + * + *

    Possible {@link net.dv8tion.jda.api.requests.ErrorResponse ErrorResponses} include: + *

      + *
    • {@link net.dv8tion.jda.api.requests.ErrorResponse#UNKNOWN_MESSAGE UNKNOWN_MESSAGE} + *
      If this message no longer exists
    • + * + *
    • {@link net.dv8tion.jda.api.requests.ErrorResponse#MESSAGE_BLOCKED_BY_AUTOMOD MESSAGE_BLOCKED_BY_AUTOMOD} + *
      If this message was blocked by an {@link net.dv8tion.jda.api.entities.automod.AutoModRule AutoModRule}
    • + * + *
    • {@link net.dv8tion.jda.api.requests.ErrorResponse#MESSAGE_BLOCKED_BY_HARMFUL_LINK_FILTER MESSAGE_BLOCKED_BY_HARMFUL_LINK_FILTER} + *
      If this message was blocked by the harmful link filter
    • + *
    * * @param content * The reply content @@ -1221,7 +1257,19 @@ default MessageCreateAction reply(@Nonnull CharSequence content) } /** - * Shortcut for {@code getChannel().sendMessage(data).setMessageReference(this)}- + * Shortcut for {@code getChannel().sendMessage(data).setMessageReference(this)}. + * + *

    Possible {@link net.dv8tion.jda.api.requests.ErrorResponse ErrorResponses} include: + *

      + *
    • {@link net.dv8tion.jda.api.requests.ErrorResponse#UNKNOWN_MESSAGE UNKNOWN_MESSAGE} + *
      If this message no longer exists
    • + * + *
    • {@link net.dv8tion.jda.api.requests.ErrorResponse#MESSAGE_BLOCKED_BY_AUTOMOD MESSAGE_BLOCKED_BY_AUTOMOD} + *
      If this message was blocked by an {@link net.dv8tion.jda.api.entities.automod.AutoModRule AutoModRule}
    • + * + *
    • {@link net.dv8tion.jda.api.requests.ErrorResponse#MESSAGE_BLOCKED_BY_HARMFUL_LINK_FILTER MESSAGE_BLOCKED_BY_HARMFUL_LINK_FILTER} + *
      If this message was blocked by the harmful link filter
    • + *
    * * @param msg * The {@link MessageCreateData} to send @@ -1241,7 +1289,19 @@ default MessageCreateAction reply(@Nonnull MessageCreateData msg) } /** - * Shortcut for {@code getChannel().sendMessageEmbeds(embed, other).setMessageReference(this)}- + * Shortcut for {@code getChannel().sendMessageEmbeds(embed, other).setMessageReference(this)}. + * + *

    Possible {@link net.dv8tion.jda.api.requests.ErrorResponse ErrorResponses} include: + *

      + *
    • {@link net.dv8tion.jda.api.requests.ErrorResponse#UNKNOWN_MESSAGE UNKNOWN_MESSAGE} + *
      If this message no longer exists
    • + * + *
    • {@link net.dv8tion.jda.api.requests.ErrorResponse#MESSAGE_BLOCKED_BY_AUTOMOD MESSAGE_BLOCKED_BY_AUTOMOD} + *
      If this message was blocked by an {@link net.dv8tion.jda.api.entities.automod.AutoModRule AutoModRule}
    • + * + *
    • {@link net.dv8tion.jda.api.requests.ErrorResponse#MESSAGE_BLOCKED_BY_HARMFUL_LINK_FILTER MESSAGE_BLOCKED_BY_HARMFUL_LINK_FILTER} + *
      If this message was blocked by the harmful link filter
    • + *
    * * @param embed * The {@link MessageEmbed} to send @@ -1268,7 +1328,19 @@ default MessageCreateAction replyEmbeds(@Nonnull MessageEmbed embed, @Nonnull Me } /** - * Shortcut for {@code getChannel().sendMessageEmbeds(embeds).setMessageReference(this)}- + * Shortcut for {@code getChannel().sendMessageEmbeds(embeds).setMessageReference(this)}. + * + *

    Possible {@link net.dv8tion.jda.api.requests.ErrorResponse ErrorResponses} include: + *

      + *
    • {@link net.dv8tion.jda.api.requests.ErrorResponse#UNKNOWN_MESSAGE UNKNOWN_MESSAGE} + *
      If this message no longer exists
    • + * + *
    • {@link net.dv8tion.jda.api.requests.ErrorResponse#MESSAGE_BLOCKED_BY_AUTOMOD MESSAGE_BLOCKED_BY_AUTOMOD} + *
      If this message was blocked by an {@link net.dv8tion.jda.api.entities.automod.AutoModRule AutoModRule}
    • + * + *
    • {@link net.dv8tion.jda.api.requests.ErrorResponse#MESSAGE_BLOCKED_BY_HARMFUL_LINK_FILTER MESSAGE_BLOCKED_BY_HARMFUL_LINK_FILTER} + *
      If this message was blocked by the harmful link filter
    • + *
    * * @param embeds * The {@link MessageEmbed MessageEmbeds} to send @@ -1290,6 +1362,18 @@ default MessageCreateAction replyEmbeds(@Nonnull CollectionPossible {@link net.dv8tion.jda.api.requests.ErrorResponse ErrorResponses} include: + *
      + *
    • {@link net.dv8tion.jda.api.requests.ErrorResponse#UNKNOWN_MESSAGE UNKNOWN_MESSAGE} + *
      If this message no longer exists
    • + * + *
    • {@link net.dv8tion.jda.api.requests.ErrorResponse#MESSAGE_BLOCKED_BY_AUTOMOD MESSAGE_BLOCKED_BY_AUTOMOD} + *
      If this message was blocked by an {@link net.dv8tion.jda.api.entities.automod.AutoModRule AutoModRule}
    • + * + *
    • {@link net.dv8tion.jda.api.requests.ErrorResponse#MESSAGE_BLOCKED_BY_HARMFUL_LINK_FILTER MESSAGE_BLOCKED_BY_HARMFUL_LINK_FILTER} + *
      If this message was blocked by the harmful link filter
    • + *
    + * * @param component * The {@link LayoutComponent} to send * @param other @@ -1317,6 +1401,18 @@ default MessageCreateAction replyComponents(@Nonnull LayoutComponent component, /** * Shortcut for {@code getChannel().sendMessageComponents(components).setMessageReference(this)}. * + *

    Possible {@link net.dv8tion.jda.api.requests.ErrorResponse ErrorResponses} include: + *

      + *
    • {@link net.dv8tion.jda.api.requests.ErrorResponse#UNKNOWN_MESSAGE UNKNOWN_MESSAGE} + *
      If this message no longer exists
    • + * + *
    • {@link net.dv8tion.jda.api.requests.ErrorResponse#MESSAGE_BLOCKED_BY_AUTOMOD MESSAGE_BLOCKED_BY_AUTOMOD} + *
      If this message was blocked by an {@link net.dv8tion.jda.api.entities.automod.AutoModRule AutoModRule}
    • + * + *
    • {@link net.dv8tion.jda.api.requests.ErrorResponse#MESSAGE_BLOCKED_BY_HARMFUL_LINK_FILTER MESSAGE_BLOCKED_BY_HARMFUL_LINK_FILTER} + *
      If this message was blocked by the harmful link filter
    • + *
    + * * @param components * The {@link LayoutComponent LayoutComponents} to send * @@ -1335,7 +1431,19 @@ default MessageCreateAction replyComponents(@Nonnull CollectionPossible {@link net.dv8tion.jda.api.requests.ErrorResponse ErrorResponses} include: + *
      + *
    • {@link net.dv8tion.jda.api.requests.ErrorResponse#UNKNOWN_MESSAGE UNKNOWN_MESSAGE} + *
      If this message no longer exists
    • + * + *
    • {@link net.dv8tion.jda.api.requests.ErrorResponse#MESSAGE_BLOCKED_BY_AUTOMOD MESSAGE_BLOCKED_BY_AUTOMOD} + *
      If this message was blocked by an {@link net.dv8tion.jda.api.entities.automod.AutoModRule AutoModRule}
    • + * + *
    • {@link net.dv8tion.jda.api.requests.ErrorResponse#MESSAGE_BLOCKED_BY_HARMFUL_LINK_FILTER MESSAGE_BLOCKED_BY_HARMFUL_LINK_FILTER} + *
      If this message was blocked by the harmful link filter
    • + *
    * * @param format * The format string @@ -1357,7 +1465,19 @@ default MessageCreateAction replyFormat(@Nonnull String format, @Nonnull Object. } /** - * Shortcut for {@code getChannel().sendFiles(files).setMessageReference(this)}- + * Shortcut for {@code getChannel().sendFiles(files).setMessageReference(this)}. + * + *

    Possible {@link net.dv8tion.jda.api.requests.ErrorResponse ErrorResponses} include: + *

      + *
    • {@link net.dv8tion.jda.api.requests.ErrorResponse#UNKNOWN_MESSAGE UNKNOWN_MESSAGE} + *
      If this message no longer exists
    • + * + *
    • {@link net.dv8tion.jda.api.requests.ErrorResponse#MESSAGE_BLOCKED_BY_AUTOMOD MESSAGE_BLOCKED_BY_AUTOMOD} + *
      If this message was blocked by an {@link net.dv8tion.jda.api.entities.automod.AutoModRule AutoModRule}
    • + * + *
    • {@link net.dv8tion.jda.api.requests.ErrorResponse#MESSAGE_BLOCKED_BY_HARMFUL_LINK_FILTER MESSAGE_BLOCKED_BY_HARMFUL_LINK_FILTER} + *
      If this message was blocked by the harmful link filter
    • + *
    * * @param files * The {@link FileUpload FileUploads} to send @@ -1377,7 +1497,19 @@ default MessageCreateAction replyFiles(@Nonnull FileUpload... files) } /** - * Shortcut for {@code getChannel().sendFiles(files).setMessageReference(this)}- + * Shortcut for {@code getChannel().sendFiles(files).setMessageReference(this)}. + * + *

    Possible {@link net.dv8tion.jda.api.requests.ErrorResponse ErrorResponses} include: + *

      + *
    • {@link net.dv8tion.jda.api.requests.ErrorResponse#UNKNOWN_MESSAGE UNKNOWN_MESSAGE} + *
      If this message no longer exists
    • + * + *
    • {@link net.dv8tion.jda.api.requests.ErrorResponse#MESSAGE_BLOCKED_BY_AUTOMOD MESSAGE_BLOCKED_BY_AUTOMOD} + *
      If this message was blocked by an {@link net.dv8tion.jda.api.entities.automod.AutoModRule AutoModRule}
    • + * + *
    • {@link net.dv8tion.jda.api.requests.ErrorResponse#MESSAGE_BLOCKED_BY_HARMFUL_LINK_FILTER MESSAGE_BLOCKED_BY_HARMFUL_LINK_FILTER} + *
      If this message was blocked by the harmful link filter
    • + *
    * * @param files * The {@link FileUpload FileUploads} to send diff --git a/src/main/java/net/dv8tion/jda/api/entities/WebhookClient.java b/src/main/java/net/dv8tion/jda/api/entities/WebhookClient.java index 860f32d9b8..d0fe01f6d7 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/WebhookClient.java +++ b/src/main/java/net/dv8tion/jda/api/entities/WebhookClient.java @@ -53,6 +53,12 @@ public interface WebhookClient *
      *
    • {@link net.dv8tion.jda.api.requests.ErrorResponse#UNKNOWN_WEBHOOK UNKNOWN_WEBHOOK} *
      The webhook is no longer available, either it was deleted or in case of interactions it expired.
    • + * + *
    • {@link net.dv8tion.jda.api.requests.ErrorResponse#MESSAGE_BLOCKED_BY_AUTOMOD MESSAGE_BLOCKED_BY_AUTOMOD} + *
      If this message was blocked by an {@link net.dv8tion.jda.api.entities.automod.AutoModRule AutoModRule}
    • + * + *
    • {@link net.dv8tion.jda.api.requests.ErrorResponse#MESSAGE_BLOCKED_BY_HARMFUL_LINK_FILTER MESSAGE_BLOCKED_BY_HARMFUL_LINK_FILTER} + *
      If this message was blocked by the harmful link filter
    • *
    * * @param content @@ -76,6 +82,12 @@ public interface WebhookClient *
      *
    • {@link net.dv8tion.jda.api.requests.ErrorResponse#UNKNOWN_WEBHOOK UNKNOWN_WEBHOOK} *
      The webhook is no longer available, either it was deleted or in case of interactions it expired.
    • + * + *
    • {@link net.dv8tion.jda.api.requests.ErrorResponse#MESSAGE_BLOCKED_BY_AUTOMOD MESSAGE_BLOCKED_BY_AUTOMOD} + *
      If this message was blocked by an {@link net.dv8tion.jda.api.entities.automod.AutoModRule AutoModRule}
    • + * + *
    • {@link net.dv8tion.jda.api.requests.ErrorResponse#MESSAGE_BLOCKED_BY_HARMFUL_LINK_FILTER MESSAGE_BLOCKED_BY_HARMFUL_LINK_FILTER} + *
      If this message was blocked by the harmful link filter
    • *
    * * @param message @@ -101,6 +113,12 @@ public interface WebhookClient *
      *
    • {@link net.dv8tion.jda.api.requests.ErrorResponse#UNKNOWN_WEBHOOK UNKNOWN_WEBHOOK} *
      The webhook is no longer available, either it was deleted or in case of interactions it expired.
    • + * + *
    • {@link net.dv8tion.jda.api.requests.ErrorResponse#MESSAGE_BLOCKED_BY_AUTOMOD MESSAGE_BLOCKED_BY_AUTOMOD} + *
      If this message was blocked by an {@link net.dv8tion.jda.api.entities.automod.AutoModRule AutoModRule}
    • + * + *
    • {@link net.dv8tion.jda.api.requests.ErrorResponse#MESSAGE_BLOCKED_BY_HARMFUL_LINK_FILTER MESSAGE_BLOCKED_BY_HARMFUL_LINK_FILTER} + *
      If this message was blocked by the harmful link filter
    • *
    * * @param format @@ -130,6 +148,12 @@ default WebhookMessageCreateAction sendMessageFormat(@Nonnull String format, *
      *
    • {@link net.dv8tion.jda.api.requests.ErrorResponse#UNKNOWN_WEBHOOK UNKNOWN_WEBHOOK} *
      The webhook is no longer available, either it was deleted or in case of interactions it expired.
    • + * + *
    • {@link net.dv8tion.jda.api.requests.ErrorResponse#MESSAGE_BLOCKED_BY_AUTOMOD MESSAGE_BLOCKED_BY_AUTOMOD} + *
      If this message was blocked by an {@link net.dv8tion.jda.api.entities.automod.AutoModRule AutoModRule}
    • + * + *
    • {@link net.dv8tion.jda.api.requests.ErrorResponse#MESSAGE_BLOCKED_BY_HARMFUL_LINK_FILTER MESSAGE_BLOCKED_BY_HARMFUL_LINK_FILTER} + *
      If this message was blocked by the harmful link filter
    • *
    * *

    Example: Attachment Images @@ -171,6 +195,12 @@ default WebhookMessageCreateAction sendMessageFormat(@Nonnull String format, *

      *
    • {@link net.dv8tion.jda.api.requests.ErrorResponse#UNKNOWN_WEBHOOK UNKNOWN_WEBHOOK} *
      The webhook is no longer available, either it was deleted or in case of interactions it expired.
    • + * + *
    • {@link net.dv8tion.jda.api.requests.ErrorResponse#MESSAGE_BLOCKED_BY_AUTOMOD MESSAGE_BLOCKED_BY_AUTOMOD} + *
      If this message was blocked by an {@link net.dv8tion.jda.api.entities.automod.AutoModRule AutoModRule}
    • + * + *
    • {@link net.dv8tion.jda.api.requests.ErrorResponse#MESSAGE_BLOCKED_BY_HARMFUL_LINK_FILTER MESSAGE_BLOCKED_BY_HARMFUL_LINK_FILTER} + *
      If this message was blocked by the harmful link filter
    • *
    * *

    Example: Attachment Images @@ -222,6 +252,12 @@ default WebhookMessageCreateAction sendMessageEmbeds(@Nonnull MessageEmbed em *

      *
    • {@link net.dv8tion.jda.api.requests.ErrorResponse#UNKNOWN_WEBHOOK UNKNOWN_WEBHOOK} *
      The webhook is no longer available, either it was deleted or in case of interactions it expired.
    • + * + *
    • {@link net.dv8tion.jda.api.requests.ErrorResponse#MESSAGE_BLOCKED_BY_AUTOMOD MESSAGE_BLOCKED_BY_AUTOMOD} + *
      If this message was blocked by an {@link net.dv8tion.jda.api.entities.automod.AutoModRule AutoModRule}
    • + * + *
    • {@link net.dv8tion.jda.api.requests.ErrorResponse#MESSAGE_BLOCKED_BY_HARMFUL_LINK_FILTER MESSAGE_BLOCKED_BY_HARMFUL_LINK_FILTER} + *
      If this message was blocked by the harmful link filter
    • *
    * * @param components @@ -245,6 +281,12 @@ default WebhookMessageCreateAction sendMessageEmbeds(@Nonnull MessageEmbed em *
      *
    • {@link net.dv8tion.jda.api.requests.ErrorResponse#UNKNOWN_WEBHOOK UNKNOWN_WEBHOOK} *
      The webhook is no longer available, either it was deleted or in case of interactions it expired.
    • + * + *
    • {@link net.dv8tion.jda.api.requests.ErrorResponse#MESSAGE_BLOCKED_BY_AUTOMOD MESSAGE_BLOCKED_BY_AUTOMOD} + *
      If this message was blocked by an {@link net.dv8tion.jda.api.entities.automod.AutoModRule AutoModRule}
    • + * + *
    • {@link net.dv8tion.jda.api.requests.ErrorResponse#MESSAGE_BLOCKED_BY_HARMFUL_LINK_FILTER MESSAGE_BLOCKED_BY_HARMFUL_LINK_FILTER} + *
      If this message was blocked by the harmful link filter
    • *
    * * @param component @@ -297,6 +339,21 @@ default WebhookMessageCreateAction sendMessageComponents(@Nonnull LayoutCompo * .queue(); * }
    * + *

    Possible {@link net.dv8tion.jda.api.requests.ErrorResponse ErrorResponses} include: + *

      + *
    • {@link net.dv8tion.jda.api.requests.ErrorResponse#UNKNOWN_WEBHOOK UNKNOWN_WEBHOOK} + *
      The webhook is no longer available, either it was deleted or in case of interactions it expired.
    • + * + *
    • {@link net.dv8tion.jda.api.requests.ErrorResponse#MESSAGE_BLOCKED_BY_AUTOMOD MESSAGE_BLOCKED_BY_AUTOMOD} + *
      If this message was blocked by an {@link net.dv8tion.jda.api.entities.automod.AutoModRule AutoModRule}
    • + * + *
    • {@link net.dv8tion.jda.api.requests.ErrorResponse#MESSAGE_BLOCKED_BY_HARMFUL_LINK_FILTER MESSAGE_BLOCKED_BY_HARMFUL_LINK_FILTER} + *
      If this message was blocked by the harmful link filter
    • + * + *
    • {@link net.dv8tion.jda.api.requests.ErrorResponse#REQUEST_ENTITY_TOO_LARGE REQUEST_ENTITY_TOO_LARGE} + *
      If the total sum of uploaded bytes exceeds the guild's {@link Guild#getMaxFileSize() upload limit}
    • + *
    + * * @param files * The {@link FileUpload FileUploads} to attach to the message * @@ -339,6 +396,21 @@ default WebhookMessageCreateAction sendMessageComponents(@Nonnull LayoutCompo * .queue(); * } * + *

    Possible {@link net.dv8tion.jda.api.requests.ErrorResponse ErrorResponses} include: + *

      + *
    • {@link net.dv8tion.jda.api.requests.ErrorResponse#UNKNOWN_WEBHOOK UNKNOWN_WEBHOOK} + *
      The webhook is no longer available, either it was deleted or in case of interactions it expired.
    • + * + *
    • {@link net.dv8tion.jda.api.requests.ErrorResponse#MESSAGE_BLOCKED_BY_AUTOMOD MESSAGE_BLOCKED_BY_AUTOMOD} + *
      If this message was blocked by an {@link net.dv8tion.jda.api.entities.automod.AutoModRule AutoModRule}
    • + * + *
    • {@link net.dv8tion.jda.api.requests.ErrorResponse#MESSAGE_BLOCKED_BY_HARMFUL_LINK_FILTER MESSAGE_BLOCKED_BY_HARMFUL_LINK_FILTER} + *
      If this message was blocked by the harmful link filter
    • + * + *
    • {@link net.dv8tion.jda.api.requests.ErrorResponse#REQUEST_ENTITY_TOO_LARGE REQUEST_ENTITY_TOO_LARGE} + *
      If the total sum of uploaded bytes exceeds the guild's {@link Guild#getMaxFileSize() upload limit}
    • + *
    + * * @param files * The {@link FileUpload FileUploads} to attach to the message * diff --git a/src/main/java/net/dv8tion/jda/api/entities/channel/concrete/ForumChannel.java b/src/main/java/net/dv8tion/jda/api/entities/channel/concrete/ForumChannel.java index 9c849ba16f..3d151591e4 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/channel/concrete/ForumChannel.java +++ b/src/main/java/net/dv8tion/jda/api/entities/channel/concrete/ForumChannel.java @@ -227,8 +227,18 @@ default boolean isTagRequired() *
      *
    • {@link net.dv8tion.jda.api.requests.ErrorResponse#UNKNOWN_CHANNEL UNKNOWN_CHANNEL} *
      If the forum channel was deleted
    • + * + *
    • {@link net.dv8tion.jda.api.requests.ErrorResponse#MESSAGE_BLOCKED_BY_AUTOMOD MESSAGE_BLOCKED_BY_AUTOMOD} + *
      If this message was blocked by an {@link net.dv8tion.jda.api.entities.automod.AutoModRule AutoModRule}
    • + * + *
    • {@link net.dv8tion.jda.api.requests.ErrorResponse#MESSAGE_BLOCKED_BY_HARMFUL_LINK_FILTER MESSAGE_BLOCKED_BY_HARMFUL_LINK_FILTER} + *
      If this message was blocked by the harmful link filter
    • + * *
    • {@link net.dv8tion.jda.api.requests.ErrorResponse#REQUEST_ENTITY_TOO_LARGE REQUEST_ENTITY_TOO_LARGE} *
      If the total sum of uploaded bytes exceeds the guild's {@link Guild#getMaxFileSize() upload limit}
    • + * + *
    • {@link net.dv8tion.jda.api.requests.ErrorResponse#TITLE_BLOCKED_BY_AUTOMOD TITLE_BLOCKED_BY_AUTOMOD} + *
      If the forum post name was blocked by an {@link net.dv8tion.jda.api.entities.automod.AutoModRule AutoModRule}
    • *
    * * @param name diff --git a/src/main/java/net/dv8tion/jda/api/entities/channel/middleman/MessageChannel.java b/src/main/java/net/dv8tion/jda/api/entities/channel/middleman/MessageChannel.java index 1175733e3b..b91c2c7e5f 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/channel/middleman/MessageChannel.java +++ b/src/main/java/net/dv8tion/jda/api/entities/channel/middleman/MessageChannel.java @@ -302,6 +302,12 @@ default List> purgeMessagesById(@Nonnull long... message *
  • {@link net.dv8tion.jda.api.requests.ErrorResponse#CANNOT_SEND_TO_USER CANNOT_SEND_TO_USER} *
    If this is a {@link net.dv8tion.jda.api.entities.channel.concrete.PrivateChannel PrivateChannel} and the currently logged in account * does not share any Guilds with the recipient User
  • + * + *
  • {@link net.dv8tion.jda.api.requests.ErrorResponse#MESSAGE_BLOCKED_BY_AUTOMOD MESSAGE_BLOCKED_BY_AUTOMOD} + *
    If this message was blocked by an {@link net.dv8tion.jda.api.entities.automod.AutoModRule AutoModRule}
  • + * + *
  • {@link net.dv8tion.jda.api.requests.ErrorResponse#MESSAGE_BLOCKED_BY_HARMFUL_LINK_FILTER MESSAGE_BLOCKED_BY_HARMFUL_LINK_FILTER} + *
    If this message was blocked by the harmful link filter
  • * * * @param text @@ -336,6 +342,12 @@ default MessageCreateAction sendMessage(@Nonnull CharSequence text) *
  • {@link net.dv8tion.jda.api.requests.ErrorResponse#CANNOT_SEND_TO_USER CANNOT_SEND_TO_USER} *
    If this is a {@link net.dv8tion.jda.api.entities.channel.concrete.PrivateChannel PrivateChannel} and the currently logged in account * does not share any Guilds with the recipient User
  • + * + *
  • {@link net.dv8tion.jda.api.requests.ErrorResponse#MESSAGE_BLOCKED_BY_AUTOMOD MESSAGE_BLOCKED_BY_AUTOMOD} + *
    If this message was blocked by an {@link net.dv8tion.jda.api.entities.automod.AutoModRule AutoModRule}
  • + * + *
  • {@link net.dv8tion.jda.api.requests.ErrorResponse#MESSAGE_BLOCKED_BY_HARMFUL_LINK_FILTER MESSAGE_BLOCKED_BY_HARMFUL_LINK_FILTER} + *
    If this message was blocked by the harmful link filter
  • * * * @param msg @@ -372,6 +384,12 @@ default MessageCreateAction sendMessage(@Nonnull MessageCreateData msg) *
  • {@link net.dv8tion.jda.api.requests.ErrorResponse#CANNOT_SEND_TO_USER CANNOT_SEND_TO_USER} *
    If this is a {@link net.dv8tion.jda.api.entities.channel.concrete.PrivateChannel PrivateChannel} and the currently logged in account * does not share any Guilds with the recipient User
  • + * + *
  • {@link net.dv8tion.jda.api.requests.ErrorResponse#MESSAGE_BLOCKED_BY_AUTOMOD MESSAGE_BLOCKED_BY_AUTOMOD} + *
    If this message was blocked by an {@link net.dv8tion.jda.api.entities.automod.AutoModRule AutoModRule}
  • + * + *
  • {@link net.dv8tion.jda.api.requests.ErrorResponse#MESSAGE_BLOCKED_BY_HARMFUL_LINK_FILTER MESSAGE_BLOCKED_BY_HARMFUL_LINK_FILTER} + *
    If this message was blocked by the harmful link filter
  • * * * @param format @@ -415,6 +433,12 @@ default MessageCreateAction sendMessageFormat(@Nonnull String format, @Nonnull O *
  • {@link net.dv8tion.jda.api.requests.ErrorResponse#CANNOT_SEND_TO_USER CANNOT_SEND_TO_USER} *
    If this is a {@link net.dv8tion.jda.api.entities.channel.concrete.PrivateChannel PrivateChannel} and the currently logged in account * does not share any Guilds with the recipient User
  • + * + *
  • {@link net.dv8tion.jda.api.requests.ErrorResponse#MESSAGE_BLOCKED_BY_AUTOMOD MESSAGE_BLOCKED_BY_AUTOMOD} + *
    If this message was blocked by an {@link net.dv8tion.jda.api.entities.automod.AutoModRule AutoModRule}
  • + * + *
  • {@link net.dv8tion.jda.api.requests.ErrorResponse#MESSAGE_BLOCKED_BY_HARMFUL_LINK_FILTER MESSAGE_BLOCKED_BY_HARMFUL_LINK_FILTER} + *
    If this message was blocked by the harmful link filter
  • * * *

    Example: Attachment Images @@ -473,6 +497,12 @@ default MessageCreateAction sendMessageEmbeds(@Nonnull MessageEmbed embed, @Nonn *

  • {@link net.dv8tion.jda.api.requests.ErrorResponse#CANNOT_SEND_TO_USER CANNOT_SEND_TO_USER} *
    If this is a {@link PrivateChannel PrivateChannel} and the currently logged in account * does not share any Guilds with the recipient User
  • + * + *
  • {@link net.dv8tion.jda.api.requests.ErrorResponse#MESSAGE_BLOCKED_BY_AUTOMOD MESSAGE_BLOCKED_BY_AUTOMOD} + *
    If this message was blocked by an {@link net.dv8tion.jda.api.entities.automod.AutoModRule AutoModRule}
  • + * + *
  • {@link net.dv8tion.jda.api.requests.ErrorResponse#MESSAGE_BLOCKED_BY_HARMFUL_LINK_FILTER MESSAGE_BLOCKED_BY_HARMFUL_LINK_FILTER} + *
    If this message was blocked by the harmful link filter
  • * * *

    Example: Attachment Images @@ -524,6 +554,12 @@ default MessageCreateAction sendMessageEmbeds(@Nonnull Collection{@link net.dv8tion.jda.api.requests.ErrorResponse#CANNOT_SEND_TO_USER CANNOT_SEND_TO_USER} *
    If this is a {@link PrivateChannel} and the currently logged in account * does not share any Guilds with the recipient User + * + *

  • {@link net.dv8tion.jda.api.requests.ErrorResponse#MESSAGE_BLOCKED_BY_AUTOMOD MESSAGE_BLOCKED_BY_AUTOMOD} + *
    If this message was blocked by an {@link net.dv8tion.jda.api.entities.automod.AutoModRule AutoModRule}
  • + * + *
  • {@link net.dv8tion.jda.api.requests.ErrorResponse#MESSAGE_BLOCKED_BY_HARMFUL_LINK_FILTER MESSAGE_BLOCKED_BY_HARMFUL_LINK_FILTER} + *
    If this message was blocked by the harmful link filter
  • * * * @param component @@ -564,6 +600,12 @@ default MessageCreateAction sendMessageComponents(@Nonnull LayoutComponent compo *
  • {@link net.dv8tion.jda.api.requests.ErrorResponse#CANNOT_SEND_TO_USER CANNOT_SEND_TO_USER} *
    If this is a {@link PrivateChannel} and the currently logged in account * does not share any Guilds with the recipient User
  • + * + *
  • {@link net.dv8tion.jda.api.requests.ErrorResponse#MESSAGE_BLOCKED_BY_AUTOMOD MESSAGE_BLOCKED_BY_AUTOMOD} + *
    If this message was blocked by an {@link net.dv8tion.jda.api.entities.automod.AutoModRule AutoModRule}
  • + * + *
  • {@link net.dv8tion.jda.api.requests.ErrorResponse#MESSAGE_BLOCKED_BY_HARMFUL_LINK_FILTER MESSAGE_BLOCKED_BY_HARMFUL_LINK_FILTER} + *
    If this message was blocked by the harmful link filter
  • * * *

    Example: Attachment Images @@ -620,6 +662,15 @@ default MessageCreateAction sendMessageComponents(@Nonnull Collection{@link net.dv8tion.jda.api.requests.ErrorResponse#CANNOT_SEND_TO_USER CANNOT_SEND_TO_USER} *
    If this is a {@link net.dv8tion.jda.api.entities.channel.concrete.PrivateChannel PrivateChannel} and the currently logged in account * does not share any Guilds with the recipient User + * + *

  • {@link net.dv8tion.jda.api.requests.ErrorResponse#MESSAGE_BLOCKED_BY_AUTOMOD MESSAGE_BLOCKED_BY_AUTOMOD} + *
    If this message was blocked by an {@link net.dv8tion.jda.api.entities.automod.AutoModRule AutoModRule}
  • + * + *
  • {@link net.dv8tion.jda.api.requests.ErrorResponse#MESSAGE_BLOCKED_BY_HARMFUL_LINK_FILTER MESSAGE_BLOCKED_BY_HARMFUL_LINK_FILTER} + *
    If this message was blocked by the harmful link filter
  • + * + *
  • {@link net.dv8tion.jda.api.requests.ErrorResponse#REQUEST_ENTITY_TOO_LARGE REQUEST_ENTITY_TOO_LARGE} + *
    If the total sum of uploaded bytes exceeds the guild's {@link Guild#getMaxFileSize() upload limit}
  • * * *

    Example: Attachment Images @@ -680,6 +731,15 @@ default MessageCreateAction sendFiles(@Nonnull Collection *

  • {@link net.dv8tion.jda.api.requests.ErrorResponse#CANNOT_SEND_TO_USER CANNOT_SEND_TO_USER} *
    If this is a {@link PrivateChannel PrivateChannel} and the currently logged in account * does not share any Guilds with the recipient User
  • + * + *
  • {@link net.dv8tion.jda.api.requests.ErrorResponse#MESSAGE_BLOCKED_BY_AUTOMOD MESSAGE_BLOCKED_BY_AUTOMOD} + *
    If this message was blocked by an {@link net.dv8tion.jda.api.entities.automod.AutoModRule AutoModRule}
  • + * + *
  • {@link net.dv8tion.jda.api.requests.ErrorResponse#MESSAGE_BLOCKED_BY_HARMFUL_LINK_FILTER MESSAGE_BLOCKED_BY_HARMFUL_LINK_FILTER} + *
    If this message was blocked by the harmful link filter
  • + * + *
  • {@link net.dv8tion.jda.api.requests.ErrorResponse#REQUEST_ENTITY_TOO_LARGE REQUEST_ENTITY_TOO_LARGE} + *
    If the total sum of uploaded bytes exceeds the guild's {@link Guild#getMaxFileSize() upload limit}
  • * * *

    Example: Attachment Images diff --git a/src/main/java/net/dv8tion/jda/api/interactions/callbacks/IReplyCallback.java b/src/main/java/net/dv8tion/jda/api/interactions/callbacks/IReplyCallback.java index 8ea5e9ae31..2988de9137 100644 --- a/src/main/java/net/dv8tion/jda/api/interactions/callbacks/IReplyCallback.java +++ b/src/main/java/net/dv8tion/jda/api/interactions/callbacks/IReplyCallback.java @@ -16,6 +16,7 @@ package net.dv8tion.jda.api.interactions.callbacks; +import net.dv8tion.jda.api.entities.Guild; import net.dv8tion.jda.api.entities.Message; import net.dv8tion.jda.api.entities.MessageEmbed; import net.dv8tion.jda.api.interactions.InteractionHook; @@ -114,6 +115,18 @@ default ReplyCallbackAction deferReply(boolean ephemeral) *
    When the acknowledgement is sent after the interaction expired, you will receive {@link net.dv8tion.jda.api.requests.ErrorResponse#UNKNOWN_INTERACTION ErrorResponse.UNKNOWN_INTERACTION}. *

    If your handling can take longer than 3 seconds, due to various rate limits or other conditions, you should use {@link #deferReply()} instead. * + *

    Possible {@link net.dv8tion.jda.api.requests.ErrorResponse ErrorResponses} include: + *

      + *
    • {@link net.dv8tion.jda.api.requests.ErrorResponse#UNKNOWN_INTERACTION UNKNOWN_INTERACTION} + *
      If the interaction has already been acknowledged or timed out
    • + * + *
    • {@link net.dv8tion.jda.api.requests.ErrorResponse#MESSAGE_BLOCKED_BY_AUTOMOD MESSAGE_BLOCKED_BY_AUTOMOD} + *
      If this message was blocked by an {@link net.dv8tion.jda.api.entities.automod.AutoModRule AutoModRule}
    • + * + *
    • {@link net.dv8tion.jda.api.requests.ErrorResponse#MESSAGE_BLOCKED_BY_HARMFUL_LINK_FILTER MESSAGE_BLOCKED_BY_HARMFUL_LINK_FILTER} + *
      If this message was blocked by the harmful link filter
    • + *
    + * * @param message * The {@link MessageCreateData} to send * @@ -143,6 +156,18 @@ default ReplyCallbackAction reply(@Nonnull MessageCreateData message) *
    When the acknowledgement is sent after the interaction expired, you will receive {@link net.dv8tion.jda.api.requests.ErrorResponse#UNKNOWN_INTERACTION ErrorResponse.UNKNOWN_INTERACTION}. *

    If your handling can take longer than 3 seconds, due to various rate limits or other conditions, you should use {@link #deferReply()} instead. * + *

    Possible {@link net.dv8tion.jda.api.requests.ErrorResponse ErrorResponses} include: + *

      + *
    • {@link net.dv8tion.jda.api.requests.ErrorResponse#UNKNOWN_INTERACTION UNKNOWN_INTERACTION} + *
      If the interaction has already been acknowledged or timed out
    • + * + *
    • {@link net.dv8tion.jda.api.requests.ErrorResponse#MESSAGE_BLOCKED_BY_AUTOMOD MESSAGE_BLOCKED_BY_AUTOMOD} + *
      If this message was blocked by an {@link net.dv8tion.jda.api.entities.automod.AutoModRule AutoModRule}
    • + * + *
    • {@link net.dv8tion.jda.api.requests.ErrorResponse#MESSAGE_BLOCKED_BY_HARMFUL_LINK_FILTER MESSAGE_BLOCKED_BY_HARMFUL_LINK_FILTER} + *
      If this message was blocked by the harmful link filter
    • + *
    + * * @param content * The message content to send * @@ -169,6 +194,18 @@ default ReplyCallbackAction reply(@Nonnull String content) *
    When the acknowledgement is sent after the interaction expired, you will receive {@link net.dv8tion.jda.api.requests.ErrorResponse#UNKNOWN_INTERACTION ErrorResponse.UNKNOWN_INTERACTION}. *

    If your handling can take longer than 3 seconds, due to various rate limits or other conditions, you should use {@link #deferReply()} instead. * + *

    Possible {@link net.dv8tion.jda.api.requests.ErrorResponse ErrorResponses} include: + *

      + *
    • {@link net.dv8tion.jda.api.requests.ErrorResponse#UNKNOWN_INTERACTION UNKNOWN_INTERACTION} + *
      If the interaction has already been acknowledged or timed out
    • + * + *
    • {@link net.dv8tion.jda.api.requests.ErrorResponse#MESSAGE_BLOCKED_BY_AUTOMOD MESSAGE_BLOCKED_BY_AUTOMOD} + *
      If this message was blocked by an {@link net.dv8tion.jda.api.entities.automod.AutoModRule AutoModRule}
    • + * + *
    • {@link net.dv8tion.jda.api.requests.ErrorResponse#MESSAGE_BLOCKED_BY_HARMFUL_LINK_FILTER MESSAGE_BLOCKED_BY_HARMFUL_LINK_FILTER} + *
      If this message was blocked by the harmful link filter
    • + *
    + * * @param embeds * The {@link MessageEmbed MessageEmbeds} to send * @@ -194,6 +231,18 @@ default ReplyCallbackAction replyEmbeds(@Nonnull CollectionWhen the acknowledgement is sent after the interaction expired, you will receive {@link net.dv8tion.jda.api.requests.ErrorResponse#UNKNOWN_INTERACTION ErrorResponse.UNKNOWN_INTERACTION}. *

    If your handling can take longer than 3 seconds, due to various rate limits or other conditions, you should use {@link #deferReply()} instead. * + *

    Possible {@link net.dv8tion.jda.api.requests.ErrorResponse ErrorResponses} include: + *

      + *
    • {@link net.dv8tion.jda.api.requests.ErrorResponse#UNKNOWN_INTERACTION UNKNOWN_INTERACTION} + *
      If the interaction has already been acknowledged or timed out
    • + * + *
    • {@link net.dv8tion.jda.api.requests.ErrorResponse#MESSAGE_BLOCKED_BY_AUTOMOD MESSAGE_BLOCKED_BY_AUTOMOD} + *
      If this message was blocked by an {@link net.dv8tion.jda.api.entities.automod.AutoModRule AutoModRule}
    • + * + *
    • {@link net.dv8tion.jda.api.requests.ErrorResponse#MESSAGE_BLOCKED_BY_HARMFUL_LINK_FILTER MESSAGE_BLOCKED_BY_HARMFUL_LINK_FILTER} + *
      If this message was blocked by the harmful link filter
    • + *
    + * * @param embed * The message embed to send * @param embeds @@ -223,6 +272,18 @@ default ReplyCallbackAction replyEmbeds(@Nonnull MessageEmbed embed, @Nonnull Me *
    When the acknowledgement is sent after the interaction expired, you will receive {@link net.dv8tion.jda.api.requests.ErrorResponse#UNKNOWN_INTERACTION ErrorResponse.UNKNOWN_INTERACTION}. *

    If your handling can take longer than 3 seconds, due to various rate limits or other conditions, you should use {@link #deferReply()} instead. * + *

    Possible {@link net.dv8tion.jda.api.requests.ErrorResponse ErrorResponses} include: + *

      + *
    • {@link net.dv8tion.jda.api.requests.ErrorResponse#UNKNOWN_INTERACTION UNKNOWN_INTERACTION} + *
      If the interaction has already been acknowledged or timed out
    • + * + *
    • {@link net.dv8tion.jda.api.requests.ErrorResponse#MESSAGE_BLOCKED_BY_AUTOMOD MESSAGE_BLOCKED_BY_AUTOMOD} + *
      If this message was blocked by an {@link net.dv8tion.jda.api.entities.automod.AutoModRule AutoModRule}
    • + * + *
    • {@link net.dv8tion.jda.api.requests.ErrorResponse#MESSAGE_BLOCKED_BY_HARMFUL_LINK_FILTER MESSAGE_BLOCKED_BY_HARMFUL_LINK_FILTER} + *
      If this message was blocked by the harmful link filter
    • + *
    + * * @param components * The {@link LayoutComponent LayoutComponents} to send, such as {@link ActionRow} * @@ -248,6 +309,18 @@ default ReplyCallbackAction replyComponents(@Nonnull CollectionWhen the acknowledgement is sent after the interaction expired, you will receive {@link net.dv8tion.jda.api.requests.ErrorResponse#UNKNOWN_INTERACTION ErrorResponse.UNKNOWN_INTERACTION}. *

    If your handling can take longer than 3 seconds, due to various rate limits or other conditions, you should use {@link #deferReply()} instead. * + *

    Possible {@link net.dv8tion.jda.api.requests.ErrorResponse ErrorResponses} include: + *

      + *
    • {@link net.dv8tion.jda.api.requests.ErrorResponse#UNKNOWN_INTERACTION UNKNOWN_INTERACTION} + *
      If the interaction has already been acknowledged or timed out
    • + * + *
    • {@link net.dv8tion.jda.api.requests.ErrorResponse#MESSAGE_BLOCKED_BY_AUTOMOD MESSAGE_BLOCKED_BY_AUTOMOD} + *
      If this message was blocked by an {@link net.dv8tion.jda.api.entities.automod.AutoModRule AutoModRule}
    • + * + *
    • {@link net.dv8tion.jda.api.requests.ErrorResponse#MESSAGE_BLOCKED_BY_HARMFUL_LINK_FILTER MESSAGE_BLOCKED_BY_HARMFUL_LINK_FILTER} + *
      If this message was blocked by the harmful link filter
    • + *
    + * * @param component * The {@link LayoutComponent} to send * @param other @@ -280,6 +353,18 @@ default ReplyCallbackAction replyComponents(@Nonnull LayoutComponent component, *
    When the acknowledgement is sent after the interaction expired, you will receive {@link net.dv8tion.jda.api.requests.ErrorResponse#UNKNOWN_INTERACTION ErrorResponse.UNKNOWN_INTERACTION}. *

    If your handling can take longer than 3 seconds, due to various rate limits or other conditions, you should use {@link #deferReply()} instead. * + *

    Possible {@link net.dv8tion.jda.api.requests.ErrorResponse ErrorResponses} include: + *

      + *
    • {@link net.dv8tion.jda.api.requests.ErrorResponse#UNKNOWN_INTERACTION UNKNOWN_INTERACTION} + *
      If the interaction has already been acknowledged or timed out
    • + * + *
    • {@link net.dv8tion.jda.api.requests.ErrorResponse#MESSAGE_BLOCKED_BY_AUTOMOD MESSAGE_BLOCKED_BY_AUTOMOD} + *
      If this message was blocked by an {@link net.dv8tion.jda.api.entities.automod.AutoModRule AutoModRule}
    • + * + *
    • {@link net.dv8tion.jda.api.requests.ErrorResponse#MESSAGE_BLOCKED_BY_HARMFUL_LINK_FILTER MESSAGE_BLOCKED_BY_HARMFUL_LINK_FILTER} + *
      If this message was blocked by the harmful link filter
    • + *
    + * * @param format * Format string for the message content * @param args @@ -313,6 +398,21 @@ default ReplyCallbackAction replyFormat(@Nonnull String format, @Nonnull Object. * For instance, if an exception occurs after using {@link FileUpload#fromData(File)}, before calling {@link RestAction#queue()}. * You can safely use a try-with-resources to handle this, since {@link FileUpload#close()} becomes ineffective once the request is handed off. * + *

    Possible {@link net.dv8tion.jda.api.requests.ErrorResponse ErrorResponses} include: + *

      + *
    • {@link net.dv8tion.jda.api.requests.ErrorResponse#UNKNOWN_INTERACTION UNKNOWN_INTERACTION} + *
      If the interaction has already been acknowledged or timed out
    • + * + *
    • {@link net.dv8tion.jda.api.requests.ErrorResponse#MESSAGE_BLOCKED_BY_AUTOMOD MESSAGE_BLOCKED_BY_AUTOMOD} + *
      If this message was blocked by an {@link net.dv8tion.jda.api.entities.automod.AutoModRule AutoModRule}
    • + * + *
    • {@link net.dv8tion.jda.api.requests.ErrorResponse#MESSAGE_BLOCKED_BY_HARMFUL_LINK_FILTER MESSAGE_BLOCKED_BY_HARMFUL_LINK_FILTER} + *
      If this message was blocked by the harmful link filter
    • + * + *
    • {@link net.dv8tion.jda.api.requests.ErrorResponse#REQUEST_ENTITY_TOO_LARGE REQUEST_ENTITY_TOO_LARGE} + *
      If the total sum of uploaded bytes exceeds the guild's {@link Guild#getMaxFileSize() upload limit}
    • + *
    + * * @param files * The {@link FileUpload FileUploads} to attach to the message * @@ -346,6 +446,21 @@ default ReplyCallbackAction replyFiles(@Nonnull Collection * For instance, if an exception occurs after using {@link FileUpload#fromData(File)}, before calling {@link RestAction#queue()}. * You can safely use a try-with-resources to handle this, since {@link FileUpload#close()} becomes ineffective once the request is handed off. * + *

    Possible {@link net.dv8tion.jda.api.requests.ErrorResponse ErrorResponses} include: + *

      + *
    • {@link net.dv8tion.jda.api.requests.ErrorResponse#UNKNOWN_INTERACTION UNKNOWN_INTERACTION} + *
      If the interaction has already been acknowledged or timed out
    • + * + *
    • {@link net.dv8tion.jda.api.requests.ErrorResponse#MESSAGE_BLOCKED_BY_AUTOMOD MESSAGE_BLOCKED_BY_AUTOMOD} + *
      If this message was blocked by an {@link net.dv8tion.jda.api.entities.automod.AutoModRule AutoModRule}
    • + * + *
    • {@link net.dv8tion.jda.api.requests.ErrorResponse#MESSAGE_BLOCKED_BY_HARMFUL_LINK_FILTER MESSAGE_BLOCKED_BY_HARMFUL_LINK_FILTER} + *
      If this message was blocked by the harmful link filter
    • + * + *
    • {@link net.dv8tion.jda.api.requests.ErrorResponse#REQUEST_ENTITY_TOO_LARGE REQUEST_ENTITY_TOO_LARGE} + *
      If the total sum of uploaded bytes exceeds the guild's {@link Guild#getMaxFileSize() upload limit}
    • + *
    + * * @param files * The {@link FileUpload FileUploads} to attach to the message * diff --git a/src/main/java/net/dv8tion/jda/api/requests/ErrorResponse.java b/src/main/java/net/dv8tion/jda/api/requests/ErrorResponse.java index e39190b742..e8dc6b264e 100644 --- a/src/main/java/net/dv8tion/jda/api/requests/ErrorResponse.java +++ b/src/main/java/net/dv8tion/jda/api/requests/ErrorResponse.java @@ -182,6 +182,10 @@ public enum ErrorResponse STICKER_FPS_TOO_SMALL_OR_TOO_LARGE( 170006, "Sticker frame rate is either too small or too large"), MAX_STICKER_ANIMATION_DURATION( 170007, "Sticker animation duration exceeds maximum of 5 seconds"), + MESSAGE_BLOCKED_BY_AUTOMOD( 200000, "Message was blocked by automatic moderation"), + TITLE_BLOCKED_BY_AUTOMOD( 200001, "Title was blocked by automatic moderation"), + MESSAGE_BLOCKED_BY_HARMFUL_LINK_FILTER( 240000, "Message blocked by harmful links filter"), + SERVER_ERROR( 0, "Discord encountered an internal server error! Not good!"); From d8f85af5b8e186fe3d9816160b1613f625710f31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Spie=C3=9F?= Date: Sun, 2 Apr 2023 15:49:27 +0200 Subject: [PATCH 33/39] Add remaining docs --- .../net/dv8tion/jda/api/entities/Guild.java | 77 +++++++++++++++++++ .../jda/api/requests/ErrorResponse.java | 1 - .../jda/internal/entities/GuildImpl.java | 2 + 3 files changed, 79 insertions(+), 1 deletion(-) diff --git a/src/main/java/net/dv8tion/jda/api/entities/Guild.java b/src/main/java/net/dv8tion/jda/api/entities/Guild.java index d4dc257013..d9cc9e8d89 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/Guild.java +++ b/src/main/java/net/dv8tion/jda/api/entities/Guild.java @@ -21,7 +21,9 @@ import net.dv8tion.jda.api.JDA; import net.dv8tion.jda.api.Permission; import net.dv8tion.jda.api.Region; +import net.dv8tion.jda.api.entities.automod.AutoModResponse; import net.dv8tion.jda.api.entities.automod.AutoModRule; +import net.dv8tion.jda.api.entities.automod.AutoModTriggerType; import net.dv8tion.jda.api.entities.automod.build.AutoModRuleData; import net.dv8tion.jda.api.entities.channel.Channel; import net.dv8tion.jda.api.entities.channel.attribute.ICopyableChannel; @@ -404,14 +406,46 @@ default RestAction> retrieveRegions() @CheckReturnValue RestAction> retrieveRegions(boolean includeDeprecated); + /** + * Retrieves all current {@link AutoModRule AutoModRules} for this guild. + * + * @throws InsufficientPermissionException + * If the currently logged in account does not have the {@link net.dv8tion.jda.api.Permission#MANAGE_SERVER MANAGE_SERVER} permission + * + * @return {@link RestAction} - Type: {@link List} of {@link AutoModRule} + */ @Nonnull @CheckReturnValue RestAction> retrieveAutoModRules(); + /** + * Retrieves the {@link AutoModRule} for the provided id. + * + * @param id + * The id of the rule + * + * @throws IllegalArgumentException + * If the provided id is not a valid snowflake + * @throws InsufficientPermissionException + * If the currently logged in account does not have the {@link net.dv8tion.jda.api.Permission#MANAGE_SERVER MANAGE_SERVER} permission + * + * @return {@link RestAction} - Type: {@link AutoModRule} + */ @Nonnull @CheckReturnValue RestAction retrieveAutoModRuleById(@Nonnull String id); + /** + * Retrieves the {@link AutoModRule} for the provided id. + * + * @param id + * The id of the rule + * + * @throws InsufficientPermissionException + * If the currently logged in account does not have the {@link net.dv8tion.jda.api.Permission#MANAGE_SERVER MANAGE_SERVER} permission + * + * @return {@link RestAction} - Type: {@link AutoModRule} + */ @Nonnull @CheckReturnValue default RestAction retrieveAutoModRuleById(long id) @@ -419,6 +453,25 @@ default RestAction retrieveAutoModRuleById(long id) return retrieveAutoModRuleById(Long.toUnsignedString(id)); } + /** + * Creates a new {@link AutoModRule} for this guild. + * + *

    You can only create a certain number of rules for each {@link AutoModTriggerType AutoModTriggerType}. + * The maximum is provided by {@link AutoModTriggerType#getMaxPerGuild()}. + * + * @param data + * The data for the new rule + * + * @throws InsufficientPermissionException + * If the currently logged in account does not have the {@link AutoModRuleData#getRequiredPermissions() required permissions} + * @throws IllegalStateException + *

      + *
    • If the provided data does not have any {@link AutoModResponse} configured
    • + *
    • If any of the configured {@link AutoModResponse AutoModResponses} is not supported by the {@link AutoModTriggerType}
    • + *
    + * + * @return {@link AuditableRestAction} - Type: {@link AutoModRule} + */ @Nonnull @CheckReturnValue AuditableRestAction createAutoModRule(@Nonnull AutoModRuleData data); @@ -454,10 +507,34 @@ default AutoModRuleManager modifyAutoModRuleById(long id) return modifyAutoModRuleById(Long.toUnsignedString(id)); } + /** + * Deletes the {@link AutoModRule} for the provided id. + * + * @param id + * The id of the rule + * + * @throws IllegalArgumentException + * If the provided id is not a valid snowflake + * @throws InsufficientPermissionException + * If the currently logged in account does not have the {@link net.dv8tion.jda.api.Permission#MANAGE_SERVER MANAGE_SERVER} permission + * + * @return {@link AuditableRestAction} - Type: {@link Void} + */ @Nonnull @CheckReturnValue AuditableRestAction deleteAutoModRuleById(@Nonnull String id); + /** + * Deletes the {@link AutoModRule} for the provided id. + * + * @param id + * The id of the rule + * + * @throws InsufficientPermissionException + * If the currently logged in account does not have the {@link net.dv8tion.jda.api.Permission#MANAGE_SERVER MANAGE_SERVER} permission + * + * @return {@link AuditableRestAction} - Type: {@link Void} + */ @Nonnull @CheckReturnValue default AuditableRestAction deleteAutoModRuleById(long id) diff --git a/src/main/java/net/dv8tion/jda/api/requests/ErrorResponse.java b/src/main/java/net/dv8tion/jda/api/requests/ErrorResponse.java index e8dc6b264e..f59c3a5c65 100644 --- a/src/main/java/net/dv8tion/jda/api/requests/ErrorResponse.java +++ b/src/main/java/net/dv8tion/jda/api/requests/ErrorResponse.java @@ -181,7 +181,6 @@ public enum ErrorResponse MAX_LOTTIE_ANIMATION_DIMENSION( 170005, "Lottie animation maximum dimensions exceeded"), STICKER_FPS_TOO_SMALL_OR_TOO_LARGE( 170006, "Sticker frame rate is either too small or too large"), MAX_STICKER_ANIMATION_DURATION( 170007, "Sticker animation duration exceeds maximum of 5 seconds"), - MESSAGE_BLOCKED_BY_AUTOMOD( 200000, "Message was blocked by automatic moderation"), TITLE_BLOCKED_BY_AUTOMOD( 200001, "Title was blocked by automatic moderation"), MESSAGE_BLOCKED_BY_HARMFUL_LINK_FILTER( 240000, "Message blocked by harmful links filter"), diff --git a/src/main/java/net/dv8tion/jda/internal/entities/GuildImpl.java b/src/main/java/net/dv8tion/jda/internal/entities/GuildImpl.java index aa14fd5c9a..04e4599333 100644 --- a/src/main/java/net/dv8tion/jda/internal/entities/GuildImpl.java +++ b/src/main/java/net/dv8tion/jda/internal/entities/GuildImpl.java @@ -359,6 +359,7 @@ public RestAction> retrieveRegions(boolean includeDeprecated) @Override public RestAction> retrieveAutoModRules() { + checkPermission(Permission.MANAGE_SERVER); Route.CompiledRoute route = Route.AutoModeration.LIST_RULES.compile(getId()); return new RestActionImpl<>(api, route, (response, request) -> { @@ -385,6 +386,7 @@ public RestAction> retrieveAutoModRules() public RestAction retrieveAutoModRuleById(@Nonnull String id) { Checks.isSnowflake(id); + checkPermission(Permission.MANAGE_SERVER); Route.CompiledRoute route = Route.AutoModeration.GET_RULE.compile(getId(), id); return new RestActionImpl<>(api, route, (response, request) -> AutoModRuleImpl.fromData(this, response.getObject())); } From fb335d19f7d1bb9d0b169d476181359a5b11e76c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Spie=C3=9F?= Date: Sun, 2 Apr 2023 15:51:37 +0200 Subject: [PATCH 34/39] Rename action type --- src/main/java/net/dv8tion/jda/api/audit/ActionType.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/net/dv8tion/jda/api/audit/ActionType.java b/src/main/java/net/dv8tion/jda/api/audit/ActionType.java index 2a08999fa1..801f5e528f 100644 --- a/src/main/java/net/dv8tion/jda/api/audit/ActionType.java +++ b/src/main/java/net/dv8tion/jda/api/audit/ActionType.java @@ -611,7 +611,7 @@ public enum ActionType *
  • {@link AuditLogKey#CHANNEL_ID CHANNEL_ID}
  • * */ - AUTO_MODERATION_RULE_BLOCK_MESSAGE( 143, TargetType.MEMBER), + AUTO_MODERATION_RULE_BLOCK_MESSAGE(143, TargetType.MEMBER), /** * An automod rule sent an alert to a channel @@ -622,7 +622,7 @@ public enum ActionType *
  • {@link AuditLogKey#AUTO_MODERATION_RULE_TRIGGER_TYPE AUTO_MODERATION_RULE_TRIGGER_TYPE}
  • * */ - AUTO_MODERATION_FLAG_TO_CHANNEL( 144, TargetType.UNKNOWN), + AUTO_MODERATION_FLAG_TO_CHANNEL( 144, TargetType.UNKNOWN), /** * An automod rule put a user in {@link Member#isTimedOut() timeout} @@ -633,7 +633,7 @@ public enum ActionType *
  • {@link AuditLogKey#AUTO_MODERATION_RULE_TRIGGER_TYPE AUTO_MODERATION_RULE_TRIGGER_TYPE}
  • * */ - AUTO_MODERATION_USER_COMMUNICATION_DISABLED(145, TargetType.UNKNOWN), + AUTO_MODERATION_MEMBER_TIMEOUT( 145, TargetType.UNKNOWN), UNKNOWN(-1, TargetType.UNKNOWN); From 6ca4831fe02329025784b1715fd221cb5314d60c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Spie=C3=9F?= Date: Sun, 2 Apr 2023 15:58:21 +0200 Subject: [PATCH 35/39] Update TargetType --- src/main/java/net/dv8tion/jda/api/audit/ActionType.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/net/dv8tion/jda/api/audit/ActionType.java b/src/main/java/net/dv8tion/jda/api/audit/ActionType.java index 801f5e528f..32efb8933e 100644 --- a/src/main/java/net/dv8tion/jda/api/audit/ActionType.java +++ b/src/main/java/net/dv8tion/jda/api/audit/ActionType.java @@ -622,7 +622,7 @@ public enum ActionType *
  • {@link AuditLogKey#AUTO_MODERATION_RULE_TRIGGER_TYPE AUTO_MODERATION_RULE_TRIGGER_TYPE}
  • * */ - AUTO_MODERATION_FLAG_TO_CHANNEL( 144, TargetType.UNKNOWN), + AUTO_MODERATION_FLAG_TO_CHANNEL( 144, TargetType.MEMBER), /** * An automod rule put a user in {@link Member#isTimedOut() timeout} @@ -633,7 +633,7 @@ public enum ActionType *
  • {@link AuditLogKey#AUTO_MODERATION_RULE_TRIGGER_TYPE AUTO_MODERATION_RULE_TRIGGER_TYPE}
  • * */ - AUTO_MODERATION_MEMBER_TIMEOUT( 145, TargetType.UNKNOWN), + AUTO_MODERATION_MEMBER_TIMEOUT( 145, TargetType.MEMBER), UNKNOWN(-1, TargetType.UNKNOWN); From 6b17e4ce38e41875517010ed1698c8cc5b6069b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Spie=C3=9F?= Date: Fri, 5 May 2023 14:21:32 +0200 Subject: [PATCH 36/39] Add support for member profile automod --- .../entities/automod/AutoModEventType.java | 5 +++ .../api/entities/automod/AutoModResponse.java | 21 ++++++++-- .../entities/automod/AutoModTriggerType.java | 12 ++++-- .../automod/build/AutoModRuleData.java | 40 +++++++++++++++++-- .../entities/automod/AutoModResponseImpl.java | 8 ++++ 5 files changed, 75 insertions(+), 11 deletions(-) diff --git a/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModEventType.java b/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModEventType.java index 173d839d8b..c630747001 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModEventType.java +++ b/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModEventType.java @@ -34,6 +34,11 @@ public enum AutoModEventType */ MESSAGE_SEND(1), + /** + * The rule is triggered when a member updates their profile. + */ + MEMBER_UPDATE(2), + /** * Placeholder for unknown types which haven't been added yet. */ diff --git a/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModResponse.java b/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModResponse.java index edcbf4f25e..b8a8a77521 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModResponse.java +++ b/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModResponse.java @@ -138,6 +138,17 @@ static AutoModResponse timeoutMember(@Nonnull Duration duration) return new AutoModResponseImpl(Type.TIMEOUT, duration); } + /** + * Create a response that will prevent the member from interacting with anything in the guild until the offending content is removed. + * + * @return The response instance + */ + @Nonnull + static AutoModResponse blockMemberInteraction() + { + return new AutoModResponseImpl(Type.BLOCK_MEMBER_INTERACTION); + } + /** * The type of response. */ @@ -146,21 +157,25 @@ enum Type /** * Blocks the message from being sent. */ - BLOCK_MESSAGE(1), + BLOCK_MESSAGE(1, EnumSet.of(AutoModTriggerType.KEYWORD, AutoModTriggerType.KEYWORD_PRESET, AutoModTriggerType.SPAM, AutoModTriggerType.MENTION_SPAM)), /** * Sends an alert message to the specified channel. */ - SEND_ALERT_MESSAGE(2), + SEND_ALERT_MESSAGE(2, EnumSet.of(AutoModTriggerType.KEYWORD, AutoModTriggerType.KEYWORD_PRESET, AutoModTriggerType.SPAM, AutoModTriggerType.MENTION_SPAM)), /** * Times out the user for the specified duration. * *

    To create a rule with this response, the creator must also have the {@link net.dv8tion.jda.api.Permission#MODERATE_MEMBERS MODERATE_MEMBERS} permission. */ TIMEOUT(3, EnumSet.of(AutoModTriggerType.KEYWORD, AutoModTriggerType.MENTION_SPAM)), + /** + * Blocks the member from interacting with the guild until they update the offending content. + */ + BLOCK_MEMBER_INTERACTION(4, EnumSet.of(AutoModTriggerType.MEMBER_PROFILE_KEYWORD)), /** * Placeholder for unknown types. */ - UNKNOWN(-1) + UNKNOWN(-1, EnumSet.noneOf(AutoModTriggerType.class)) ; private final int key; diff --git a/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModTriggerType.java b/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModTriggerType.java index ccc932582e..d030648515 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModTriggerType.java +++ b/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModTriggerType.java @@ -24,21 +24,25 @@ public enum AutoModTriggerType { /** - * The rule is triggered by user content containing specific keywords or phrases. + * The rule is triggered by user message content containing specific keywords or phrases. */ KEYWORD(1, 6), /** - * The rule is triggered by user content containing classified spam content. + * The rule is triggered by user message content containing classified spam content. */ SPAM(3, 1), /** - * The rule is triggered by user content containing keywords from a predefined list (such as {@link AutoModRule.KeywordPreset#SLURS slurs}). + * The rule is triggered by user message content containing keywords from a predefined list (such as {@link AutoModRule.KeywordPreset#SLURS slurs}). */ KEYWORD_PRESET(4, 1), /** - * The rule is triggered by user content containing more than the allowed number of mentions. + * The rule is triggered by user message content containing more than the allowed number of mentions. */ MENTION_SPAM(5, 1), + /** + * The rule is triggered by a member profile containing specific keywords or phrases. + */ + MEMBER_PROFILE_KEYWORD(6, 1), /** * Placeholder for unknown trigger types that haven't been added yet. */ diff --git a/src/main/java/net/dv8tion/jda/api/entities/automod/build/AutoModRuleData.java b/src/main/java/net/dv8tion/jda/api/entities/automod/build/AutoModRuleData.java index 33461ff153..1be696e8fd 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/automod/build/AutoModRuleData.java +++ b/src/main/java/net/dv8tion/jda/api/entities/automod/build/AutoModRuleData.java @@ -28,7 +28,6 @@ import net.dv8tion.jda.api.utils.data.SerializableData; import net.dv8tion.jda.internal.utils.Checks; -import javax.annotation.CheckReturnValue; import javax.annotation.Nonnull; import java.util.ArrayList; import java.util.Collection; @@ -73,8 +72,8 @@ public class AutoModRuleData implements SerializableData protected AutoModRuleData(AutoModEventType eventType, String name, TriggerConfig triggerMetadata) { this.eventType = eventType; - this.name = name; - this.triggerMetadata = triggerMetadata; + this.setName(name); + this.setTriggerConfig(triggerMetadata); } /** @@ -96,6 +95,30 @@ public static AutoModRuleData onMessage(@Nonnull String name, @Nonnull TriggerCo return new AutoModRuleData(AutoModEventType.MESSAGE_SEND, name, triggerConfig); } + + /** + * Create a new {@link AutoModRule} which triggers on a member profile being updated. + * + * @param name + * The name of the rule (1-{@value AutoModRule#MAX_RULE_NAME_LENGTH} characters) + * @param triggerConfig + * The trigger configuration for this rule + * + * @throws IllegalArgumentException + * If null is provided or the name is not between 1 and {@value AutoModRule#MAX_RULE_NAME_LENGTH} characters + * + * @return The new {@link AutoModRuleData} instance + */ + @Nonnull + public static AutoModRuleData onMemberProfile(@Nonnull String name, @Nonnull TriggerConfig triggerConfig) + { + AutoModTriggerType type = triggerConfig.getType(); + if (type != AutoModTriggerType.KEYWORD && type != AutoModTriggerType.MEMBER_PROFILE_KEYWORD) + throw new IllegalArgumentException("Invalid trigger type for member profile: " + type); + return new AutoModRuleData(AutoModEventType.MEMBER_UPDATE, name, triggerConfig) + .putResponses(AutoModResponse.blockMemberInteraction()); + } + /** * Change the name of the rule. * @@ -207,6 +230,8 @@ public AutoModRuleData setResponses(@Nonnull Collection getRequiredPermissions() public DataObject toData() { AutoModTriggerType triggerType = triggerMetadata.getType(); + if (eventType == AutoModEventType.MEMBER_UPDATE) + { + if (triggerType == AutoModTriggerType.KEYWORD) + triggerType = AutoModTriggerType.MEMBER_PROFILE_KEYWORD; + else + throw new IllegalStateException("Cannot create rule of trigger type " + triggerType + " with event type " + eventType); + } + for (AutoModResponse response : actions.values()) { if (!response.getType().isSupportedTrigger(triggerType)) diff --git a/src/main/java/net/dv8tion/jda/internal/entities/automod/AutoModResponseImpl.java b/src/main/java/net/dv8tion/jda/internal/entities/automod/AutoModResponseImpl.java index e92b4d75c2..f15fd97c4d 100644 --- a/src/main/java/net/dv8tion/jda/internal/entities/automod/AutoModResponseImpl.java +++ b/src/main/java/net/dv8tion/jda/internal/entities/automod/AutoModResponseImpl.java @@ -32,6 +32,14 @@ public class AutoModResponseImpl implements AutoModResponse private final String customMessage; private final long timeoutDuration; + public AutoModResponseImpl(Type type) + { + this.type = type; + this.channel = null; + this.customMessage = null; + this.timeoutDuration = 0; + } + public AutoModResponseImpl(Type type, GuildMessageChannel channel) { this.type = type; From 044c648556aa54a81d1464c9cc13dfdeaa1b0233 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Spie=C3=9F?= Date: Fri, 5 May 2023 21:20:27 +0200 Subject: [PATCH 37/39] Add mention raid protection --- .../jda/api/entities/automod/AutoModRule.java | 8 ++++++++ .../automod/build/MentionSpamTriggerConfig.java | 17 +++++++++++++++++ .../entities/automod/AutoModRuleImpl.java | 14 ++++++++++++++ 3 files changed, 39 insertions(+) diff --git a/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModRule.java b/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModRule.java index cf59c0ba95..952ee53142 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModRule.java +++ b/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModRule.java @@ -206,6 +206,14 @@ default String getCreatorId() */ int getMentionLimit(); + /** + * Whether this rule is using the raid protection feature. + *

    Only applies to {@link AutoModTriggerType#MENTION_SPAM}. + * + * @return True, if mention raid protection is enabled + */ + boolean isMentionRaidProtectionEnabled(); + /** * Returns an {@link AutoModRuleManager}, which can be used to modify this rule. *

    The manager allows modifying multiple fields in a single request. diff --git a/src/main/java/net/dv8tion/jda/api/entities/automod/build/MentionSpamTriggerConfig.java b/src/main/java/net/dv8tion/jda/api/entities/automod/build/MentionSpamTriggerConfig.java index 9a9c11a439..ff91534d1c 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/automod/build/MentionSpamTriggerConfig.java +++ b/src/main/java/net/dv8tion/jda/api/entities/automod/build/MentionSpamTriggerConfig.java @@ -29,6 +29,7 @@ public class MentionSpamTriggerConfig extends AbstractTriggerConfig implements TriggerConfig { private int mentionLimit; + private boolean isMentionRaidProtectionEnabled; public MentionSpamTriggerConfig(int mentionLimit) { @@ -56,12 +57,28 @@ public MentionSpamTriggerConfig setMentionLimit(int mentionLimit) return this; } + /** + * Whether to enable mention raid protection. + * + * @param enabled + * True, if mention raid protection should be enabled + * + * @return The current config for chaining convenience + */ + @Nonnull + public MentionSpamTriggerConfig setMentionRaidProtectionEnabled(boolean enabled) + { + this.isMentionRaidProtectionEnabled = enabled; + return this; + } + @Nonnull @Override public DataObject toData() { DataObject data = super.toData(); data.put("mention_total_limit", mentionLimit); + data.put("mention_raid_protection_enabled", isMentionRaidProtectionEnabled); return data; } } diff --git a/src/main/java/net/dv8tion/jda/internal/entities/automod/AutoModRuleImpl.java b/src/main/java/net/dv8tion/jda/internal/entities/automod/AutoModRuleImpl.java index b57e6e122a..9bfbd75cad 100644 --- a/src/main/java/net/dv8tion/jda/internal/entities/automod/AutoModRuleImpl.java +++ b/src/main/java/net/dv8tion/jda/internal/entities/automod/AutoModRuleImpl.java @@ -54,6 +54,7 @@ public class AutoModRuleImpl implements AutoModRule private EnumSet filteredPresets = EnumSet.noneOf(KeywordPreset.class); private List allowlist = Collections.emptyList(); private int mentionLimit = -1; + private boolean isMentionRaidProtectionEnabled = false; public AutoModRuleImpl(Guild guild, long id) { @@ -181,6 +182,12 @@ public int getMentionLimit() return mentionLimit; } + @Override + public boolean isMentionRaidProtectionEnabled() + { + return isMentionRaidProtectionEnabled; + } + public AutoModRuleImpl setName(String name) { this.name = name; @@ -259,6 +266,12 @@ public AutoModRuleImpl setMentionLimit(int mentionLimit) return this; } + public AutoModRuleImpl setMentionRaidProtectionEnabled(boolean mentionRaidProtectionEnabled) + { + isMentionRaidProtectionEnabled = mentionRaidProtectionEnabled; + return this; + } + @Override public int hashCode() { @@ -329,6 +342,7 @@ public static AutoModRuleImpl fromData(Guild guild, DataObject data) ); // Only for MENTION type rule.setMentionLimit(metadata.getInt("mention_total_limit", 0)); + rule.setMentionRaidProtectionEnabled(metadata.getBoolean("mention_raid_protection_enabled")); }); return rule; From 17697ea20ac45e88070f14575dfbc4bf644fe2e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Spie=C3=9F?= Date: Sun, 7 May 2023 13:45:08 +0200 Subject: [PATCH 38/39] Improve type checks --- .../entities/automod/AutoModTriggerType.java | 46 ++++++++++++++++--- .../automod/build/AutoModRuleData.java | 6 +-- 2 files changed, 41 insertions(+), 11 deletions(-) diff --git a/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModTriggerType.java b/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModTriggerType.java index d030648515..06d082f3ae 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModTriggerType.java +++ b/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModTriggerType.java @@ -16,7 +16,10 @@ package net.dv8tion.jda.api.entities.automod; +import net.dv8tion.jda.internal.utils.Helpers; + import javax.annotation.Nonnull; +import java.util.EnumSet; /** * The type which defines what triggers an {@link AutoModRule}. @@ -26,36 +29,41 @@ public enum AutoModTriggerType /** * The rule is triggered by user message content containing specific keywords or phrases. */ - KEYWORD(1, 6), + KEYWORD(1, 6, AutoModEventType.MESSAGE_SEND, AutoModEventType.MEMBER_UPDATE), /** * The rule is triggered by user message content containing classified spam content. */ - SPAM(3, 1), + SPAM(3, 1, AutoModEventType.MESSAGE_SEND), /** * The rule is triggered by user message content containing keywords from a predefined list (such as {@link AutoModRule.KeywordPreset#SLURS slurs}). */ - KEYWORD_PRESET(4, 1), + KEYWORD_PRESET(4, 1, AutoModEventType.MESSAGE_SEND), /** * The rule is triggered by user message content containing more than the allowed number of mentions. */ - MENTION_SPAM(5, 1), + MENTION_SPAM(5, 1, AutoModEventType.MESSAGE_SEND), /** * The rule is triggered by a member profile containing specific keywords or phrases. */ - MEMBER_PROFILE_KEYWORD(6, 1), + MEMBER_PROFILE_KEYWORD(6, 1, AutoModEventType.MEMBER_UPDATE), /** * Placeholder for unknown trigger types that haven't been added yet. */ - UNKNOWN(-1, 1), + UNKNOWN(-1, 0), ; private final int key; private final int maxPerGuild; + private final EnumSet eventTypes; - AutoModTriggerType(int key, int maxPerGuild) + AutoModTriggerType(int key, int maxPerGuild, AutoModEventType... supportedEvents) { this.key = key; this.maxPerGuild = maxPerGuild; + if (supportedEvents.length > 0) + this.eventTypes = EnumSet.of(supportedEvents[0], supportedEvents); + else + this.eventTypes = EnumSet.noneOf(AutoModEventType.class); } /** @@ -78,6 +86,30 @@ public int getMaxPerGuild() return maxPerGuild; } + /** + * The {@link AutoModEventType AutoModEventTypes} that support this trigger type. + * + * @return The supported event types + */ + @Nonnull + public EnumSet getSupportedEventTypes() + { + return Helpers.copyEnumSet(AutoModEventType.class, eventTypes); + } + + /** + * Whether the provided {@link AutoModEventType} is supported by this trigger type. + * + * @param type + * The event type to check + * + * @return True, if the event type is supported + */ + public boolean isEventTypeSupported(@Nonnull AutoModEventType type) + { + return type != null && eventTypes.contains(type); + } + /** * The {@link AutoModTriggerType} that matches the provided key. * diff --git a/src/main/java/net/dv8tion/jda/api/entities/automod/build/AutoModRuleData.java b/src/main/java/net/dv8tion/jda/api/entities/automod/build/AutoModRuleData.java index 1be696e8fd..7d30bdbd4f 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/automod/build/AutoModRuleData.java +++ b/src/main/java/net/dv8tion/jda/api/entities/automod/build/AutoModRuleData.java @@ -95,7 +95,6 @@ public static AutoModRuleData onMessage(@Nonnull String name, @Nonnull TriggerCo return new AutoModRuleData(AutoModEventType.MESSAGE_SEND, name, triggerConfig); } - /** * Create a new {@link AutoModRule} which triggers on a member profile being updated. * @@ -112,13 +111,11 @@ public static AutoModRuleData onMessage(@Nonnull String name, @Nonnull TriggerCo @Nonnull public static AutoModRuleData onMemberProfile(@Nonnull String name, @Nonnull TriggerConfig triggerConfig) { - AutoModTriggerType type = triggerConfig.getType(); - if (type != AutoModTriggerType.KEYWORD && type != AutoModTriggerType.MEMBER_PROFILE_KEYWORD) - throw new IllegalArgumentException("Invalid trigger type for member profile: " + type); return new AutoModRuleData(AutoModEventType.MEMBER_UPDATE, name, triggerConfig) .putResponses(AutoModResponse.blockMemberInteraction()); } + /** * Change the name of the rule. * @@ -396,6 +393,7 @@ public AutoModRuleData setExemptChannels(@Nonnull Collection Date: Sat, 20 May 2023 16:35:10 +0200 Subject: [PATCH 39/39] Remove profile api again --- .../entities/automod/AutoModEventType.java | 4 ++ .../api/entities/automod/AutoModResponse.java | 7 ++++ .../entities/automod/AutoModTriggerType.java | 4 ++ .../automod/build/AutoModRuleData.java | 38 +++++++++---------- 4 files changed, 34 insertions(+), 19 deletions(-) diff --git a/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModEventType.java b/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModEventType.java index c630747001..4b7f6967c8 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModEventType.java +++ b/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModEventType.java @@ -16,6 +16,7 @@ package net.dv8tion.jda.api.entities.automod; +import net.dv8tion.jda.annotations.Incubating; import net.dv8tion.jda.api.entities.automod.build.AutoModRuleData; import net.dv8tion.jda.api.entities.automod.build.TriggerConfig; @@ -36,7 +37,10 @@ public enum AutoModEventType /** * The rule is triggered when a member updates their profile. + * + * @incubating This has not been officially released yet */ + @Incubating MEMBER_UPDATE(2), /** diff --git a/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModResponse.java b/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModResponse.java index b8a8a77521..b0cfe0a57a 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModResponse.java +++ b/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModResponse.java @@ -16,6 +16,7 @@ package net.dv8tion.jda.api.entities.automod; +import net.dv8tion.jda.annotations.Incubating; import net.dv8tion.jda.api.entities.channel.middleman.GuildMessageChannel; import net.dv8tion.jda.api.utils.data.SerializableData; import net.dv8tion.jda.internal.entities.automod.AutoModResponseImpl; @@ -142,8 +143,11 @@ static AutoModResponse timeoutMember(@Nonnull Duration duration) * Create a response that will prevent the member from interacting with anything in the guild until the offending content is removed. * * @return The response instance + * + * @incubating This has not been officially released yet */ @Nonnull + @Incubating static AutoModResponse blockMemberInteraction() { return new AutoModResponseImpl(Type.BLOCK_MEMBER_INTERACTION); @@ -170,7 +174,10 @@ enum Type TIMEOUT(3, EnumSet.of(AutoModTriggerType.KEYWORD, AutoModTriggerType.MENTION_SPAM)), /** * Blocks the member from interacting with the guild until they update the offending content. + * + * @incubating This has not been officially released yet */ + @Incubating BLOCK_MEMBER_INTERACTION(4, EnumSet.of(AutoModTriggerType.MEMBER_PROFILE_KEYWORD)), /** * Placeholder for unknown types. diff --git a/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModTriggerType.java b/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModTriggerType.java index 06d082f3ae..c7f3ca8986 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModTriggerType.java +++ b/src/main/java/net/dv8tion/jda/api/entities/automod/AutoModTriggerType.java @@ -16,6 +16,7 @@ package net.dv8tion.jda.api.entities.automod; +import net.dv8tion.jda.annotations.Incubating; import net.dv8tion.jda.internal.utils.Helpers; import javax.annotation.Nonnull; @@ -44,7 +45,10 @@ public enum AutoModTriggerType MENTION_SPAM(5, 1, AutoModEventType.MESSAGE_SEND), /** * The rule is triggered by a member profile containing specific keywords or phrases. + * + * @incubating This has not been officially released yet */ + @Incubating MEMBER_PROFILE_KEYWORD(6, 1, AutoModEventType.MEMBER_UPDATE), /** * Placeholder for unknown trigger types that haven't been added yet. diff --git a/src/main/java/net/dv8tion/jda/api/entities/automod/build/AutoModRuleData.java b/src/main/java/net/dv8tion/jda/api/entities/automod/build/AutoModRuleData.java index 7d30bdbd4f..3fe3b48acb 100644 --- a/src/main/java/net/dv8tion/jda/api/entities/automod/build/AutoModRuleData.java +++ b/src/main/java/net/dv8tion/jda/api/entities/automod/build/AutoModRuleData.java @@ -95,25 +95,25 @@ public static AutoModRuleData onMessage(@Nonnull String name, @Nonnull TriggerCo return new AutoModRuleData(AutoModEventType.MESSAGE_SEND, name, triggerConfig); } - /** - * Create a new {@link AutoModRule} which triggers on a member profile being updated. - * - * @param name - * The name of the rule (1-{@value AutoModRule#MAX_RULE_NAME_LENGTH} characters) - * @param triggerConfig - * The trigger configuration for this rule - * - * @throws IllegalArgumentException - * If null is provided or the name is not between 1 and {@value AutoModRule#MAX_RULE_NAME_LENGTH} characters - * - * @return The new {@link AutoModRuleData} instance - */ - @Nonnull - public static AutoModRuleData onMemberProfile(@Nonnull String name, @Nonnull TriggerConfig triggerConfig) - { - return new AutoModRuleData(AutoModEventType.MEMBER_UPDATE, name, triggerConfig) - .putResponses(AutoModResponse.blockMemberInteraction()); - } +// /** +// * Create a new {@link AutoModRule} which triggers on a member profile being updated. +// * +// * @param name +// * The name of the rule (1-{@value AutoModRule#MAX_RULE_NAME_LENGTH} characters) +// * @param triggerConfig +// * The trigger configuration for this rule +// * +// * @throws IllegalArgumentException +// * If null is provided or the name is not between 1 and {@value AutoModRule#MAX_RULE_NAME_LENGTH} characters +// * +// * @return The new {@link AutoModRuleData} instance +// */ +// @Nonnull +// public static AutoModRuleData onMemberProfile(@Nonnull String name, @Nonnull TriggerConfig triggerConfig) +// { +// return new AutoModRuleData(AutoModEventType.MEMBER_UPDATE, name, triggerConfig) +// .putResponses(AutoModResponse.blockMemberInteraction()); +// } /**