Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: non-breaking auto mod fix #1546

Merged
merged 5 commits into from
Sep 2, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions interactions/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,9 @@
to_optional_snowflake,
to_snowflake,
to_snowflake_list,
TYPE_ALL_ACTION,
TYPE_ALL_CHANNEL,
TYPE_ALL_TRIGGER,
TYPE_CHANNEL_MAPPING,
TYPE_COMPONENT_MAPPING,
TYPE_DM_CHANNEL,
Expand Down Expand Up @@ -659,7 +661,9 @@
"to_optional_snowflake",
"to_snowflake",
"to_snowflake_list",
"TYPE_ALL_ACTION",
"TYPE_ALL_CHANNEL",
"TYPE_ALL_TRIGGER",
"TYPE_CHANNEL_MAPPING",
"TYPE_COMPONENT_MAPPING",
"TYPE_DM_CHANNEL",
Expand Down
2 changes: 2 additions & 0 deletions interactions/api/events/discord.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,8 @@ class AutoModExec(BaseEvent):

@attrs.define(eq=False, order=False, hash=False, kw_only=False)
class AutoModCreated(BaseEvent):
"""Dispatched when an auto mod rule is created"""

guild: "Guild" = attrs.field(repr=False, metadata=docs("The guild the rule was modified in"))
rule: "AutoModRule" = attrs.field(repr=False, metadata=docs("The rule that was modified"))

Expand Down
7 changes: 4 additions & 3 deletions interactions/api/events/processors/auto_mod.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
from typing import TYPE_CHECKING

from interactions.models.discord.auto_mod import AutoModerationAction, AutoModRule
from ._template import EventMixinTemplate, Processor

from ... import events
from ._template import EventMixinTemplate, Processor

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

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

@Processor.define()
async def raw_auto_moderation_rule_update(self, event: "RawGatewayEvent") -> None:
async def raw_auto_moderation_rule_delete(self, event: "RawGatewayEvent") -> None:
rule = AutoModRule.from_dict(event.data, self)
guild = self.get_guild(event.data["guild_id"])
self.dispatch(events.AutoModDeleted(guild, rule))
4 changes: 4 additions & 0 deletions interactions/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,9 @@
to_optional_snowflake,
to_snowflake,
to_snowflake_list,
TYPE_ALL_ACTION,
TYPE_ALL_CHANNEL,
TYPE_ALL_TRIGGER,
TYPE_CHANNEL_MAPPING,
TYPE_COMPONENT_MAPPING,
TYPE_DM_CHANNEL,
Expand Down Expand Up @@ -576,7 +578,9 @@
"to_optional_snowflake",
"to_snowflake",
"to_snowflake_list",
"TYPE_ALL_ACTION",
"TYPE_ALL_CHANNEL",
"TYPE_ALL_TRIGGER",
"TYPE_CHANNEL_MAPPING",
"TYPE_COMPONENT_MAPPING",
"TYPE_DM_CHANNEL",
Expand Down
4 changes: 3 additions & 1 deletion interactions/models/discord/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from .app_perms import ApplicationCommandPermission
from .application import Application
from .asset import Asset
from .auto_mod import AutoModerationAction, AutoModRule
from .auto_mod import AutoModerationAction, AutoModRule, TYPE_ALL_ACTION, TYPE_ALL_TRIGGER
from .channel import (
BaseChannel,
ChannelHistory,
Expand Down Expand Up @@ -337,7 +337,9 @@
"to_optional_snowflake",
"to_snowflake",
"to_snowflake_list",
"TYPE_ALL_ACTION",
"TYPE_ALL_CHANNEL",
"TYPE_ALL_TRIGGER",
"TYPE_CHANNEL_MAPPING",
"TYPE_COMPONENT_MAPPING",
"TYPE_DM_CHANNEL",
Expand Down
89 changes: 67 additions & 22 deletions interactions/models/discord/auto_mod.py
Original file line number Diff line number Diff line change
@@ -1,24 +1,32 @@
from typing import Any, Optional, TYPE_CHECKING
from typing import TYPE_CHECKING, Any, Optional, Union

import attrs

from interactions.client.const import get_logger, MISSING, Absent
from interactions.client.const import MISSING, Absent, get_logger
from interactions.client.mixins.serialization import DictSerializationMixin
from interactions.client.utils import list_converter, optional
from interactions.client.utils.attr_utils import docs
from interactions.models.discord.base import ClientObject, DiscordObject
from interactions.models.discord.enums import (
AutoModTriggerType,
AutoModAction,
AutoModEvent,
AutoModLanuguageType,
AutoModTriggerType,
)
from interactions.models.discord.snowflake import to_snowflake_list, to_snowflake
from interactions.models.discord.snowflake import to_snowflake, to_snowflake_list

if TYPE_CHECKING:
from interactions import Snowflake_Type, Guild, GuildText, Message, Client, Member, User
from interactions import (
Client,
Guild,
GuildText,
Member,
Message,
Snowflake_Type,
User,
)

__all__ = ("AutoModerationAction", "AutoModRule")
__all__ = ("AutoModerationAction", "AutoModRule", "TYPE_ALL_ACTION", "TYPE_ALL_TRIGGER")


@attrs.define(eq=False, order=False, hash=False, kw_only=True)
Expand Down Expand Up @@ -71,7 +79,7 @@ def _process_dict(cls, data: dict[str, Any]) -> dict[str, Any]:
return data

@classmethod
def from_dict_factory(cls, data: dict) -> "BaseAction":
def from_dict_factory(cls, data: dict) -> "TYPE_ALL_TRIGGER":
trigger_class = TRIGGER_MAPPING.get(data.get("trigger_type"))
meta = data.get("trigger_metadata", {})
if not trigger_class:
Expand Down Expand Up @@ -103,10 +111,22 @@ class KeywordTrigger(BaseTrigger):
repr=True,
metadata=docs("The type of trigger"),
)
keyword_filter: str | list[str] = attrs.field(
keyword_filter: list[str] = attrs.field(
factory=list,
repr=True,
metadata=docs("What words will trigger this"),
metadata=docs("Substrings which will be searched for in content"),
converter=_keyword_converter,
)
regex_patterns: list[str] = attrs.field(
factory=list,
repr=True,
metadata=docs("Regular expression patterns which will be matched against content"),
converter=_keyword_converter,
)
allow_list: list[str] = attrs.field(
factory=list,
repr=True,
metadata=docs("Substrings which should not trigger the rule"),
converter=_keyword_converter,
)

Expand Down Expand Up @@ -137,37 +157,57 @@ class KeywordPresetTrigger(BaseTrigger):
factory=list,
converter=list_converter(AutoModLanuguageType),
repr=True,
metadata=docs("The preset list of keywords that will trigger this"),
metadata=docs("The internally pre-defined wordsets which will be searched for in content"),
)


