Skip to content

Commit 0802deb

Browse files
committed
feat(implement:AutoMod): Added support for providing a reason when creating, editing and deleting an automod rule
1 parent c3d0d6f commit 0802deb

File tree

3 files changed

+156
-26
lines changed

3 files changed

+156
-26
lines changed

discord/automod.py

Lines changed: 125 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242
from . import utils
4343
from .role import Role
4444
from .object import Object
45-
from .abc import GuildChannel
45+
from .abc import GuildChannel, Snowflake
4646
from .utils import SnowflakeList
4747
from .errors import ClientException
4848
from .enums import AutoModEventType, AutoModKeywordPresetType, AutoModActionType, AutoModTriggerType, try_enum
@@ -342,6 +342,9 @@ def __init__(self,
342342
self._state: ConnectionState = state
343343
self.guild: Guild = guild
344344
self.id: int = int(data['id'])
345+
self._update(data)
346+
347+
def _update(self, data) -> AutoModRule:
345348
self.name: str = data['name']
346349
self.creator_id: int = int(data['creator_id'])
347350
self.event_type: AutoModEventType = try_enum(AutoModEventType, data['event_type'])
@@ -351,6 +354,7 @@ def __init__(self,
351354
self.enabled: bool = data['enabled']
352355
self._exempt_roles: SnowflakeList = SnowflakeList(map(int, data['exempt_roles']))
353356
self._exempt_channels: SnowflakeList = SnowflakeList(map(int, data['exempt_channels']))
357+
return self
354358

355359
def __repr__(self) -> str:
356360
return f'<AutoModRule "{self.name}" guild_id={self.guild.id} creator_id={self.creator_id}>'
@@ -430,6 +434,126 @@ def created_at(self) -> datetime.datetime:
430434
""":class:`datetime.datetime`: When the rule was created in UTC"""
431435
return utils.snowflake_time(self.id)
432436

437+
async def delete(self, *, reason: Optional[str]) -> None:
438+
"""|coro|
439+
440+
Deletes the automod rule, this requires the :attr:`~Permissions.manage_server` permission.
441+
442+
Parameters
443+
-----------
444+
reason: Optional[:class:`str`]
445+
The reason for deleting this rule. Shows up in the audit log.
446+
447+
Raises
448+
------
449+
:exc:`discord.Forbidden`
450+
The bot is missing permissions to delete the rule
451+
:exc:`~discord.HTTPException`
452+
Deleting the rule failed
453+
"""
454+
await self._state.http.delete_automod_rule(self.guild.id, self.id, reason=reason)
455+
456+
async def edit(self, *, reason: Optional[str] = None, **payload) -> AutoModRule:
457+
"""|coro|
458+
459+
Edits the automod rule, this requires the :attr:`~Permissions.manage_server` permission.
460+
461+
Parameters
462+
----------
463+
name: Optional[:class:`str`]
464+
The name, the rule should have. Only valid if it's not a preset rule.
465+
event_type: Optional[:class:`~discord.AutoModEventType`]
466+
Indicates in what event context a rule should be checked
467+
trigger_type: Optional[:class:`~discord.AutoModTriggerType`]
468+
Characterizes the type of content which can trigger the rule
469+
trigger_metadata: Optional[:class:`~discord.AutoModTriggerMetadata`]
470+
Additional data used to determine whether a rule should be triggered.
471+
Different fields are relevant based on the value of :attr:`~AutoModRule.trigger_type`.
472+
actions: Optional[List[:class:`~discord.AutoModAction`]]
473+
The actions which will execute when the rule is triggered.
474+
enabled: Optional[:class:`bool`]
475+
Whether the rule is enabled, default :obj:`True`.
476+
exempt_roles: Optional[List[:class:`.Snowflake`]]
477+
Up to 20 :class:`~discord.Role`'s, that should not be affected by the rule.
478+
exempt_channels: Optional[List[:class:`.Snowflake`]]
479+
Up to 50 :class:`~discord.TextChannel`/:class:`~discord.VoiceChannel`'s, that should not be affected by the rule.
480+
reason: Optional[:class:`str`]
481+
The reason for editing the rule. Shows up in the audit log.
482+
483+
Raises
484+
-------
485+
:exc:`discord.Forbidden`
486+
The bot is missing permissions to edit the rule
487+
:exc:`~discord.HTTPException`
488+
Editing the rule failed
489+
490+
Returns
491+
-------
492+
:class:`AutoModRule`
493+
The updated rule on success.
494+
"""
495+
data = {}
496+
497+
try:
498+
name: str = payload['name']
499+
except KeyError:
500+
pass
501+
else:
502+
data['name'] = name
503+
504+
try:
505+
event_type: AutoModEventType = payload['event_type']
506+
except KeyError:
507+
pass
508+
else:
509+
data['event_type'] = int(event_type)
510+
511+
try:
512+
trigger_type = payload['trigger_type']
513+
except KeyError:
514+
pass
515+
else:
516+
data['trigger_type'] = int(trigger_type)
517+
518+
try:
519+
trigger_metadata: AutoModTriggerMetadata = payload['trigger_metadata']
520+
except KeyError:
521+
pass
522+
else:
523+
data['trigger_metadata'] = int(trigger_metadata)
524+
525+
try:
526+
exempt_channels: List[Snowflake] = payload['exempt_channels']
527+
except KeyError:
528+
exempt_channels = self._exempt_channels
529+
data['exempt_channels'] = exempt_channels = [str(c.id) for c in exempt_channels]
530+
531+
try:
532+
actions: List[AutoModAction] = payload['actions']
533+
except KeyError:
534+
pass
535+
else:
536+
for action in actions: # Add the channels where messages should be logged to, to the exempted channels
537+
if action.type.send_alert_message and str(action.channel_id) not in exempt_channels:
538+
exempt_channels.append(str(action.channel_id))
539+
data['actions'] = [a.to_dict() for a in actions]
540+
541+
try:
542+
enabled: bool = payload['enabled']
543+
except KeyError:
544+
pass
545+
else:
546+
data['enabled'] = enabled
547+
548+
try:
549+
exempt_roles: List[Snowflake] = payload['exempt_roles']
550+
except KeyError:
551+
pass
552+
else:
553+
data['exempt_roles'] = [str(r.id) for r in exempt_roles]
554+
data = await self._state.http.edit_automod_rule(self.guild.id, self.id, data=data, reason=reason)
555+
return self._update(data)
556+
433557

434558
class AutoModActionPayload:
435559
"""Represents the payload for an :func:`on_automod_action` event

discord/guild.py

Lines changed: 22 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2824,42 +2824,45 @@ async def create_automod_rule(self,
28242824
actions: List[AutoModAction],
28252825
enabled: bool = True,
28262826
exempt_roles: List['Snowflake'] = [],
2827-
exempt_channels: List['Snowflake'] = []) -> AutoModRule:
2827+
exempt_channels: List['Snowflake'] = [],
2828+
*, reason: Optional[str] = None) -> AutoModRule:
28282829
"""|coro|
28292830
28302831
Creates a new AutoMod rule for this guild
28312832
28322833
Parameters
28332834
-----------
28342835
name: :class:`str`
2835-
The name, the rule should have
2836+
The name, the rule should have. Only valid if it's not a preset rule.
28362837
event_type: :class:`~discord.AutoModEventType`
2837-
Indicates in what event context a rule should be checked
2838+
Indicates in what event context a rule should be checked.
28382839
trigger_type: :class:`~discord.AutoModTriggerType`
2839-
Characterizes the type of content which can trigger the rule
2840+
Characterizes the type of content which can trigger the rule.
28402841
trigger_metadata: :class:`~discord.AutoModTriggerMetadata`
28412842
Additional data used to determine whether a rule should be triggered.
2842-
Different fields are relevant based on the value of :attr:`~Guild.create_automod_rule.trigger_type`.
2843+
Different fields are relevant based on the value of :attr:`~AutoModRule.trigger_type`.
28432844
actions: List[:class:`~discord.AutoModAction`]
2844-
The actions which will execute when the rule is triggered
2845+
The actions which will execute when the rule is triggered.
28452846
enabled: :class:`bool`
2846-
Whether the rule is enabled, default ``True``
2847+
Whether the rule is enabled, default :obj:`True`.
28472848
exempt_roles: List[:class:`.Snowflake`]
2848-
Up to 20 :class:`~discord.Role`'s, that should not be affected by the rule
2849+
Up to 20 :class:`~discord.Role`'s, that should not be affected by the rule.
28492850
exempt_channels: List[:class:`.Snowflake`]
2850-
Up to 50 :class:`~discord.TextChannel`/:class:`~discord.VoiceChannel`'s, that should not be affected by the rule
2851-
2852-
Returns
2853-
--------
2854-
:class:`~discord.AutoModRule`
2855-
The AutoMod rule created
2851+
Up to 50 :class:`~discord.TextChannel`/:class:`~discord.VoiceChannel`'s, that should not be affected by the rule.
2852+
reason: Optional[:class:`str`]
2853+
The reason for creating the rule. Shows up in the audit log.
28562854
28572855
Raises
28582856
------
28592857
:exc:`discord.Forbidden`
28602858
The bot is missing permissions to create AutoMod rules
28612859
:exc:`~discord.HTTPException`
28622860
Creating the rule failed
2861+
2862+
Returns
2863+
--------
2864+
:class:`~discord.AutoModRule`
2865+
The AutoMod rule created
28632866
"""
28642867
data = {
28652868
'name': name,
@@ -2870,12 +2873,12 @@ async def create_automod_rule(self,
28702873
'enabled': enabled,
28712874
'exempt_roles': [str(r.id) for r in exempt_roles]
28722875
}
2873-
except_channels = [str(c.id) for c in exempt_channels]
2876+
exempt_channels = [str(c.id) for c in exempt_channels]
28742877
for action in actions: # Add the channels where messages should be logged to, to the exempted channels
2875-
if action.type.send_alert_message and str(action.channel_id) not in except_channels:
2876-
except_channels.append(str(action.channel_id))
2877-
data['exempt_channels'] = except_channels
2878-
rule_data = await self._state.http.create_automod_rule(guild_id=self.id, data=data)
2878+
if action.type.send_alert_message and str(action.channel_id) not in exempt_channels:
2879+
exempt_channels.append(str(action.channel_id))
2880+
data['exempt_channels'] = exempt_channels
2881+
rule_data = await self._state.http.create_automod_rule(guild_id=self.id, data=data, reason=reason)
28792882
rule = AutoModRule(state=self._state, guild=self, data=rule_data)
28802883
self._add_automod_rule(rule)
28812884
return rule

discord/http.py

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1284,14 +1284,17 @@ def get_automod_rules(self, guild_id: int):
12841284
def get_automod_rule(self, guild_id: int, rule_id: int):
12851285
return self.request(Route('GET', '/guilds/{guild_id}/auto-moderation/rules/{rule_id}', guild_id=guild_id, rule_id=rule_id))
12861286

1287-
def create_automod_rule(self, guild_id: int, data: dict):
1288-
return self.request(Route('POST', '/guilds/{guild_id}/auto-moderation/rules', guild_id=guild_id), json=data)
1287+
def create_automod_rule(self, guild_id: int, data: dict, reason: str = None):
1288+
r = Route('POST', '/guilds/{guild_id}/auto-moderation/rules', guild_id=guild_id)
1289+
return self.request(r, json=data, reason=reason)
12891290

1290-
def edit_automod_rule(self, guild_id: int, rule_id: int, data: dict):
1291-
return self.request(Route('PATCH', '/guilds/{guild_id}/auto-moderation/rules/{rule_id}', guild_id=guild_id, rule_id=rule_id), json=data)
1291+
def edit_automod_rule(self, guild_id: int, rule_id: int, data: dict, reason: str = None):
1292+
r = Route('PATCH', '/guilds/{guild_id}/auto-moderation/rules/{rule_id}', guild_id=guild_id, rule_id=rule_id)
1293+
return self.request(r, json=data, reason=reason)
12921294

1293-
def delete_automod_rule(self, guild_id: int, rule_id: int):
1294-
return self.request(Route('DELETE', '/guilds/{guild_id}/auto-moderation/rules/{rule_id}', guild_id=guild_id, rule_id=rule_id))
1295+
def delete_automod_rule(self, guild_id: int, rule_id: int, reason: str = None):
1296+
r = Route('DELETE', '/guilds/{guild_id}/auto-moderation/rules/{rule_id}', guild_id=guild_id, rule_id=rule_id)
1297+
return self.request(r, reason=reason)
12951298

12961299
# Misc
12971300
def application_info(self):

0 commit comments

Comments
 (0)