Skip to content

Commit d69b4de

Browse files
authored
fix: non-breaking auto mod fix (#1546)
* fix: non-breaking auto mod fix * fix: re-add update/delete auto mod fixes * re-add type properties * feat: add TYPE_ALL_TRIGGER and TYPE_ALL_ACTION to interactions namespace
1 parent 69d187f commit d69b4de

File tree

6 files changed

+84
-26
lines changed

6 files changed

+84
-26
lines changed

interactions/__init__.py

+4
Original file line numberDiff line numberDiff line change
@@ -310,7 +310,9 @@
310310
to_optional_snowflake,
311311
to_snowflake,
312312
to_snowflake_list,
313+
TYPE_ALL_ACTION,
313314
TYPE_ALL_CHANNEL,
315+
TYPE_ALL_TRIGGER,
314316
TYPE_CHANNEL_MAPPING,
315317
TYPE_COMPONENT_MAPPING,
316318
TYPE_DM_CHANNEL,
@@ -659,7 +661,9 @@
659661
"to_optional_snowflake",
660662
"to_snowflake",
661663
"to_snowflake_list",
664+
"TYPE_ALL_ACTION",
662665
"TYPE_ALL_CHANNEL",
666+
"TYPE_ALL_TRIGGER",
663667
"TYPE_CHANNEL_MAPPING",
664668
"TYPE_COMPONENT_MAPPING",
665669
"TYPE_DM_CHANNEL",

interactions/api/events/discord.py

+2
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,8 @@ class AutoModExec(BaseEvent):
132132

133133
@attrs.define(eq=False, order=False, hash=False, kw_only=False)
134134
class AutoModCreated(BaseEvent):
135+
"""Dispatched when an auto mod rule is created"""
136+
135137
guild: "Guild" = attrs.field(repr=False, metadata=docs("The guild the rule was modified in"))
136138
rule: "AutoModRule" = attrs.field(repr=False, metadata=docs("The rule that was modified"))
137139

interactions/api/events/processors/auto_mod.py

+4-3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
from typing import TYPE_CHECKING
22

33
from interactions.models.discord.auto_mod import AutoModerationAction, AutoModRule
4-
from ._template import EventMixinTemplate, Processor
4+
55
from ... import events
6+
from ._template import EventMixinTemplate, Processor
67

78
if TYPE_CHECKING:
89
from interactions.api.events import RawGatewayEvent
@@ -25,13 +26,13 @@ async def raw_auto_moderation_rule_create(self, event: "RawGatewayEvent") -> Non
2526
self.dispatch(events.AutoModCreated(guild, rule))
2627

2728
@Processor.define()
28-
async def raw_auto_moderation_rule_delete(self, event: "RawGatewayEvent") -> None:
29+
async def raw_auto_moderation_rule_update(self, event: "RawGatewayEvent") -> None:
2930
rule = AutoModRule.from_dict(event.data, self)
3031
guild = self.get_guild(event.data["guild_id"])
3132
self.dispatch(events.AutoModUpdated(guild, rule))
3233

3334
@Processor.define()
34-
async def raw_auto_moderation_rule_update(self, event: "RawGatewayEvent") -> None:
35+
async def raw_auto_moderation_rule_delete(self, event: "RawGatewayEvent") -> None:
3536
rule = AutoModRule.from_dict(event.data, self)
3637
guild = self.get_guild(event.data["guild_id"])
3738
self.dispatch(events.AutoModDeleted(guild, rule))

interactions/models/__init__.py

+4
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,9 @@
167167
to_optional_snowflake,
168168
to_snowflake,
169169
to_snowflake_list,
170+
TYPE_ALL_ACTION,
170171
TYPE_ALL_CHANNEL,
172+
TYPE_ALL_TRIGGER,
171173
TYPE_CHANNEL_MAPPING,
172174
TYPE_COMPONENT_MAPPING,
173175
TYPE_DM_CHANNEL,
@@ -576,7 +578,9 @@
576578
"to_optional_snowflake",
577579
"to_snowflake",
578580
"to_snowflake_list",
581+
"TYPE_ALL_ACTION",
579582
"TYPE_ALL_CHANNEL",
583+
"TYPE_ALL_TRIGGER",
580584
"TYPE_CHANNEL_MAPPING",
581585
"TYPE_COMPONENT_MAPPING",
582586
"TYPE_DM_CHANNEL",

interactions/models/discord/__init__.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
from .app_perms import ApplicationCommandPermission
33
from .application import Application
44
from .asset import Asset
5-
from .auto_mod import AutoModerationAction, AutoModRule
5+
from .auto_mod import AutoModerationAction, AutoModRule, TYPE_ALL_ACTION, TYPE_ALL_TRIGGER
66
from .channel import (
77
BaseChannel,
88
ChannelHistory,
@@ -337,7 +337,9 @@
337337
"to_optional_snowflake",
338338
"to_snowflake",
339339
"to_snowflake_list",
340+
"TYPE_ALL_ACTION",
340341
"TYPE_ALL_CHANNEL",
342+
"TYPE_ALL_TRIGGER",
341343
"TYPE_CHANNEL_MAPPING",
342344
"TYPE_COMPONENT_MAPPING",
343345
"TYPE_DM_CHANNEL",

interactions/models/discord/auto_mod.py

+67-22
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,32 @@
1-
from typing import Any, Optional, TYPE_CHECKING
1+
from typing import TYPE_CHECKING, Any, Optional, Union
22

33
import attrs
44

5-
from interactions.client.const import get_logger, MISSING, Absent
5+
from interactions.client.const import MISSING, Absent, get_logger
66
from interactions.client.mixins.serialization import DictSerializationMixin
77
from interactions.client.utils import list_converter, optional
88
from interactions.client.utils.attr_utils import docs
99
from interactions.models.discord.base import ClientObject, DiscordObject
1010
from interactions.models.discord.enums import (
11-
AutoModTriggerType,
1211
AutoModAction,
1312
AutoModEvent,
1413
AutoModLanuguageType,
14+
AutoModTriggerType,
1515
)
16-
from interactions.models.discord.snowflake import to_snowflake_list, to_snowflake
16+
from interactions.models.discord.snowflake import to_snowflake, to_snowflake_list
1717

1818
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+
)
2028

21-
__all__ = ("AutoModerationAction", "AutoModRule")
29+
__all__ = ("AutoModerationAction", "AutoModRule", "TYPE_ALL_ACTION", "TYPE_ALL_TRIGGER")
2230

2331

2432
@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]:
7179
return data
7280

