Skip to content

Commit

Permalink
Implement Automod Features (Pycord-Development#1316)
Browse files Browse the repository at this point in the history
Co-authored-by: baronkobama <amachann2005@gmail.com>
Co-authored-by: Lala Sabathil <lala@pycord.dev>
  • Loading branch information
3 people authored Jul 4, 2022
1 parent ef301fc commit d0d7451
Show file tree
Hide file tree
Showing 14 changed files with 967 additions and 3 deletions.
446 changes: 446 additions & 0 deletions discord/automod.py

Large diffs are not rendered by default.

34 changes: 34 additions & 0 deletions discord/enums.py
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,7 @@ class MessageType(Enum):
thread_starter_message = 21
guild_invite_reminder = 22
context_menu_command = 23
auto_moderation_action = 24


class VoiceRegion(Enum):
Expand Down Expand Up @@ -381,6 +382,10 @@ class AuditLogAction(Enum):
thread_update = 111
thread_delete = 112
application_command_permission_update = 121
auto_moderation_rule_create = 140
auto_moderation_rule_update = 141
auto_moderation_rule_delete = 142
auto_moderation_block_message = 143

@property
def category(self) -> Optional[AuditLogActionCategory]:
Expand Down Expand Up @@ -433,6 +438,10 @@ def category(self) -> Optional[AuditLogActionCategory]:
AuditLogAction.thread_update: AuditLogActionCategory.update,
AuditLogAction.thread_delete: AuditLogActionCategory.delete,
AuditLogAction.application_command_permission_update: AuditLogActionCategory.update,
AuditLogAction.auto_moderation_rule_create: AuditLogActionCategory.create,
AuditLogAction.auto_moderation_rule_update: AuditLogActionCategory.update,
AuditLogAction.auto_moderation_rule_delete: AuditLogActionCategory.delete,
AuditLogAction.auto_moderation_block_message: None,
}
return lookup[self]

Expand Down Expand Up @@ -471,6 +480,8 @@ def target_type(self) -> Optional[str]:
return "thread"
elif v < 122:
return "application_command_permission"
elif v < 144:
return "auto_moderation_rule"


class UserFlags(Enum):
Expand Down Expand Up @@ -764,6 +775,29 @@ class ScheduledEventLocationType(Enum):
voice = 2
external = 3


class AutoModTriggerType(Enum):
keyword = 1
harmful_link = 2
spam = 3
keyword_preset = 4


class AutoModEventType(Enum):
message_send = 1


class AutoModActionType(Enum):
block_message = 1
send_alert_message = 2
timeout = 3


class AutoModKeywordPresetType(Enum):
profanity = 1
sexual_content = 2
slurs = 3


T = TypeVar("T")

