|
1 |
| -from typing import Any, Optional, TYPE_CHECKING |
| 1 | +from typing import TYPE_CHECKING, Any, Optional, Union |
2 | 2 |
|
3 | 3 | import attrs
|
4 | 4 |
|
5 |
| -from interactions.client.const import get_logger, MISSING, Absent |
| 5 | +from interactions.client.const import MISSING, Absent, get_logger |
6 | 6 | from interactions.client.mixins.serialization import DictSerializationMixin
|
7 | 7 | from interactions.client.utils import list_converter, optional
|
8 | 8 | from interactions.client.utils.attr_utils import docs
|
9 | 9 | from interactions.models.discord.base import ClientObject, DiscordObject
|
10 | 10 | from interactions.models.discord.enums import (
|
11 |
| - AutoModTriggerType, |
12 | 11 | AutoModAction,
|
13 | 12 | AutoModEvent,
|
14 | 13 | AutoModLanuguageType,
|
| 14 | + AutoModTriggerType, |
15 | 15 | )
|
16 |
| -from interactions.models.discord.snowflake import to_snowflake_list, to_snowflake |
| 16 | +from interactions.models.discord.snowflake import to_snowflake, to_snowflake_list |
17 | 17 |
|
18 | 18 | if TYPE_CHECKING:
|
19 |
| - from interactions import Snowflake_Type, Guild, GuildText, Message, Client, Member, User |
| 19 | + from interactions import ( |
| 20 | + Client, |
| 21 | + Guild, |
| 22 | + GuildText, |
| 23 | + Member, |
| 24 | + Message, |
| 25 | + Snowflake_Type, |
| 26 | + User, |
| 27 | + ) |
20 | 28 |
|
21 |
| -__all__ = ("AutoModerationAction", "AutoModRule") |
| 29 | +__all__ = ("AutoModerationAction", "AutoModRule", "TYPE_ALL_ACTION", "TYPE_ALL_TRIGGER") |
22 | 30 |
|
23 | 31 |
|
24 | 32 | @attrs.define(eq=False, order=False, hash=False, kw_only=True)
|
@@ -71,7 +79,7 @@ def _process_dict(cls, data: dict[str, Any]) -> dict[str, Any]:
|
71 | 79 | return data
|
72 | 80 |
|
73 | 81 | @classmethod
|
74 |
| - def from_dict_factory(cls, data: dict) -> "BaseAction": |
| 82 | + def from_dict_factory(cls, data: dict) -> "TYPE_ALL_TRIGGER": |
75 | 83 | trigger_class = TRIGGER_MAPPING.get(data.get("trigger_type"))
|
76 | 84 | meta = data.get("trigger_metadata", {})
|
77 | 85 | if not trigger_class:
|
@@ -103,10 +111,22 @@ class KeywordTrigger(BaseTrigger):
|
103 | 111 | repr=True,
|
104 | 112 | metadata=docs("The type of trigger"),
|
105 | 113 | )
|
106 |
| - keyword_filter: str | list[str] = attrs.field( |
| 114 | + keyword_filter: list[str] = attrs.field( |
107 | 115 | factory=list,
|
108 | 116 | repr=True,
|
109 |
| - metadata=docs("What words will trigger this"), |
| 117 | + metadata=docs("Substrings which will be searched for in content"), |
| 118 | + converter=_keyword_converter, |
| 119 | + ) |
| 120 | + regex_patterns: list[str] = attrs.field( |
| 121 | + factory=list, |
| 122 | + repr=True, |
| 123 | + metadata=docs("Regular expression patterns which will be matched against content"), |
| 124 | + converter=_keyword_converter, |
| 125 | + ) |
| 126 | + allow_list: list[str] = attrs.field( |
| 127 | + factory=list, |
| 128 | + repr=True, |
| 129 | + metadata=docs("Substrings which should not trigger the rule"), |
110 | 130 | converter=_keyword_converter,
|
111 | 131 | )
|
112 | 132 |
|
@@ -137,37 +157,57 @@ class KeywordPresetTrigger(BaseTrigger):
|
137 | 157 | factory=list,
|
138 | 158 | converter=list_converter(AutoModLanuguageType),
|
139 | 159 | repr=True,
|
140 |
| - metadata=docs("The preset list of keywords that will trigger this"), |
| 160 | + metadata=docs("The internally pre-defined wordsets which will be searched for in content"), |
141 | 161 | )
|
142 | 162 |
|
143 | 163 |
|
144 | 164 | @attrs.define(eq=False, order=False, hash=False, kw_only=True)
|
145 | 165 | class MentionSpamTrigger(BaseTrigger):
|
146 |
| - """A trigger that checks if content contains more mentions than allowed""" |
| 166 | + """A trigger that checks if content contains more unique mentions than allowed""" |
147 | 167 |
|
148 | 168 | mention_total_limit: int = attrs.field(
|
149 | 169 | default=3, repr=True, metadata=docs("The maximum number of mentions allowed")
|
150 | 170 | )
|
| 171 | + mention_raid_protection_enabled: bool = attrs.field( |
| 172 | + repr=True, metadata=docs("Whether to automatically detect mention raids") |
| 173 | + ) |
151 | 174 |
|
152 | 175 |
|
153 | 176 | @attrs.define(eq=False, order=False, hash=False, kw_only=True)
|
154 | 177 | class MemberProfileTrigger(BaseTrigger):
|
| 178 | + """A trigger that checks if member profile contains words from a user defined list of keywords""" |
| 179 | + |
155 | 180 | regex_patterns: list[str] = attrs.field(
|
156 |
| - factory=list, repr=True, metadata=docs("The regex patterns to check against") |
| 181 | + factory=list, |
| 182 | + repr=True, |
| 183 | + metadata=docs("Regular expression patterns which will be matched against content"), |
| 184 | + converter=_keyword_converter, |
157 | 185 | )
|
158 |
| - keyword_filter: str | list[str] = attrs.field( |
159 |
| - factory=list, repr=True, metadata=docs("The keywords to check against") |
| 186 | + keyword_filter: list[str] = attrs.field( |
| 187 | + factory=list, |
| 188 | + repr=True, |
| 189 | + metadata=docs("Substrings which will be searched for in content"), |
| 190 | + converter=_keyword_converter, |
160 | 191 | )
|
161 |
| - allow_list: list["Snowflake_Type"] = attrs.field( |
162 |
| - factory=list, repr=True, metadata=docs("The roles exempt from this rule") |
| 192 | + allow_list: list[str] = attrs.field( |
| 193 | + factory=list, |
| 194 | + repr=True, |
| 195 | + metadata=docs("Substrings which should not trigger the rule"), |
| 196 | + converter=_keyword_converter, |
163 | 197 | )
|
164 | 198 |
|
165 | 199 |
|
| 200 | +@attrs.define(eq=False, order=False, hash=False, kw_only=True) |
| 201 | +class SpamTrigger(BaseTrigger): |
| 202 | + """A trigger that checks if content represents generic spam""" |
| 203 | + |
| 204 | + |
166 | 205 | @attrs.define(eq=False, order=False, hash=False, kw_only=True)
|
167 | 206 | class BlockMessage(BaseAction):
|
168 |
| - """blocks the content of a message according to the rule""" |
| 207 | + """Blocks the content of a message according to the rule""" |
169 | 208 |
|
170 | 209 | type: AutoModAction = attrs.field(repr=False, default=AutoModAction.BLOCK_MESSAGE, converter=AutoModAction)
|
| 210 | + custom_message: Optional[str] = attrs.field(repr=True, default=None) |
171 | 211 |
|
172 | 212 |
|
173 | 213 | @attrs.define(eq=False, order=False, hash=False, kw_only=True)
|
@@ -204,13 +244,13 @@ class AutoModRule(DiscordObject):
|
204 | 244 | enabled: bool = attrs.field(repr=False, default=False)
|
205 | 245 | """whether the rule is enabled"""
|
206 | 246 |
|
207 |
| - actions: list[BaseAction] = attrs.field(repr=False, factory=list) |
| 247 | + actions: list["TYPE_ALL_ACTION"] = attrs.field(repr=False, factory=list) |
208 | 248 | """the actions which will execute when the rule is triggered"""
|
209 | 249 | event_type: AutoModEvent = attrs.field(
|
210 | 250 | repr=False,
|
211 | 251 | )
|
212 | 252 | """the rule event type"""
|
213 |
| - trigger: BaseTrigger = attrs.field( |
| 253 | + trigger: "TYPE_ALL_TRIGGER" = attrs.field( |
214 | 254 | repr=False,
|
215 | 255 | )
|
216 | 256 | """The trigger for this rule"""
|
@@ -262,10 +302,10 @@ async def modify(
|
262 | 302 | self,
|
263 | 303 | *,
|
264 | 304 | name: Absent[str] = MISSING,
|
265 |
| - trigger: Absent[BaseTrigger] = MISSING, |
| 305 | + trigger: Absent["TYPE_ALL_TRIGGER"] = MISSING, |
266 | 306 | trigger_type: Absent[AutoModTriggerType] = MISSING,
|
267 | 307 | trigger_metadata: Absent[dict] = MISSING,
|
268 |
| - actions: Absent[list[BaseAction]] = MISSING, |
| 308 | + actions: Absent[list["TYPE_ALL_ACTION"]] = MISSING, |
269 | 309 | exempt_channels: Absent[list["Snowflake_Type"]] = MISSING,
|
270 | 310 | exempt_roles: Absent[list["Snowflake_Type"]] = MISSING,
|
271 | 311 | event_type: Absent[AutoModEvent] = MISSING,
|
@@ -318,7 +358,7 @@ class AutoModerationAction(ClientObject):
|
318 | 358 | repr=False,
|
319 | 359 | )
|
320 | 360 |
|
321 |
| - action: BaseAction = attrs.field(default=MISSING, repr=True) |
| 361 | + action: "TYPE_ALL_ACTION" = attrs.field(default=MISSING, repr=True) |
322 | 362 |
|
323 | 363 | matched_keyword: str = attrs.field(repr=True)
|
324 | 364 | matched_content: Optional[str] = attrs.field(repr=False, default=None)
|
@@ -369,7 +409,12 @@ def member(self) -> "Optional[Member]":
|
369 | 409 | TRIGGER_MAPPING = {
|
370 | 410 | AutoModTriggerType.KEYWORD: KeywordTrigger,
|
371 | 411 | AutoModTriggerType.HARMFUL_LINK: HarmfulLinkFilter,
|
| 412 | + AutoModTriggerType.SPAM: SpamTrigger, |
372 | 413 | AutoModTriggerType.KEYWORD_PRESET: KeywordPresetTrigger,
|
373 | 414 | AutoModTriggerType.MENTION_SPAM: MentionSpamTrigger,
|
374 | 415 | AutoModTriggerType.MEMBER_PROFILE: MemberProfileTrigger,
|
375 | 416 | }
|
| 417 | + |
| 418 | +TYPE_ALL_TRIGGER = Union[KeywordTrigger, SpamTrigger, KeywordPresetTrigger, MentionSpamTrigger, MemberProfileTrigger] |
| 419 | + |
| 420 | +TYPE_ALL_ACTION = Union[BlockMessage, AlertMessage, TimeoutUser, BlockMemberInteraction] |
0 commit comments