7381
@classmethod
74-
def from_dict_factory(cls, data: dict) -> "BaseAction":
82+
def from_dict_factory(cls, data: dict) -> "TYPE_ALL_TRIGGER":
7583
trigger_class = TRIGGER_MAPPING.get(data.get("trigger_type"))
7684
meta = data.get("trigger_metadata", {})
7785
if not trigger_class:
@@ -103,10 +111,22 @@ class KeywordTrigger(BaseTrigger):
103111
repr=True,
104112
metadata=docs("The type of trigger"),
105113
)
106-
keyword_filter: str | list[str] = attrs.field(
114+
keyword_filter: list[str] = attrs.field(
107115
factory=list,
108116
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"),
110130
converter=_keyword_converter,
111131
)
112132

@@ -137,37 +157,57 @@ class KeywordPresetTrigger(BaseTrigger):
137157
factory=list,
138158
converter=list_converter(AutoModLanuguageType),
139159
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"),
141161
)
142162

143163

144164
@attrs.define(eq=False, order=False, hash=False, kw_only=True)
145165
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"""
147167

148168
mention_total_limit: int = attrs.field(
149169
default=3, repr=True, metadata=docs("The maximum number of mentions allowed")
150170
)
171+
mention_raid_protection_enabled: bool = attrs.field(
172+
repr=True, metadata=docs("Whether to automatically detect mention raids")
173+
)
151174

152175

153176
@attrs.define(eq=False, order=False, hash=False, kw_only=True)
154177
class MemberProfileTrigger(BaseTrigger):
178+
"""A trigger that checks if member profile contains words from a user defined list of keywords"""
179+
155180
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,
157185
)
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,
160191
)
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,
163197
)
164198

165199

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+
166205
@attrs.define(eq=False, order=False, hash=False, kw_only=True)
167206
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"""
169208