Expand Down
22 changes: 22 additions & 0 deletions discord/flags.py
Original file line number Diff line number Diff line change
Expand Up @@ -970,6 +970,28 @@ def scheduled_events(self):
- :meth:`Guild.get_scheduled_event`
"""
return 1 << 16

@flag_value
def auto_moderation_configuration(self):
""":class:`bool`: Whether guild auto moderation configuration events are enabled.
This corresponds to the following events:
- :func:`on_auto_moderation_rule_create`
- :func:`on_auto_moderation_rule_update`
- :func:`on_auto_moderation_rule_delete`
"""
return 1 << 20

@flag_value
def auto_moderation_execution(self):
""":class:`bool`: Whether guild auto moderation execution events are enabled.
This corresponds to the following events:
- :func:`on_auto_moderation_action_execution`
"""
return 1 << 21


@fill_with_flags()
Expand Down
112 changes: 111 additions & 1 deletion discord/guild.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,16 @@
)

from . import abc, utils
from .automod import AutoModAction, AutoModRule, AutoModTriggerMetadata
from .asset import Asset
from .channel import *
from .channel import _guild_channel_factory, _threaded_guild_channel_factory
from .colour import Colour
from .emoji import Emoji
from .enums import (
AuditLogAction,
AutoModEventType,
AutoModTriggerType,
ChannelType,
ContentFilter,
NotificationLevel,
Expand Down Expand Up @@ -203,6 +206,7 @@ class Guild(Hashable):
- ``ANIMATED_BANNER``: Guild can upload an animated banner.
- ``ANIMATED_ICON``: Guild can upload an animated icon.
- ``AUTO_MODERATION``: Guild has enabled the auto moderation system.
- ``BANNER``: Guild can upload and use a banner. (i.e. :attr:`.banner`)
- ``CHANNEL_BANNER``: Guild can upload and use a channel banners.
- ``COMMERCE``: Guild can sell things using store channels, which have now been removed.
Expand Down Expand Up @@ -545,7 +549,6 @@ def _from_data(self, guild: GuildPayload) -> None:

for obj in guild.get("voice_states", []):
self._update_voice_state(obj, int(obj["channel_id"]))

# TODO: refactor/remove?
def _sync(self, data: GuildPayload) -> None:
try:
Expand Down Expand Up @@ -3520,3 +3523,110 @@ async def create_scheduled_event(
def scheduled_events(self) -> List[ScheduledEvent]:
"""List[:class:`.ScheduledEvent`]: A list of scheduled events in this guild."""
return list(self._scheduled_events.values())

async def fetch_auto_moderation_rules(self) -> List[AutoModRule]:
"""|coro|
Retrieves a list of auto moderation rules for this guild.
Raises
-------
HTTPException
Getting the auto moderation rules failed.
Forbidden
You do not have the Manage Guild permission.
Returns
--------
List[:class:`AutoModRule`]
The auto moderation rules for this guild.
"""
data = await self._state.http.get_auto_moderation_rules(self.id)
return [AutoModRule(state=self._state, data=rule) for rule in data]

async def fetch_auto_moderation_rule(self, id: int) -> AutoModRule:
"""|coro|
Retrieves a :class:`AutoModRule` from rule ID.
Raises
-------
HTTPException
Getting the auto moderation rule failed.
Forbidden
You do not have the Manage Guild permission.
Returns
--------
:class:`AutoModRule`
The requested auto moderation rule.
"""
data = await self._state.http.get_auto_moderation_rule(self.id, id)
return AutoModRule(state=self._state, data=data)

async def create_auto_moderation_rule(
self,
*,
name: str,
event_type: AutoModEventType,
trigger_type: AutoModTriggerType,
trigger_metadata: AutoModTriggerMetadata,
actions: List[AutoModAction],
enabled: bool = False,
exempt_roles: List[Snowflake] = None,
exempt_channels: List[Snowflake] = None,
reason: Optional[str] = None,
) -> AutoModRule:
"""
Creates an auto moderation rule.
Parameters
-----------
name: :class:`str`
The name of the auto moderation rule.
event_type: :class:`AutoModEventType`
The type of event that triggers the rule.
trigger_type: :class:`AutoModTriggerType`
The rule's trigger type.
trigger_metadata: :class:`AutoModTriggerMetadata`
The rule's trigger metadata.
actions: List[:class:`AutoModAction`]
The actions to take when the rule is triggered.
enabled: :class:`bool`
Whether the rule is enabled.
exempt_roles: List[:class:`Snowflake`]
A list of roles that are exempt from the rule.
exempt_channels: List[:class:`Snowflake`]
A list of channels that are exempt from the rule.
reason: Optional[:class:`str`]
The reason for creating the rule. Shows up in the audit log.
Raises
-------
HTTPException
Creating the auto moderation rule failed.
Forbidden
You do not have the Manage Guild permission.
Returns
--------
:class:`AutoModRule`
The new auto moderation rule.
"""
payload = {
"name": name,
"event_type": event_type.value,
"trigger_type": trigger_type.value,
"trigger_metadata": trigger_metadata.to_dict(),
"actions": [a.to_dict() for a in actions],
"enabled": enabled,
}

if exempt_roles:
payload["exempt_roles"] = [r.id for r in exempt_roles]

if exempt_channels:
payload["exempt_channels"] = [c.id for c in exempt_channels]

data = await self._state.http.create_auto_moderation_rule(self.id, payload)
return AutoModRule(state=self._state, data=data, reason=reason)
69 changes: 69 additions & 0 deletions discord/http.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@
from .types import (
appinfo,
audit_log,
automod,
channel,
components,
embed,
Expand Down Expand Up @@ -2315,6 +2316,74 @@ def get_guild_command_permissions(
)
return self.request(r)

# Guild Automod Rules

def get_auto_moderation_rules(
self,
guild_id: Snowflake,
) -> Response[List[automod.AutoModRule]]:
r = Route(
"GET",
"/guilds/{guild_id}/auto-moderation/rules",
guild_id=guild_id,
)
return self.request(r)

def get_auto_moderation_rule(
self,
guild_id: Snowflake,
rule_id: Snowflake,
) -> Response[automod.AutoModRule]:
r = Route(
"GET",
"/guilds/{guild_id}/auto-moderation/rules/{rule_id}",
guild_id=guild_id,
rule_id=rule_id,
)
return self.request(r)

def create_auto_moderation_rule(
self,
guild_id: Snowflake,
payload: automod.CreateAutoModRule,
reason: Optional[str] = None,
) -> Response[automod.AutoModRule]:
r = Route(
"POST",
"/guilds/{guild_id}/auto-moderation/rules",
guild_id=guild_id,
)
return self.request(r, json=payload, reason=reason)

def edit_auto_moderation_rule(
self,
guild_id: Snowflake,
rule_id: Snowflake,
payload: automod.EditAutoModRule,
reason: Optional[str] = None,
) -> Response[automod.AutoModRule]:
r = Route(
"PATCH",
"/guilds/{guild_id}/auto-moderation/rules/{rule_id}",
guild_id=guild_id,
rule_id=rule_id,
)
return self.request(r, json=payload, reason=reason)

def delete_auto_moderation_rule(
self,
guild_id: Snowflake,
rule_id: Snowflake,
reason: Optional[str] = None,
) -> Response[None]:
r = Route(
"DELETE",
"/guilds/{guild_id}/auto-moderation/rules/{rule_id}",
guild_id=guild_id,
rule_id=rule_id,
)
return self.request(r, reason=reason)

# Interaction responses

def _edit_webhook_helper(
Expand Down
Loading

0 comments on commit d0d7451

Please sign in to comment.