@attrs.define(eq=False, order=False, hash=False, kw_only=True)
class MentionSpamTrigger(BaseTrigger):
"""A trigger that checks if content contains more mentions than allowed"""
"""A trigger that checks if content contains more unique mentions than allowed"""

mention_total_limit: int = attrs.field(
default=3, repr=True, metadata=docs("The maximum number of mentions allowed")
)
mention_raid_protection_enabled: bool = attrs.field(
repr=True, metadata=docs("Whether to automatically detect mention raids")
)


@attrs.define(eq=False, order=False, hash=False, kw_only=True)
class MemberProfileTrigger(BaseTrigger):
"""A trigger that checks if member profile contains words from a user defined list of keywords"""

regex_patterns: list[str] = attrs.field(
factory=list, repr=True, metadata=docs("The regex patterns to check against")
factory=list,
repr=True,
metadata=docs("Regular expression patterns which will be matched against content"),
converter=_keyword_converter,
)
keyword_filter: str | list[str] = attrs.field(
factory=list, repr=True, metadata=docs("The keywords to check against")
keyword_filter: list[str] = attrs.field(
factory=list,
repr=True,
metadata=docs("Substrings which will be searched for in content"),
converter=_keyword_converter,
)
allow_list: list["Snowflake_Type"] = attrs.field(
factory=list, repr=True, metadata=docs("The roles exempt from this rule")
allow_list: list[str] = attrs.field(
factory=list,
repr=True,
metadata=docs("Substrings which should not trigger the rule"),
converter=_keyword_converter,
)


@attrs.define(eq=False, order=False, hash=False, kw_only=True)
class SpamTrigger(BaseTrigger):
"""A trigger that checks if content represents generic spam"""


@attrs.define(eq=False, order=False, hash=False, kw_only=True)
class BlockMessage(BaseAction):
"""blocks the content of a message according to the rule"""
"""Blocks the content of a message according to the rule"""

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


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

actions: list[BaseAction] = attrs.field(repr=False, factory=list)
actions: list["TYPE_ALL_ACTION"] = attrs.field(repr=False, factory=list)
"""the actions which will execute when the rule is triggered"""
event_type: AutoModEvent = attrs.field(
repr=False,
)
"""the rule event type"""
trigger: BaseTrigger = attrs.field(
trigger: "TYPE_ALL_TRIGGER" = attrs.field(
repr=False,
)
"""The trigger for this rule"""
Expand Down Expand Up @@ -262,10 +302,10 @@ async def modify(
self,
*,
name: Absent[str] = MISSING,
trigger: Absent[BaseTrigger] = MISSING,
trigger: Absent["TYPE_ALL_TRIGGER"] = MISSING,
trigger_type: Absent[AutoModTriggerType] = MISSING,
trigger_metadata: Absent[dict] = MISSING,
actions: Absent[list[BaseAction]] = MISSING,
actions: Absent[list["TYPE_ALL_ACTION"]] = MISSING,
exempt_channels: Absent[list["Snowflake_Type"]] = MISSING,
exempt_roles: Absent[list["Snowflake_Type"]] = MISSING,
event_type: Absent[AutoModEvent] = MISSING,
Expand Down Expand Up @@ -318,7 +358,7 @@ class AutoModerationAction(ClientObject):
repr=False,
)

action: BaseAction = attrs.field(default=MISSING, repr=True)
action: "TYPE_ALL_ACTION" = attrs.field(default=MISSING, repr=True)

matched_keyword: str = attrs.field(repr=True)
matched_content: Optional[str] = attrs.field(repr=False, default=None)
Expand Down Expand Up @@ -369,7 +409,12 @@ def member(self) -> "Optional[Member]":
TRIGGER_MAPPING = {
AutoModTriggerType.KEYWORD: KeywordTrigger,
AutoModTriggerType.HARMFUL_LINK: HarmfulLinkFilter,
AutoModTriggerType.SPAM: SpamTrigger,
AutoModTriggerType.KEYWORD_PRESET: KeywordPresetTrigger,
AutoModTriggerType.MENTION_SPAM: MentionSpamTrigger,
AutoModTriggerType.MEMBER_PROFILE: MemberProfileTrigger,
}

TYPE_ALL_TRIGGER = Union[KeywordTrigger, SpamTrigger, KeywordPresetTrigger, MentionSpamTrigger, MemberProfileTrigger]

TYPE_ALL_ACTION = Union[BlockMessage, AlertMessage, TimeoutUser, BlockMemberInteraction]