170209
type: AutoModAction = attrs.field(repr=False, default=AutoModAction.BLOCK_MESSAGE, converter=AutoModAction)
210+
custom_message: Optional[str] = attrs.field(repr=True, default=None)
171211

172212

173213
@attrs.define(eq=False, order=False, hash=False, kw_only=True)
@@ -204,13 +244,13 @@ class AutoModRule(DiscordObject):
204244
enabled: bool = attrs.field(repr=False, default=False)
205245
"""whether the rule is enabled"""
206246

207-
actions: list[BaseAction] = attrs.field(repr=False, factory=list)
247+
actions: list["TYPE_ALL_ACTION"] = attrs.field(repr=False, factory=list)
208248
"""the actions which will execute when the rule is triggered"""
209249
event_type: AutoModEvent = attrs.field(
210250
repr=False,
211251
)
212252
"""the rule event type"""
213-
trigger: BaseTrigger = attrs.field(
253+
trigger: "TYPE_ALL_TRIGGER" = attrs.field(
214254
repr=False,
215255
)
216256
"""The trigger for this rule"""
@@ -262,10 +302,10 @@ async def modify(
262302
self,
263303
*,
264304
name: Absent[str] = MISSING,
265-
trigger: Absent[BaseTrigger] = MISSING,
305+
trigger: Absent["TYPE_ALL_TRIGGER"] = MISSING,
266306
trigger_type: Absent[AutoModTriggerType] = MISSING,
267307
trigger_metadata: Absent[dict] = MISSING,
268-
actions: Absent[list[BaseAction]] = MISSING,
308+
actions: Absent[list["TYPE_ALL_ACTION"]] = MISSING,
269309
exempt_channels: Absent[list["Snowflake_Type"]] = MISSING,
270310
exempt_roles: Absent[list["Snowflake_Type"]] = MISSING,
271311
event_type: Absent[AutoModEvent] = MISSING,
@@ -318,7 +358,7 @@ class AutoModerationAction(ClientObject):
318358
repr=False,
319359
)
320360

321-
action: BaseAction = attrs.field(default=MISSING, repr=True)
361+
action: "TYPE_ALL_ACTION" = attrs.field(default=MISSING, repr=True)
322362

323363
matched_keyword: str = attrs.field(repr=True)
324364
matched_content: Optional[str] = attrs.field(repr=False, default=None)
@@ -369,7 +409,12 @@ def member(self) -> "Optional[Member]":
369409
TRIGGER_MAPPING = {
370410
AutoModTriggerType.KEYWORD: KeywordTrigger,
371411
AutoModTriggerType.HARMFUL_LINK: HarmfulLinkFilter,
412+
AutoModTriggerType.SPAM: SpamTrigger,
372413
AutoModTriggerType.KEYWORD_PRESET: KeywordPresetTrigger,
373414
AutoModTriggerType.MENTION_SPAM: MentionSpamTrigger,
374415
AutoModTriggerType.MEMBER_PROFILE: MemberProfileTrigger,
375416
}
417+
418+
TYPE_ALL_TRIGGER = Union[KeywordTrigger, SpamTrigger, KeywordPresetTrigger, MentionSpamTrigger, MemberProfileTrigger]
419+
420+
TYPE_ALL_ACTION = Union[BlockMessage, AlertMessage, TimeoutUser, BlockMemberInteraction]

0 commit comments

Comments
 (0)