mirror of
https://github.com/Rapptz/discord.py.git
synced 2025-05-12 16:59:50 +00:00
Implement AutoMod
This commit is contained in:
parent
7ad00750c6
commit
5426d19dc7
@ -67,6 +67,7 @@ from .scheduled_event import *
|
|||||||
from .interactions import *
|
from .interactions import *
|
||||||
from .components import *
|
from .components import *
|
||||||
from .threads import *
|
from .threads import *
|
||||||
|
from .automod import *
|
||||||
|
|
||||||
|
|
||||||
class VersionInfo(NamedTuple):
|
class VersionInfo(NamedTuple):
|
||||||
|
@ -276,6 +276,7 @@ class AuditLogChanges:
|
|||||||
'preferred_locale': (None, _enum_transformer(enums.Locale)),
|
'preferred_locale': (None, _enum_transformer(enums.Locale)),
|
||||||
'image_hash': ('cover_image', _transform_cover_image),
|
'image_hash': ('cover_image', _transform_cover_image),
|
||||||
'app_command_permission_update': ('app_command_permissions', _transform_app_command_permissions),
|
'app_command_permission_update': ('app_command_permissions', _transform_app_command_permissions),
|
||||||
|
'trigger_type': (None, _enum_transformer(enums.AutoModRuleTriggerType)),
|
||||||
}
|
}
|
||||||
# fmt: on
|
# fmt: on
|
||||||
|
|
||||||
@ -394,6 +395,12 @@ class _AuditLogProxyMessageBulkDelete(_AuditLogProxy):
|
|||||||
count: int
|
count: int
|
||||||
|
|
||||||
|
|
||||||
|
class _AuditLogProxyAutoModAction(_AuditLogProxy):
|
||||||
|
automod_rule_name: str
|
||||||
|
automod_rule_trigger_type: str
|
||||||
|
channel: Union[abc.GuildChannel, Thread]
|
||||||
|
|
||||||
|
|
||||||
class AuditLogEntry(Hashable):
|
class AuditLogEntry(Hashable):
|
||||||
r"""Represents an Audit Log entry.
|
r"""Represents an Audit Log entry.
|
||||||
|
|
||||||
@ -469,6 +476,7 @@ class AuditLogEntry(Hashable):
|
|||||||
_AuditLogProxyPinAction,
|
_AuditLogProxyPinAction,
|
||||||
_AuditLogProxyStageInstanceAction,
|
_AuditLogProxyStageInstanceAction,
|
||||||
_AuditLogProxyMessageBulkDelete,
|
_AuditLogProxyMessageBulkDelete,
|
||||||
|
_AuditLogProxyAutoModAction,
|
||||||
Member, User, None, PartialIntegration,
|
Member, User, None, PartialIntegration,
|
||||||
Role, Object
|
Role, Object
|
||||||
] = None
|
] = None
|
||||||
@ -500,6 +508,16 @@ class AuditLogEntry(Hashable):
|
|||||||
channel=self.guild.get_channel_or_thread(channel_id) or Object(id=channel_id),
|
channel=self.guild.get_channel_or_thread(channel_id) or Object(id=channel_id),
|
||||||
message_id=int(extra['message_id']),
|
message_id=int(extra['message_id']),
|
||||||
)
|
)
|
||||||
|
elif self.action is enums.AuditLogAction.automod_block_message:
|
||||||
|
channel_id = int(extra['channel_id'])
|
||||||
|
self.extra = _AuditLogProxyAutoModAction(
|
||||||
|
automod_rule_name=extra['auto_moderation_rule_name'],
|
||||||
|
automod_rule_trigger_type=enums.try_enum(
|
||||||
|
enums.AutoModRuleTriggerType, extra['auto_moderation_rule_trigger_type']
|
||||||
|
),
|
||||||
|
channel=self.guild.get_channel_or_thread(channel_id) or Object(id=channel_id),
|
||||||
|
)
|
||||||
|
|
||||||
elif self.action.name.startswith('overwrite_'):
|
elif self.action.name.startswith('overwrite_'):
|
||||||
# the overwrite_ actions have a dict with some information
|
# the overwrite_ actions have a dict with some information
|
||||||
instance_id = int(extra['id'])
|
instance_id = int(extra['id'])
|
||||||
@ -660,3 +678,6 @@ class AuditLogEntry(Hashable):
|
|||||||
|
|
||||||
def _convert_target_integration_or_app_command(self, target_id: int) -> Union[PartialIntegration, AppCommand, Object]:
|
def _convert_target_integration_or_app_command(self, target_id: int) -> Union[PartialIntegration, AppCommand, Object]:
|
||||||
return self._get_integration_by_app_id(target_id) or self._get_app_command(target_id) or Object(target_id)
|
return self._get_integration_by_app_id(target_id) or self._get_app_command(target_id) or Object(target_id)
|
||||||
|
|
||||||
|
def _convert_target_auto_moderation(self, target_id: int) -> Union[Member, Object]:
|
||||||
|
return self.guild.get_member(target_id) or Object(target_id)
|
||||||
|
487
discord/automod.py
Normal file
487
discord/automod.py
Normal file
@ -0,0 +1,487 @@
|
|||||||
|
"""
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2015-present Rapptz
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
to deal in the Software without restriction, including without limitation
|
||||||
|
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
Software is furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||||
|
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
DEALINGS IN THE SOFTWARE.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
import datetime
|
||||||
|
|
||||||
|
from typing import TYPE_CHECKING, Any, Dict, Optional, List, Sequence, Set, Union, Sequence
|
||||||
|
|
||||||
|
|
||||||
|
from .enums import AutoModRuleTriggerType, AutoModRuleActionType, AutoModRuleEventType, try_enum
|
||||||
|
from .flags import AutoModPresets
|
||||||
|
from . import utils
|
||||||
|
from .utils import MISSING, cached_slot_property
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from typing_extensions import Self
|
||||||
|
from .abc import Snowflake, GuildChannel
|
||||||
|
from .threads import Thread
|
||||||
|
from .guild import Guild
|
||||||
|
from .member import Member
|
||||||
|
from .state import ConnectionState
|
||||||
|
from .types.automod import (
|
||||||
|
AutoModerationRule as AutoModerationRulePayload,
|
||||||
|
AutoModerationTriggerMetadata as AutoModerationTriggerMetadataPayload,
|
||||||
|
AutoModerationAction as AutoModerationActionPayload,
|
||||||
|
AutoModerationActionExecution as AutoModerationActionExecutionPayload,
|
||||||
|
)
|
||||||
|
from .role import Role
|
||||||
|
|
||||||
|
__all__ = (
|
||||||
|
'AutoModRuleAction',
|
||||||
|
'AutoModTrigger',
|
||||||
|
'AutoModRule',
|
||||||
|
'AutoModAction',
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class AutoModRuleAction:
|
||||||
|
"""Represents an auto moderation's rule action.
|
||||||
|
|
||||||
|
.. versionadded:: 2.0
|
||||||
|
|
||||||
|
Attributes
|
||||||
|
-----------
|
||||||
|
type: :class:`AutoModRuleActionType`
|
||||||
|
The type of action to take.
|
||||||
|
channel_id: Optional[:class:`int`]
|
||||||
|
The ID of the channel to send the alert message to, if any.
|
||||||
|
duration: Optional[:class:`datetime.timedelta`]
|
||||||
|
The duration of the timeout to apply, if any.
|
||||||
|
Has a maximum of 28 days.
|
||||||
|
"""
|
||||||
|
|
||||||
|
__slots__ = ('type', 'channel_id', 'duration')
|
||||||
|
|
||||||
|
def __init__(self, *, channel_id: Optional[int] = None, duration: Optional[datetime.timedelta] = None) -> None:
|
||||||
|
self.channel_id: Optional[int] = channel_id
|
||||||
|
self.duration: Optional[datetime.timedelta] = duration
|
||||||
|
if channel_id and duration:
|
||||||
|
raise ValueError('Please provide only one of ``channel`` or ``duration``')
|
||||||
|
|
||||||
|
if channel_id:
|
||||||
|
self.type = AutoModRuleActionType.send_alert_message
|
||||||
|
elif duration:
|
||||||
|
self.type = AutoModRuleActionType.timeout
|
||||||
|
else:
|
||||||
|
self.type = AutoModRuleActionType.block_message
|
||||||
|
|
||||||
|
def __repr__(self) -> str:
|
||||||
|
return f'<AutoModRuleAction type={self.type.value} channel={self.channel_id} duration={self.duration}>'
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_data(cls, data: AutoModerationActionPayload) -> Self:
|
||||||
|
type_ = try_enum(AutoModRuleActionType, data['type'])
|
||||||
|
if data['type'] == AutoModRuleActionType.timeout.value:
|
||||||
|
duration_seconds = data['metadata']['duration_seconds']
|
||||||
|
return cls(duration=datetime.timedelta(seconds=duration_seconds))
|
||||||
|
elif data['type'] == AutoModRuleActionType.send_alert_message.value:
|
||||||
|
channel_id = int(data['metadata']['channel_id'])
|
||||||
|
return cls(channel_id=channel_id)
|
||||||
|
return cls()
|
||||||
|
|
||||||
|
def to_dict(self) -> Dict[str, Any]:
|
||||||
|
ret = {'type': self.type.value, 'metadata': {}}
|
||||||
|
if self.type is AutoModRuleActionType.timeout:
|
||||||
|
ret['metadata'] = {'duration_seconds': int(self.duration.total_seconds())} # type: ignore # duration cannot be None here
|
||||||
|
elif self.type is AutoModRuleActionType.send_alert_message:
|
||||||
|
ret['metadata'] = {'channel_id': str(self.channel_id)}
|
||||||
|
return ret
|
||||||
|
|
||||||
|
|
||||||
|
class AutoModTrigger:
|
||||||
|
"""Represents a trigger for an auto moderation rule.
|
||||||
|
|
||||||
|
.. versionadded:: 2.0
|
||||||
|
|
||||||
|
Attributes
|
||||||
|
-----------
|
||||||
|
type: :class:`AutoModRuleTriggerType`
|
||||||
|
The type of trigger.
|
||||||
|
keyword_filter: Optional[List[:class:`str`]]
|
||||||
|
The list of strings that will trigger the keyword filter.
|
||||||
|
presets: Optional[:class:`AutoModPresets`]
|
||||||
|
The presets used with the preset keyword filter.
|
||||||
|
"""
|
||||||
|
|
||||||
|
__slots__ = ('type', 'keyword_filter', 'presets')
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
*,
|
||||||
|
keyword_filter: Optional[List[str]] = None,
|
||||||
|
presets: Optional[AutoModPresets] = None,
|
||||||
|
) -> None:
|
||||||
|
self.keyword_filter: Optional[List[str]] = keyword_filter
|
||||||
|
self.presets: Optional[AutoModPresets] = presets
|
||||||
|
if keyword_filter and presets:
|
||||||
|
raise ValueError('Please pass only one of keyword_filter or presets.')
|
||||||
|
|
||||||
|
if self.keyword_filter is not None:
|
||||||
|
self.type = AutoModRuleTriggerType.keyword
|
||||||
|
else:
|
||||||
|
self.type = AutoModRuleTriggerType.keyword_preset
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_data(cls, type: int, data: Optional[AutoModerationTriggerMetadataPayload]) -> Self:
|
||||||
|
type_ = try_enum(AutoModRuleTriggerType, type)
|
||||||
|
if type_ is AutoModRuleTriggerType.keyword:
|
||||||
|
return cls(keyword_filter=data['keyword_filter']) # type: ignore # unable to typeguard due to outer payload
|
||||||
|
else:
|
||||||
|
return cls(presets=AutoModPresets._from_value(data['presets'])) # type: ignore # unable to typeguard due to outer payload
|
||||||
|
|
||||||
|
def to_metadata_dict(self) -> Dict[str, Any]:
|
||||||
|
if self.keyword_filter is not None:
|
||||||
|
return {'keyword_filter': self.keyword_filter}
|
||||||
|
elif self.presets is not None:
|
||||||
|
return {'presets': self.presets.to_array()}
|
||||||
|
|
||||||
|
return {}
|
||||||
|
|
||||||
|
|
||||||
|
class AutoModRule:
|
||||||
|
"""Represents an auto moderation rule.
|
||||||
|
|
||||||
|
.. versionadded:: 2.0
|
||||||
|
|
||||||
|
Attributes
|
||||||
|
-----------
|
||||||
|
id: :class:`int`
|
||||||
|
The ID of the rule.
|
||||||
|
guild: :class:`Guild`
|
||||||
|
The guild the rule is for.
|
||||||
|
name: :class:`str`
|
||||||
|
The name of the rule.
|
||||||
|
creator_id: :class:`int`
|
||||||
|
The ID of the user that created the rule.
|
||||||
|
trigger: :class:`AutoModTrigger`
|
||||||
|
The rule's trigger.
|
||||||
|
enabled: :class:`bool`
|
||||||
|
Whether the rule is enabled.
|
||||||
|
exempt_role_ids: Set[:class:`int`]
|
||||||
|
The IDs of the roles that are exempt from the rule.
|
||||||
|
exempt_channel_ids: Set[:class:`int`]
|
||||||
|
The IDs of the channels that are exempt from the rule.
|
||||||
|
"""
|
||||||
|
|
||||||
|
__slots__ = (
|
||||||
|
'_state',
|
||||||
|
'_cs_exempt_roles',
|
||||||
|
'_cs_exempt_channels',
|
||||||
|
'_cs_actions',
|
||||||
|
'id',
|
||||||
|
'guild',
|
||||||
|
'name',
|
||||||
|
'creator_id',
|
||||||
|
'event_type',
|
||||||
|
'trigger',
|
||||||
|
'enabled',
|
||||||
|
'exempt_role_ids',
|
||||||
|
'exempt_channel_ids',
|
||||||
|
'_actions',
|
||||||
|
)
|
||||||
|
|
||||||
|
def __init__(self, *, data: AutoModerationRulePayload, guild: Guild, state: ConnectionState) -> None:
|
||||||
|
self._state: ConnectionState = state
|
||||||
|
self.guild: Guild = guild
|
||||||
|
self.id: int = int(data['id'])
|
||||||
|
self.name: str = data['name']
|
||||||
|
self.creator_id = int(data['creator_id'])
|
||||||
|
self.event_type: AutoModRuleEventType = try_enum(AutoModRuleEventType, data['event_type'])
|
||||||
|
self.trigger: AutoModTrigger = AutoModTrigger.from_data(data['trigger_type'], data=data.get('trigger_metadata'))
|
||||||
|
self.enabled: bool = data['enabled']
|
||||||
|
self.exempt_role_ids: Set[int] = {int(role_id) for role_id in data['exempt_roles']}
|
||||||
|
self.exempt_channel_ids: Set[int] = {int(channel_id) for channel_id in data['exempt_channels']}
|
||||||
|
self._actions: List[AutoModerationActionPayload] = data['actions']
|
||||||
|
|
||||||
|
def __repr__(self) -> str:
|
||||||
|
return f'<AutoModRule id={self.id} name={self.name!r} guild={self.guild!r}>'
|
||||||
|
|
||||||
|
def to_dict(self) -> AutoModerationRulePayload:
|
||||||
|
ret: AutoModerationRulePayload = {
|
||||||
|
'id': str(self.id),
|
||||||
|
'guild_id': str(self.guild.id),
|
||||||
|
'name': self.name,
|
||||||
|
'creator_id': str(self.creator_id),
|
||||||
|
'event_type': self.event_type.value,
|
||||||
|
'trigger_type': self.trigger.type.value,
|
||||||
|
'trigger_metadata': self.trigger.to_metadata_dict(),
|
||||||
|
'actions': [action.to_dict() for action in self.actions],
|
||||||
|
'enabled': self.enabled,
|
||||||
|
'exempt_roles': [str(role_id) for role_id in self.exempt_role_ids],
|
||||||
|
'exempt_channels': [str(channel_id) for channel_id in self.exempt_channel_ids],
|
||||||
|
} # type: ignore # trigger types break the flow here.
|
||||||
|
|
||||||
|
return ret
|
||||||
|
|
||||||
|
@property
|
||||||
|
def creator(self) -> Optional[Member]:
|
||||||
|
"""Optional[:class:`Member`]: The member that created this rule."""
|
||||||
|
return self.guild.get_member(self.creator_id)
|
||||||
|
|
||||||
|
@cached_slot_property('_cs_exempt_roles')
|
||||||
|
def exempt_roles(self) -> List[Role]:
|
||||||
|
"""List[:class:`Role`]: The roles that are exempt from this rule."""
|
||||||
|
result = []
|
||||||
|
get_role = self.guild.get_role
|
||||||
|
for role_id in self.exempt_role_ids:
|
||||||
|
role = get_role(role_id)
|
||||||
|
if role is not None:
|
||||||
|
result.append(role)
|
||||||
|
|
||||||
|
return utils._unique(result)
|
||||||
|
|
||||||
|
@cached_slot_property('_cs_exempt_channels')
|
||||||
|
def exempt_channels(self) -> List[Union[GuildChannel, Thread]]:
|
||||||
|
"""List[Union[:class:`abc.GuildChannel`, :class:`Thread`]]: The channels that are exempt from this rule."""
|
||||||
|
it = filter(None, map(self.guild._resolve_channel, self.exempt_channel_ids))
|
||||||
|
return utils._unique(it)
|
||||||
|
|
||||||
|
@cached_slot_property('_cs_actions')
|
||||||
|
def actions(self) -> List[AutoModRuleAction]:
|
||||||
|
"""List[:class:`AutoModRuleAction`]: The actions that are taken when this rule is triggered."""
|
||||||
|
return [AutoModRuleAction.from_data(action) for action in self._actions]
|
||||||
|
|
||||||
|
def is_exempt(self, obj: Snowflake, /) -> bool:
|
||||||
|
"""Check if an object is exempt from the automod rule.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
-----------
|
||||||
|
obj: :class:`abc.Snowflake`
|
||||||
|
The role, channel, or thread to check.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
--------
|
||||||
|
:class:`bool`
|
||||||
|
Whether the object is exempt from the automod rule.
|
||||||
|
"""
|
||||||
|
return obj.id in self.exempt_channel_ids or obj.id in self.exempt_role_ids
|
||||||
|
|
||||||
|
async def edit(
|
||||||
|
self,
|
||||||
|
*,
|
||||||
|
name: str = MISSING,
|
||||||
|
event_type: AutoModRuleEventType = MISSING,
|
||||||
|
actions: List[AutoModRuleAction] = MISSING,
|
||||||
|
trigger: AutoModTrigger = MISSING,
|
||||||
|
enabled: bool = MISSING,
|
||||||
|
exempt_roles: Sequence[Snowflake] = MISSING,
|
||||||
|
exempt_channels: Sequence[Snowflake] = MISSING,
|
||||||
|
reason: str = MISSING,
|
||||||
|
) -> Self:
|
||||||
|
"""|coro|
|
||||||
|
|
||||||
|
Edits this auto moderation rule.
|
||||||
|
|
||||||
|
You must have :attr:`Permissions.manage_guild` to edit rules.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
-----------
|
||||||
|
name: :class:`str`
|
||||||
|
The new name to change to.
|
||||||
|
event_type: :class:`AutoModRuleEventType`
|
||||||
|
The new event type to change to.
|
||||||
|
actions: List[:class:`AutoModRuleAction`]
|
||||||
|
The new rule actions to update.
|
||||||
|
trigger: :class:`AutoModTrigger`
|
||||||
|
The new trigger to update.
|
||||||
|
You can only change the trigger metadata, not the type.
|
||||||
|
enabled: :class:`bool`
|
||||||
|
Whether the rule should be enabled or not.
|
||||||
|
exempt_roles: Sequence[:class:`abc.Snowflake`]
|
||||||
|
The new roles to exempt from the rule.
|
||||||
|
exempt_channels: Sequence[:class:`abc.Snowflake`]
|
||||||
|
The new channels to exempt from the rule.
|
||||||
|
reason: :class:`str`
|
||||||
|
The reason for updating this rule. Shows up on the audit log.
|
||||||
|
|
||||||
|
Raises
|
||||||
|
-------
|
||||||
|
Forbidden
|
||||||
|
You do not have permission to edit this rule.
|
||||||
|
HTTPException
|
||||||
|
Editing the rule failed.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
--------
|
||||||
|
:class:`AutoModRule`
|
||||||
|
The updated auto moderation rule.
|
||||||
|
"""
|
||||||
|
payload = {}
|
||||||
|
if actions is not MISSING:
|
||||||
|
payload['actions'] = [action.to_dict() for action in actions]
|
||||||
|
|
||||||
|
if name is not MISSING:
|
||||||
|
payload['name'] = name
|
||||||
|
|
||||||
|
if event_type is not MISSING:
|
||||||
|
payload['event_type'] = event_type
|
||||||
|
|
||||||
|
if trigger is not MISSING:
|
||||||
|
payload['trigger_metadata'] = trigger.to_metadata_dict()
|
||||||
|
|
||||||
|
if enabled is not MISSING:
|
||||||
|
payload['enabled'] = enabled
|
||||||
|
|
||||||
|
if exempt_roles is not MISSING:
|
||||||
|
payload['exempt_roles'] = exempt_roles
|
||||||
|
|
||||||
|
if exempt_channels is not MISSING:
|
||||||
|
payload['exempt_channels'] = exempt_channels
|
||||||
|
|
||||||
|
data = await self._state.http.edit_auto_moderation_rule(
|
||||||
|
self.guild.id,
|
||||||
|
self.id,
|
||||||
|
reason=reason,
|
||||||
|
**payload,
|
||||||
|
)
|
||||||
|
|
||||||
|
return AutoModRule(data=data, guild=self.guild, state=self._state)
|
||||||
|
|
||||||
|
async def delete(self, *, reason: str = MISSING) -> None:
|
||||||
|
"""|coro|
|
||||||
|
|
||||||
|
Deletes the auto moderation rule.
|
||||||
|
|
||||||
|
You must have :attr:`Permissions.manage_guild` to delete rules.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
-----------
|
||||||
|
reason: :class:`str`
|
||||||
|
The reason for deleting this rule. Shows up on the audit log.
|
||||||
|
|
||||||
|
Raises
|
||||||
|
-------
|
||||||
|
Forbidden
|
||||||
|
You do not have permissions to delete the rule.
|
||||||
|
HTTPException
|
||||||
|
Deleting the rule failed.
|
||||||
|
"""
|
||||||
|
await self._state.http.delete_auto_moderation_rule(self.guild.id, self.id, reason=reason)
|
||||||
|
|
||||||
|
|
||||||
|
class AutoModAction:
|
||||||
|
"""Represents an action that was taken as the result of a moderation rule.
|
||||||
|
|
||||||
|
.. versionadded:: 2.0
|
||||||
|
|
||||||
|
Attributes
|
||||||
|
-----------
|
||||||
|
action: :class:`AutoModRuleAction`
|
||||||
|
The action that was taken.
|
||||||
|
message_id: Optional[:class:`int`]
|
||||||
|
The message ID that triggered the action.
|
||||||
|
rule_id: :class:`int`
|
||||||
|
The ID of the rule that was triggered.
|
||||||
|
rule_trigger_type: :class:`AutoModRuleTriggerType`
|
||||||
|
The trigger type of the rule that was triggered.
|
||||||
|
guild_id: :class:`int`
|
||||||
|
The ID of the guild where the rule was triggered.
|
||||||
|
user_id: :class:`int`
|
||||||
|
The ID of the user that triggered the rule.
|
||||||
|
channel_id: :class:`int`
|
||||||
|
The ID of the channel where the rule was triggered.
|
||||||
|
alert_system_message_id: Optional[:class:`int`]
|
||||||
|
The ID of the system message that was sent to the predefined alert channel.
|
||||||
|
content: :class:`str`
|
||||||
|
The content of the message that triggered the rule.
|
||||||
|
Requires the :attr:`Intents.message_content` or it will always return an empty string.
|
||||||
|
matched_keyword: Optional[:class:`str`]
|
||||||
|
The matched keyword from the triggering message.
|
||||||
|
matched_content: Optional[:class:`str`]
|
||||||
|
The matched content from the triggering message.
|
||||||
|
Requires the :attr:`Intents.message_content` or it will always return an empty string.
|
||||||
|
"""
|
||||||
|
|
||||||
|
__slots__ = (
|
||||||
|
'_state',
|
||||||
|
'action',
|
||||||
|
'rule_id',
|
||||||
|
'rule_trigger_type',
|
||||||
|
'guild_id',
|
||||||
|
'user_id',
|
||||||
|
'channel_id',
|
||||||
|
'message_id',
|
||||||
|
'alert_system_message_id',
|
||||||
|
'content',
|
||||||
|
'matched_keyword',
|
||||||
|
'matched_content',
|
||||||
|
)
|
||||||
|
|
||||||
|
def __init__(self, *, data: AutoModerationActionExecutionPayload, state: ConnectionState) -> None:
|
||||||
|
self._state: ConnectionState = state
|
||||||
|
self.message_id: Optional[int] = utils._get_as_snowflake(data, 'message_id')
|
||||||
|
self.action: AutoModRuleAction = AutoModRuleAction.from_data(data['action'])
|
||||||
|
self.rule_id: int = int(data['rule_id'])
|
||||||
|
self.rule_trigger_type: AutoModRuleTriggerType = try_enum(AutoModRuleTriggerType, data['rule_trigger_type'])
|
||||||
|
self.guild_id: int = int(data['guild_id'])
|
||||||
|
self.channel_id: Optional[int] = utils._get_as_snowflake(data, 'channel_id')
|
||||||
|
self.user_id: int = int(data['user_id'])
|
||||||
|
self.alert_system_message_id: Optional[int] = utils._get_as_snowflake(data, 'alert_system_message_id')
|
||||||
|
self.content: str = data['content']
|
||||||
|
self.matched_keyword: Optional[str] = data['matched_keyword']
|
||||||
|
self.matched_content: Optional[str] = data['matched_content']
|
||||||
|
|
||||||
|
def __repr__(self) -> str:
|
||||||
|
return f'<AutoModRuleExecution rule_id={self.rule_id} action={self.action!r}>'
|
||||||
|
|
||||||
|
@property
|
||||||
|
def guild(self) -> Guild:
|
||||||
|
""":class:`Guild`: The guild this action was taken in."""
|
||||||
|
return self._state._get_or_create_unavailable_guild(self.guild_id)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def channel(self) -> Optional[Union[GuildChannel, Thread]]:
|
||||||
|
"""Optional[Union[:class:`abc.GuildChannel`, :class:`Thread`]]: The channel this action was taken in."""
|
||||||
|
if self.channel_id:
|
||||||
|
return self.guild.get_channel(self.channel_id)
|
||||||
|
return None
|
||||||
|
|
||||||
|
@property
|
||||||
|
def member(self) -> Optional[Member]:
|
||||||
|
"""Optional[:class:`Member`]: The member this action was taken against /who triggered this rule."""
|
||||||
|
return self.guild.get_member(self.user_id)
|
||||||
|
|
||||||
|
async def fetch_rule(self) -> AutoModRule:
|
||||||
|
"""|coro|
|
||||||
|
|
||||||
|
Fetch the rule whose action was taken.
|
||||||
|
|
||||||
|
You must have the :attr:`Permissions.manage_guild` permission to use this.
|
||||||
|
|
||||||
|
Raises
|
||||||
|
-------
|
||||||
|
Forbidden
|
||||||
|
You do not have permissions to view the rule.
|
||||||
|
HTTPException
|
||||||
|
Fetching the rule failed.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
--------
|
||||||
|
:class:`AutoModRule`
|
||||||
|
The rule that was executed.
|
||||||
|
"""
|
||||||
|
|
||||||
|
data = await self._state.http.get_auto_moderation_rule(self.guild.id, self.rule_id)
|
||||||
|
return AutoModRule(data=data, guild=self.guild, state=self._state)
|
@ -63,6 +63,9 @@ __all__ = (
|
|||||||
'AppCommandType',
|
'AppCommandType',
|
||||||
'AppCommandOptionType',
|
'AppCommandOptionType',
|
||||||
'AppCommandPermissionType',
|
'AppCommandPermissionType',
|
||||||
|
'AutoModRuleTriggerType',
|
||||||
|
'AutoModRuleEventType',
|
||||||
|
'AutoModRuleActionType',
|
||||||
)
|
)
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
@ -227,6 +230,7 @@ class MessageType(Enum):
|
|||||||
thread_starter_message = 21
|
thread_starter_message = 21
|
||||||
guild_invite_reminder = 22
|
guild_invite_reminder = 22
|
||||||
context_menu_command = 23
|
context_menu_command = 23
|
||||||
|
auto_moderation_action = 24
|
||||||
|
|
||||||
|
|
||||||
class SpeakingState(Enum):
|
class SpeakingState(Enum):
|
||||||
@ -347,6 +351,10 @@ class AuditLogAction(Enum):
|
|||||||
thread_update = 111
|
thread_update = 111
|
||||||
thread_delete = 112
|
thread_delete = 112
|
||||||
app_command_permission_update = 121
|
app_command_permission_update = 121
|
||||||
|
automod_rule_create = 140
|
||||||
|
automod_rule_update = 141
|
||||||
|
automod_rule_delete = 142
|
||||||
|
automod_block_message = 143
|
||||||
# fmt: on
|
# fmt: on
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@ -401,6 +409,10 @@ class AuditLogAction(Enum):
|
|||||||
AuditLogAction.thread_delete: AuditLogActionCategory.delete,
|
AuditLogAction.thread_delete: AuditLogActionCategory.delete,
|
||||||
AuditLogAction.thread_update: AuditLogActionCategory.update,
|
AuditLogAction.thread_update: AuditLogActionCategory.update,
|
||||||
AuditLogAction.app_command_permission_update: AuditLogActionCategory.update,
|
AuditLogAction.app_command_permission_update: AuditLogActionCategory.update,
|
||||||
|
AuditLogAction.automod_rule_create: AuditLogActionCategory.create,
|
||||||
|
AuditLogAction.automod_rule_update: AuditLogActionCategory.update,
|
||||||
|
AuditLogAction.automod_rule_delete: AuditLogActionCategory.delete,
|
||||||
|
AuditLogAction.automod_block_message: None,
|
||||||
}
|
}
|
||||||
# fmt: on
|
# fmt: on
|
||||||
return lookup[self]
|
return lookup[self]
|
||||||
@ -440,6 +452,8 @@ class AuditLogAction(Enum):
|
|||||||
return 'thread'
|
return 'thread'
|
||||||
elif v < 122:
|
elif v < 122:
|
||||||
return 'integration_or_app_command'
|
return 'integration_or_app_command'
|
||||||
|
elif v < 144:
|
||||||
|
return 'auto_moderation'
|
||||||
|
|
||||||
|
|
||||||
class UserFlags(Enum):
|
class UserFlags(Enum):
|
||||||
@ -689,6 +703,23 @@ class AppCommandPermissionType(Enum):
|
|||||||
channel = 3
|
channel = 3
|
||||||
|
|
||||||
|
|
||||||
|
class AutoModRuleTriggerType(Enum):
|
||||||
|
keyword = 1
|
||||||
|
harmful_link = 2
|
||||||
|
spam = 3
|
||||||
|
keyword_preset = 4
|
||||||
|
|
||||||
|
|
||||||
|
class AutoModRuleEventType(Enum):
|
||||||
|
message_send = 1
|
||||||
|
|
||||||
|
|
||||||
|
class AutoModRuleActionType(Enum):
|
||||||
|
block_message = 1
|
||||||
|
send_alert_message = 2
|
||||||
|
timeout = 3
|
||||||
|
|
||||||
|
|
||||||
def create_unknown_value(cls: Type[E], val: Any) -> E:
|
def create_unknown_value(cls: Type[E], val: Any) -> E:
|
||||||
value_cls = cls._enum_value_cls_ # type: ignore # This is narrowed below
|
value_cls = cls._enum_value_cls_ # type: ignore # This is narrowed below
|
||||||
name = f'unknown_{val}'
|
name = f'unknown_{val}'
|
||||||
|
133
discord/flags.py
133
discord/flags.py
@ -24,6 +24,7 @@ DEALINGS IN THE SOFTWARE.
|
|||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from functools import reduce
|
||||||
from typing import TYPE_CHECKING, Any, Callable, ClassVar, Dict, Iterator, List, Optional, Tuple, Type, TypeVar, overload
|
from typing import TYPE_CHECKING, Any, Callable, ClassVar, Dict, Iterator, List, Optional, Tuple, Type, TypeVar, overload
|
||||||
|
|
||||||
from .enums import UserFlags
|
from .enums import UserFlags
|
||||||
@ -40,6 +41,7 @@ __all__ = (
|
|||||||
'MemberCacheFlags',
|
'MemberCacheFlags',
|
||||||
'ApplicationFlags',
|
'ApplicationFlags',
|
||||||
'ChannelFlags',
|
'ChannelFlags',
|
||||||
|
'AutoModPresets',
|
||||||
)
|
)
|
||||||
|
|
||||||
BF = TypeVar('BF', bound='BaseFlags')
|
BF = TypeVar('BF', bound='BaseFlags')
|
||||||
@ -655,8 +657,7 @@ class Intents(BaseFlags):
|
|||||||
@classmethod
|
@classmethod
|
||||||
def all(cls: Type[Intents]) -> Intents:
|
def all(cls: Type[Intents]) -> Intents:
|
||||||
"""A factory method that creates a :class:`Intents` with everything enabled."""
|
"""A factory method that creates a :class:`Intents` with everything enabled."""
|
||||||
bits = max(cls.VALID_FLAGS.values()).bit_length()
|
value = reduce(lambda a, b: a | b, cls.VALID_FLAGS.values())
|
||||||
value = (1 << bits) - 1
|
|
||||||
self = cls.__new__(cls)
|
self = cls.__new__(cls)
|
||||||
self.value = value
|
self.value = value
|
||||||
return self
|
return self
|
||||||
@ -1104,6 +1105,31 @@ class Intents(BaseFlags):
|
|||||||
"""
|
"""
|
||||||
return 1 << 16
|
return 1 << 16
|
||||||
|
|
||||||
|
@flag_value
|
||||||
|
def auto_moderation_configuration(self):
|
||||||
|
""":class:`bool`: Whether auto moderation configuration related events are enabled.
|
||||||
|
|
||||||
|
This corresponds to the following events:
|
||||||
|
|
||||||
|
- :func:`on_automod_rule_create`
|
||||||
|
- :func:`on_automod_rule_update`
|
||||||
|
- :func:`on_automod_rule_delete`
|
||||||
|
|
||||||
|
.. versionadded:: 2.0
|
||||||
|
"""
|
||||||
|
return 1 << 20
|
||||||
|
|
||||||
|
@flag_value
|
||||||
|
def auto_moderation_execution(self):
|
||||||
|
""":class:`bool`: Whether auto moderation execution related events are enabled.
|
||||||
|
|
||||||
|
This corresponds to the following events:
|
||||||
|
- :func:`on_automod_action`
|
||||||
|
|
||||||
|
.. versionadded:: 2.0
|
||||||
|
"""
|
||||||
|
return 1 << 21
|
||||||
|
|
||||||
|
|
||||||
@fill_with_flags()
|
@fill_with_flags()
|
||||||
class MemberCacheFlags(BaseFlags):
|
class MemberCacheFlags(BaseFlags):
|
||||||
@ -1436,3 +1462,106 @@ class ChannelFlags(BaseFlags):
|
|||||||
def pinned(self):
|
def pinned(self):
|
||||||
""":class:`bool`: Returns ``True`` if the thread is pinned to the forum channel."""
|
""":class:`bool`: Returns ``True`` if the thread is pinned to the forum channel."""
|
||||||
return 1 << 1
|
return 1 << 1
|
||||||
|
|
||||||
|
|
||||||
|
class ArrayFlags(BaseFlags):
|
||||||
|
@classmethod
|
||||||
|
def _from_value(cls: Type[Self], value: List[int]) -> Self:
|
||||||
|
self = cls.__new__(cls)
|
||||||
|
self.value = reduce(lambda a, b: a | (1 << b - 1), value)
|
||||||
|
return self
|
||||||
|
|
||||||
|
def to_array(self) -> List[int]:
|
||||||
|
return [i + 1 for i in range(self.value.bit_length()) if self.value & (1 << i)]
|
||||||
|
|
||||||
|
|
||||||
|
@fill_with_flags()
|
||||||
|
class AutoModPresets(ArrayFlags):
|
||||||
|
r"""Wraps up the Discord :class:`AutoModRule` presets.
|
||||||
|
|
||||||
|
.. versionadded:: 2.0
|
||||||
|
|
||||||
|
|
||||||
|
.. container:: operations
|
||||||
|
|
||||||
|
.. describe:: x == y
|
||||||
|
|
||||||
|
Checks if two AutoMod preset flags are equal.
|
||||||
|
|
||||||
|
.. describe:: x != y
|
||||||
|
|
||||||
|
Checks if two AutoMod preset flags are not equal.
|
||||||
|
|
||||||
|
.. describe:: x | y, x |= y
|
||||||
|
|
||||||
|
Returns a AutoModPresets instance with all enabled flags from
|
||||||
|
both x and y.
|
||||||
|
|
||||||
|
.. versionadded:: 2.0
|
||||||
|
|
||||||
|
.. describe:: x & y, x &= y
|
||||||
|
|
||||||
|
Returns a AutoModPresets instance with only flags enabled on
|
||||||
|
both x and y.
|
||||||
|
|
||||||
|
.. versionadded:: 2.0
|
||||||
|
|
||||||
|
.. describe:: x ^ y, x ^= y
|
||||||
|
|
||||||
|
Returns a AutoModPresets instance with only flags enabled on
|
||||||
|
only one of x or y, not on both.
|
||||||
|
|
||||||
|
.. versionadded:: 2.0
|
||||||
|
|
||||||
|
.. describe:: ~x
|
||||||
|
|
||||||
|
Returns a AutoModPresets instance with all flags inverted from x.
|
||||||
|
|
||||||
|
.. versionadded:: 2.0
|
||||||
|
|
||||||
|
.. describe:: hash(x)
|
||||||
|
|
||||||
|
Return the flag's hash.
|
||||||
|
.. describe:: iter(x)
|
||||||
|
|
||||||
|
Returns an iterator of ``(name, value)`` pairs. This allows it
|
||||||
|
to be, for example, constructed as a dict or a list of pairs.
|
||||||
|
Note that aliases are not shown.
|
||||||
|
|
||||||
|
Attributes
|
||||||
|
-----------
|
||||||
|
value: :class:`int`
|
||||||
|
The raw value. You should query flags via the properties
|
||||||
|
rather than using this raw value.
|
||||||
|
"""
|
||||||
|
|
||||||
|
@flag_value
|
||||||
|
def profanity(self):
|
||||||
|
""":class:`bool`: Whether to use the preset profanity filter."""
|
||||||
|
return 1 << 0
|
||||||
|
|
||||||
|
@flag_value
|
||||||
|
def sexual_content(self):
|
||||||
|
""":class:`bool`: Whether to use the preset sexual content filter."""
|
||||||
|
return 1 << 1
|
||||||
|
|
||||||
|
@flag_value
|
||||||
|
def slurs(self):
|
||||||
|
""":class:`bool`: Whether to use the preset slurs filter."""
|
||||||
|
return 1 << 2
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def all(cls: Type[Self]) -> Self:
|
||||||
|
"""A factory method that creates a :class:`AutoModPresets` with everything enabled."""
|
||||||
|
bits = max(cls.VALID_FLAGS.values()).bit_length()
|
||||||
|
value = (1 << bits) - 1
|
||||||
|
self = cls.__new__(cls)
|
||||||
|
self.value = value
|
||||||
|
return self
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def none(cls: Type[Self]) -> Self:
|
||||||
|
"""A factory method that creates a :class:`AutoModPresets` with everything disabled."""
|
||||||
|
self = cls.__new__(cls)
|
||||||
|
self.value = self.DEFAULT_VALUE
|
||||||
|
return self
|
||||||
|
123
discord/guild.py
123
discord/guild.py
@ -71,6 +71,7 @@ from .enums import (
|
|||||||
NSFWLevel,
|
NSFWLevel,
|
||||||
MFALevel,
|
MFALevel,
|
||||||
Locale,
|
Locale,
|
||||||
|
AutoModRuleEventType,
|
||||||
)
|
)
|
||||||
from .mixins import Hashable
|
from .mixins import Hashable
|
||||||
from .user import User
|
from .user import User
|
||||||
@ -87,6 +88,7 @@ from .file import File
|
|||||||
from .audit_logs import AuditLogEntry
|
from .audit_logs import AuditLogEntry
|
||||||
from .object import OLDEST_OBJECT, Object
|
from .object import OLDEST_OBJECT, Object
|
||||||
from .welcome_screen import WelcomeScreen, WelcomeChannel
|
from .welcome_screen import WelcomeScreen, WelcomeChannel
|
||||||
|
from .automod import AutoModRule, AutoModTrigger, AutoModRuleAction
|
||||||
|
|
||||||
|
|
||||||
__all__ = (
|
__all__ = (
|
||||||
@ -3833,3 +3835,124 @@ class Guild(Hashable):
|
|||||||
ws = self._state._get_websocket(self.id)
|
ws = self._state._get_websocket(self.id)
|
||||||
channel_id = channel.id if channel else None
|
channel_id = channel.id if channel else None
|
||||||
await ws.voice_state(self.id, channel_id, self_mute, self_deaf)
|
await ws.voice_state(self.id, channel_id, self_mute, self_deaf)
|
||||||
|
|
||||||
|
async def fetch_automod_rule(self, automod_rule_id: int, /) -> AutoModRule:
|
||||||
|
"""|coro|
|
||||||
|
|
||||||
|
Fetches an active automod rule from the guild.
|
||||||
|
|
||||||
|
You must have the :attr:`Permissions.manage_guild` to use this.
|
||||||
|
|
||||||
|
.. versionadded:: 2.0
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
-----------
|
||||||
|
automod_rule_id: :class:`int`
|
||||||
|
The ID of the automod rule to fetch.
|
||||||
|
|
||||||
|
Raises
|
||||||
|
-------
|
||||||
|
Forbidden
|
||||||
|
You do not have permission to view the automod rule.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
--------
|
||||||
|
:class:`AutoModRule`
|
||||||
|
The automod rule that was fetched.
|
||||||
|
"""
|
||||||
|
|
||||||
|
data = await self._state.http.get_auto_moderation_rule(self.id, automod_rule_id)
|
||||||
|
|
||||||
|
return AutoModRule(data=data, guild=self, state=self._state)
|
||||||
|
|
||||||
|
async def fetch_automod_rules(self) -> List[AutoModRule]:
|
||||||
|
"""|coro|
|
||||||
|
|
||||||
|
Fetches all automod rules from the guild.
|
||||||
|
|
||||||
|
You must have the :attr:`Permissions.manage_guild` to use this.
|
||||||
|
|
||||||
|
.. versionadded:: 2.0
|
||||||
|
|
||||||
|
Raises
|
||||||
|
-------
|
||||||
|
Forbidden
|
||||||
|
You do not have permission to view the automod rule.
|
||||||
|
NotFound
|
||||||
|
There are no automod rules within this guild.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
--------
|
||||||
|
List[:class:`AutoModRule`]
|
||||||
|
The automod rules that were fetched.
|
||||||
|
"""
|
||||||
|
data = await self._state.http.get_auto_moderation_rules(self.id)
|
||||||
|
|
||||||
|
return [AutoModRule(data=d, guild=self, state=self._state) for d in data]
|
||||||
|
|
||||||
|
async def create_automod_rule(
|
||||||
|
self,
|
||||||
|
*,
|
||||||
|
name: str,
|
||||||
|
event_type: AutoModRuleEventType,
|
||||||
|
trigger: AutoModTrigger,
|
||||||
|
actions: List[AutoModRuleAction],
|
||||||
|
enabled: bool = MISSING,
|
||||||
|
exempt_roles: Sequence[Snowflake] = MISSING,
|
||||||
|
exempt_channels: Sequence[Snowflake] = MISSING,
|
||||||
|
reason: str = MISSING,
|
||||||
|
) -> AutoModRule:
|
||||||
|
"""|coro|
|
||||||
|
|
||||||
|
Create an automod rule.
|
||||||
|
|
||||||
|
You must have the :attr:`Permissions.manage_guild` permission to use this.
|
||||||
|
|
||||||
|
.. versionadded:: 2.0
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
-----------
|
||||||
|
name: :class:`str`
|
||||||
|
The name of the automod rule.
|
||||||
|
event_type: :class:`AutoModRuleEventType`
|
||||||
|
The type of event that the automod rule will trigger on.
|
||||||
|
trigger: :class:`AutoModTrigger`
|
||||||
|
The trigger that will trigger the automod rule.
|
||||||
|
actions: List[:class:`AutoModRuleAction`]
|
||||||
|
The actions that will be taken when the automod rule is triggered.
|
||||||
|
enabled: :class:`bool`
|
||||||
|
Whether the automod rule is enabled.
|
||||||
|
Discord will default to ``False``.
|
||||||
|
exempt_roles: Sequence[:class:`abc.Snowflake`]
|
||||||
|
A list of roles that will be exempt from the automod rule.
|
||||||
|
exempt_channels: Sequence[:class:`abc.Snowflake`]
|
||||||
|
A list of channels that will be exempt from the automod rule.
|
||||||
|
reason: :class:`str`
|
||||||
|
The reason for creating this automod rule. Shows up on the audit log.
|
||||||
|
|
||||||
|
Raises
|
||||||
|
-------
|
||||||
|
Forbidden
|
||||||
|
You do not have permissions to create an automod rule.
|
||||||
|
HTTPException
|
||||||
|
Creating the automod rule failed.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
--------
|
||||||
|
:class:`AutoModRule`
|
||||||
|
The automod rule that was created.
|
||||||
|
"""
|
||||||
|
data = await self._state.http.create_auto_moderation_rule(
|
||||||
|
self.id,
|
||||||
|
name=name,
|
||||||
|
event_type=event_type.value,
|
||||||
|
trigger_type=trigger.type.value,
|
||||||
|
trigger_metadata=trigger.to_metadata_dict() or None,
|
||||||
|
actions=[a.to_dict() for a in actions],
|
||||||
|
enabled=enabled,
|
||||||
|
exempt_roles=[str(r.id) for r in exempt_roles] if exempt_roles else None,
|
||||||
|
exempt_channel=[str(c.id) for c in exempt_channels] if exempt_channels else None,
|
||||||
|
reason=reason,
|
||||||
|
)
|
||||||
|
|
||||||
|
return AutoModRule(data=data, guild=self, state=self._state)
|
||||||
|
@ -71,6 +71,7 @@ if TYPE_CHECKING:
|
|||||||
from .types import (
|
from .types import (
|
||||||
appinfo,
|
appinfo,
|
||||||
audit_log,
|
audit_log,
|
||||||
|
automod,
|
||||||
channel,
|
channel,
|
||||||
command,
|
command,
|
||||||
emoji,
|
emoji,
|
||||||
@ -2039,6 +2040,63 @@ class HTTPClient:
|
|||||||
)
|
)
|
||||||
return self.request(r, json=payload)
|
return self.request(r, json=payload)
|
||||||
|
|
||||||
|
def get_auto_moderation_rules(self, guild_id: Snowflake) -> Response[List[automod.AutoModerationRule]]:
|
||||||
|
return self.request(Route('GET', '/guilds/{guild_id}/auto-moderation/rules', guild_id=guild_id))
|
||||||
|
|
||||||
|
def get_auto_moderation_rule(self, guild_id: Snowflake, rule_id: Snowflake) -> Response[automod.AutoModerationRule]:
|
||||||
|
return self.request(
|
||||||
|
Route('GET', '/guilds/{guild_id}/auto-moderation/rules/{rule_id}', guild_id=guild_id, rule_id=rule_id)
|
||||||
|
)
|
||||||
|
|
||||||
|
def create_auto_moderation_rule(
|
||||||
|
self, guild_id: Snowflake, *, reason: Optional[str], **payload: Any
|
||||||
|
) -> Response[automod.AutoModerationRule]:
|
||||||
|
valid_keys = (
|
||||||
|
'name',
|
||||||
|
'event_type',
|
||||||
|
'trigger_type',
|
||||||
|
'trigger_metadata',
|
||||||
|
'actions',
|
||||||
|
'enabled',
|
||||||
|
'exempt_roles',
|
||||||
|
'exempt_channels',
|
||||||
|
)
|
||||||
|
|
||||||
|
payload = {k: v for k, v in payload.items() if k in valid_keys and v is not None}
|
||||||
|
|
||||||
|
return self.request(
|
||||||
|
Route('POST', '/guilds/{guild_id}/auto-moderation/rules', guild_id=guild_id), json=payload, reason=reason
|
||||||
|
)
|
||||||
|
|
||||||
|
def edit_auto_moderation_rule(
|
||||||
|
self, guild_id: Snowflake, rule_id: Snowflake, *, reason: Optional[str], **payload: Any
|
||||||
|
) -> Response[automod.AutoModerationRule]:
|
||||||
|
valid_keys = (
|
||||||
|
'name',
|
||||||
|
'event_type',
|
||||||
|
'trigger_metadata',
|
||||||
|
'actions',
|
||||||
|
'enabled',
|
||||||
|
'exempt_roles',
|
||||||
|
'exempt_channels',
|
||||||
|
)
|
||||||
|
|
||||||
|
payload = {k: v for k, v in payload.items() if k in valid_keys and v is not None}
|
||||||
|
|
||||||
|
return self.request(
|
||||||
|
Route('PATCH', '/guilds/{guild_id}/auto-moderation/rules/{rule_id}', guild_id=guild_id, rule_id=rule_id),
|
||||||
|
json=payload,
|
||||||
|
reason=reason,
|
||||||
|
)
|
||||||
|
|
||||||
|
def delete_auto_moderation_rule(
|
||||||
|
self, guild_id: Snowflake, rule_id: Snowflake, *, reason: Optional[str]
|
||||||
|
) -> Response[None]:
|
||||||
|
return self.request(
|
||||||
|
Route('DELETE', '/guilds/{guild_id}/auto-moderation/rules/{rule_id}', guild_id=guild_id, rule_id=rule_id),
|
||||||
|
reason=reason,
|
||||||
|
)
|
||||||
|
|
||||||
# Misc
|
# Misc
|
||||||
|
|
||||||
def application_info(self) -> Response[appinfo.AppInfo]:
|
def application_info(self) -> Response[appinfo.AppInfo]:
|
||||||
|
@ -73,6 +73,7 @@ from .scheduled_event import ScheduledEvent
|
|||||||
from .stage_instance import StageInstance
|
from .stage_instance import StageInstance
|
||||||
from .threads import Thread, ThreadMember
|
from .threads import Thread, ThreadMember
|
||||||
from .sticker import GuildSticker
|
from .sticker import GuildSticker
|
||||||
|
from .automod import AutoModRule, AutoModAction
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from .abc import PrivateChannel
|
from .abc import PrivateChannel
|
||||||
@ -84,6 +85,7 @@ if TYPE_CHECKING:
|
|||||||
from .gateway import DiscordWebSocket
|
from .gateway import DiscordWebSocket
|
||||||
from .app_commands import CommandTree
|
from .app_commands import CommandTree
|
||||||
|
|
||||||
|
from .types.automod import AutoModerationRule, AutoModerationActionExecution
|
||||||
from .types.snowflake import Snowflake
|
from .types.snowflake import Snowflake
|
||||||
from .types.activity import Activity as ActivityPayload
|
from .types.activity import Activity as ActivityPayload
|
||||||
from .types.channel import DMChannel as DMChannelPayload
|
from .types.channel import DMChannel as DMChannelPayload
|
||||||
@ -1079,6 +1081,46 @@ class ConnectionState:
|
|||||||
guild.stickers = tuple(map(lambda d: self.store_sticker(guild, d), data['stickers']))
|
guild.stickers = tuple(map(lambda d: self.store_sticker(guild, d), data['stickers']))
|
||||||
self.dispatch('guild_stickers_update', guild, before_stickers, guild.stickers)
|
self.dispatch('guild_stickers_update', guild, before_stickers, guild.stickers)
|
||||||
|
|
||||||
|
def parse_auto_moderation_rule_create(self, data: AutoModerationRule) -> None:
|
||||||
|
guild = self._get_guild(int(data['guild_id']))
|
||||||
|
if guild is None:
|
||||||
|
_log.debug('AUTO_MODERATION_RULE_CREATE referencing an unknown guild ID: %s. Discarding.', data['guild_id'])
|
||||||
|
return
|
||||||
|
|
||||||
|
rule = AutoModRule(data=data, guild=guild, state=self)
|
||||||
|
|
||||||
|
self.dispatch('automod_rule_create', rule)
|
||||||
|
|
||||||
|
def parse_auto_moderation_rule_update(self, data: AutoModerationRule) -> None:
|
||||||
|
guild = self._get_guild(int(data['guild_id']))
|
||||||
|
if guild is None:
|
||||||
|
_log.debug('AUTO_MODERATION_RULE_UPDATE referencing an unknown guild ID: %s. Discarding.', data['guild_id'])
|
||||||
|
return
|
||||||
|
|
||||||
|
rule = AutoModRule(data=data, guild=guild, state=self)
|
||||||
|
|
||||||
|
self.dispatch('automod_rule_update', rule)
|
||||||
|
|
||||||
|
def parse_auto_moderation_rule_delete(self, data: AutoModerationRule) -> None:
|
||||||
|
guild = self._get_guild(int(data['guild_id']))
|
||||||
|
if guild is None:
|
||||||
|
_log.debug('AUTO_MODERATION_RULE_DELETE referencing an unknown guild ID: %s. Discarding.', data['guild_id'])
|
||||||
|
return
|
||||||
|
|
||||||
|
rule = AutoModRule(data=data, guild=guild, state=self)
|
||||||
|
|
||||||
|
self.dispatch('automod_rule_delete', rule)
|
||||||
|
|
||||||
|
def parse_auto_moderation_action_execution(self, data: AutoModerationActionExecution) -> None:
|
||||||
|
guild = self._get_guild(int(data['guild_id']))
|
||||||
|
if guild is None:
|
||||||
|
_log.debug('AUTO_MODERATION_ACTION_EXECUTION referencing an unknown guild ID: %s. Discarding.', data['guild_id'])
|
||||||
|
return
|
||||||
|
|
||||||
|
execution = AutoModAction(data=data, state=self)
|
||||||
|
|
||||||
|
self.dispatch('automod_action', execution)
|
||||||
|
|
||||||
def _get_create_guild(self, data: gw.GuildCreateEvent) -> Guild:
|
def _get_create_guild(self, data: gw.GuildCreateEvent) -> Guild:
|
||||||
if data.get('unavailable') is False:
|
if data.get('unavailable') is False:
|
||||||
# GUILD_CREATE with unavailable in the response
|
# GUILD_CREATE with unavailable in the response
|
||||||
|
@ -283,6 +283,8 @@ class AuditEntryInfo(TypedDict):
|
|||||||
role_name: str
|
role_name: str
|
||||||
application_id: Snowflake
|
application_id: Snowflake
|
||||||
guild_id: Snowflake
|
guild_id: Snowflake
|
||||||
|
auto_moderation_rule_name: str
|
||||||
|
auto_moderation_rule_trigger_type: str
|
||||||
|
|
||||||
|
|
||||||
class AuditLogEntry(TypedDict):
|
class AuditLogEntry(TypedDict):
|
||||||
|
119
discord/types/automod.py
Normal file
119
discord/types/automod.py
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
"""
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2015-present Rapptz
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
to deal in the Software without restriction, including without limitation
|
||||||
|
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
Software is furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||||
|
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
DEALINGS IN THE SOFTWARE.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from typing import Literal, TypedDict, List, Union, Optional
|
||||||
|
from typing_extensions import NotRequired
|
||||||
|
|
||||||
|
from .snowflake import Snowflake
|
||||||
|
|
||||||
|
AutoModerationRuleTriggerType = Literal[1, 2, 3, 4]
|
||||||
|
AutoModerationActionTriggerType = Literal[1, 2, 3]
|
||||||
|
AutoModerationRuleEventType = Literal[1]
|
||||||
|
AutoModerationTriggerPresets = Literal[1, 2, 3]
|
||||||
|
|
||||||
|
|
||||||
|
class Empty(TypedDict):
|
||||||
|
...
|
||||||
|
|
||||||
|
|
||||||
|
class _AutoModerationActionMetadataAlert(TypedDict):
|
||||||
|
channel_id: Snowflake
|
||||||
|
|
||||||
|
|
||||||
|
class _AutoModerationActionMetadataTimeout(TypedDict):
|
||||||
|
duration_seconds: int
|
||||||
|
|
||||||
|
|
||||||
|
class _AutoModerationActionBlockMessage(TypedDict):
|
||||||
|
type: Literal[1]
|
||||||
|
metadata: NotRequired[Empty]
|
||||||
|
|
||||||
|
|
||||||
|
class _AutoModerationActionAlert(TypedDict):
|
||||||
|
type: Literal[2]
|
||||||
|
metadata: _AutoModerationActionMetadataAlert
|
||||||
|
|
||||||
|
|
||||||
|
class _AutoModerationActionTimeout(TypedDict):
|
||||||
|
type: Literal[3]
|
||||||
|
metadata: _AutoModerationActionMetadataTimeout
|
||||||
|
|
||||||
|
|
||||||
|
AutoModerationAction = Union[_AutoModerationActionBlockMessage, _AutoModerationActionAlert, _AutoModerationActionTimeout]
|
||||||
|
|
||||||
|
|
||||||
|
class _AutoModerationTriggerMetadataKeyword(TypedDict):
|
||||||
|
keyword_filter: List[str]
|
||||||
|
|
||||||
|
|
||||||
|
class _AutoModerationTriggerMetadataKeywordPreset(TypedDict):
|
||||||
|
presets: List[AutoModerationTriggerPresets]
|
||||||
|
|
||||||
|
|
||||||
|
AutoModerationTriggerMetadata = Union[
|
||||||
|
_AutoModerationTriggerMetadataKeyword, _AutoModerationTriggerMetadataKeywordPreset, Empty
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class _BaseAutoModerationRule(TypedDict):
|
||||||
|
id: Snowflake
|
||||||
|
guild_id: Snowflake
|
||||||
|
name: str
|
||||||
|
creator_id: Snowflake
|
||||||
|
event_type: AutoModerationRuleEventType
|
||||||
|
actions: List[AutoModerationAction]
|
||||||
|
enabled: bool
|
||||||
|
exempt_roles: List[Snowflake]
|
||||||
|
exempt_channels: List[Snowflake]
|
||||||
|
|
||||||
|
|
||||||
|
class _AutoModerationRuleKeyword(_BaseAutoModerationRule):
|
||||||
|
trigger_type: Literal[1]
|
||||||
|
trigger_metadata: _AutoModerationTriggerMetadataKeyword
|
||||||
|
|
||||||
|
|
||||||
|
class _AutoModerationRuleKeywordPreset(_BaseAutoModerationRule):
|
||||||
|
trigger_type: Literal[4]
|
||||||
|
trigger_metadata: _AutoModerationTriggerMetadataKeywordPreset
|
||||||
|
|
||||||
|
|
||||||
|
class _AutoModerationRuleOther(_BaseAutoModerationRule):
|
||||||
|
trigger_type: Literal[2, 3]
|
||||||
|
|
||||||
|
|
||||||
|
AutoModerationRule = Union[_AutoModerationRuleKeyword, _AutoModerationRuleKeywordPreset, _AutoModerationRuleOther]
|
||||||
|
|
||||||
|
|
||||||
|
class AutoModerationActionExecution(TypedDict):
|
||||||
|
guild_id: Snowflake
|
||||||
|
action: AutoModerationAction
|
||||||
|
rule_id: Snowflake
|
||||||
|
rule_trigger_type: AutoModerationRuleTriggerType
|
||||||
|
user_id: Snowflake
|
||||||
|
channel_id: NotRequired[Snowflake]
|
||||||
|
message_id: NotRequired[Snowflake]
|
||||||
|
alert_system_message_id: NotRequired[Snowflake]
|
||||||
|
content: str
|
||||||
|
matched_keyword: Optional[str]
|
||||||
|
matched_content: Optional[str]
|
@ -25,6 +25,7 @@ DEALINGS IN THE SOFTWARE.
|
|||||||
from typing import List, Literal, Optional, TypedDict
|
from typing import List, Literal, Optional, TypedDict
|
||||||
from typing_extensions import NotRequired, Required
|
from typing_extensions import NotRequired, Required
|
||||||
|
|
||||||
|
from .automod import AutoModerationAction, AutoModerationRuleTriggerType
|
||||||
from .activity import PartialPresenceUpdate
|
from .activity import PartialPresenceUpdate
|
||||||
from .voice import GuildVoiceState
|
from .voice import GuildVoiceState
|
||||||
from .integration import BaseIntegration, IntegrationApplication
|
from .integration import BaseIntegration, IntegrationApplication
|
||||||
@ -321,3 +322,17 @@ class TypingStartEvent(TypedDict):
|
|||||||
timestamp: int
|
timestamp: int
|
||||||
guild_id: NotRequired[Snowflake]
|
guild_id: NotRequired[Snowflake]
|
||||||
member: NotRequired[MemberWithUser]
|
member: NotRequired[MemberWithUser]
|
||||||
|
|
||||||
|
|
||||||
|
class AutoModerationActionExecution(TypedDict):
|
||||||
|
guild_id: Snowflake
|
||||||
|
action: AutoModerationAction
|
||||||
|
rule_id: Snowflake
|
||||||
|
rule_trigger_type: AutoModerationRuleTriggerType
|
||||||
|
user_id: Snowflake
|
||||||
|
channel_id: NotRequired[Snowflake]
|
||||||
|
message_id: NotRequired[Snowflake]
|
||||||
|
alert_system_message_id: NotRequired[Snowflake]
|
||||||
|
content: str
|
||||||
|
matched_keyword: Optional[str]
|
||||||
|
matched_content: Optional[str]
|
||||||
|
249
docs/api.rst
249
docs/api.rst
@ -203,6 +203,53 @@ to handle it, which defaults to logging the traceback and ignoring the exception
|
|||||||
errors. In order to turn a function into a coroutine they must be ``async def``
|
errors. In order to turn a function into a coroutine they must be ``async def``
|
||||||
functions.
|
functions.
|
||||||
|
|
||||||
|
AutoMod
|
||||||
|
~~~~~~~
|
||||||
|
|
||||||
|
.. function:: on_automod_rule_create(rule)
|
||||||
|
|
||||||
|
Called when a :class:`AutoModRule` is created.
|
||||||
|
|
||||||
|
This requires :attr:`Intents.auto_moderation_configuration` to be enabled.
|
||||||
|
|
||||||
|
.. versionadded:: 2.0
|
||||||
|
|
||||||
|
:param rule: The rule that was created.
|
||||||
|
:type rule: :class:`AutoModRule`
|
||||||
|
|
||||||
|
.. function:: on_automod_rule_update(rule)
|
||||||
|
|
||||||
|
Called when a :class:`AutoModRule` is updated.
|
||||||
|
|
||||||
|
This requires :attr:`Intents.auto_moderation_configuration` to be enabled.
|
||||||
|
|
||||||
|
.. versionadded:: 2.0
|
||||||
|
|
||||||
|
:param rule: The rule that was updated.
|
||||||
|
:type rule: :class:`AutoModRule`
|
||||||
|
|
||||||
|
.. function:: on_automod_rule_delete(rule)
|
||||||
|
|
||||||
|
Called when a :class:`AutoModRule` is deleted.
|
||||||
|
|
||||||
|
This requires :attr:`Intents.auto_moderation_configuration` to be enabled.
|
||||||
|
|
||||||
|
.. versionadded:: 2.0
|
||||||
|
|
||||||
|
:param rule: The rule that was deleted.
|
||||||
|
:type rule: :class:`AutoModRule`
|
||||||
|
|
||||||
|
.. function:: on_automod_action(execution)
|
||||||
|
|
||||||
|
Called when a :class:`AutoModAction` is created/performed.
|
||||||
|
|
||||||
|
This requires :attr:`Intents.auto_moderation_execution` to be enabled.
|
||||||
|
|
||||||
|
.. versionadded:: 2.0
|
||||||
|
|
||||||
|
:param execution: The rule execution that was performed.
|
||||||
|
:type execution: :class:`AutoModAction`
|
||||||
|
|
||||||
Channels
|
Channels
|
||||||
~~~~~~~~~
|
~~~~~~~~~
|
||||||
|
|
||||||
@ -2525,6 +2572,84 @@ of :class:`enum.Enum`.
|
|||||||
|
|
||||||
.. versionadded:: 2.0
|
.. versionadded:: 2.0
|
||||||
|
|
||||||
|
.. attribute:: automod_rule_create
|
||||||
|
|
||||||
|
An automod rule was created.
|
||||||
|
|
||||||
|
When this is the action, the type of :attr:`~AuditLogEntry.target` is
|
||||||
|
a :class:`Object` with the ID of the automod rule that was created.
|
||||||
|
|
||||||
|
Possible attributes for :class:`AuditLogDiff`:
|
||||||
|
|
||||||
|
- :attr:`~AuditLogDiff.name`
|
||||||
|
- :attr:`~AuditLogDiff.enabled`
|
||||||
|
- :attr:`~AuditLogDiff.event_type`
|
||||||
|
- :attr:`~AuditLogDiff.trigger_type`
|
||||||
|
- :attr:`~AuditLogDiff.trigger_metadata`
|
||||||
|
- :attr:`~AuditLogDiff.actions`
|
||||||
|
- :attr:`~AuditLogDiff.exempt_roles`
|
||||||
|
- :attr:`~AuditLogDiff.exempt_channels`
|
||||||
|
|
||||||
|
.. versionadded:: 2.0
|
||||||
|
|
||||||
|
.. attribute:: automod_role_update
|
||||||
|
|
||||||
|
An automod rule was updated.
|
||||||
|
|
||||||
|
When this is the action, the type of :attr:`~AuditLogEntry.target` is
|
||||||
|
a :class:`Object` with the ID of the automod rule that was updated.
|
||||||
|
|
||||||
|
Possible attributes for :class:`AuditLogDiff`:
|
||||||
|
|
||||||
|
- :attr:`~AuditLogDiff.name`
|
||||||
|
- :attr:`~AuditLogDiff.enabled`
|
||||||
|
- :attr:`~AuditLogDiff.event_type`
|
||||||
|
- :attr:`~AuditLogDiff.trigger_type`
|
||||||
|
- :attr:`~AuditLogDiff.trigger_metadata`
|
||||||
|
- :attr:`~AuditLogDiff.actions`
|
||||||
|
- :attr:`~AuditLogDiff.exempt_roles`
|
||||||
|
- :attr:`~AuditLogDiff.exempt_channels`
|
||||||
|
|
||||||
|
.. versionadded:: 2.0
|
||||||
|
|
||||||
|
.. attribute:: automod_rule_delete
|
||||||
|
|
||||||
|
An automod rule was deleted.
|
||||||
|
|
||||||
|
When this is the action, the type of :attr:`~AuditLogEntry.target` is
|
||||||
|
a :class:`Object` with the ID of the automod rule that was deleted.
|
||||||
|
|
||||||
|
Possible attributes for :class:`AuditLogDiff`:
|
||||||
|
|
||||||
|
- :attr:`~AuditLogDiff.name`
|
||||||
|
- :attr:`~AuditLogDiff.enabled`
|
||||||
|
- :attr:`~AuditLogDiff.event_type`
|
||||||
|
- :attr:`~AuditLogDiff.trigger_type`
|
||||||
|
- :attr:`~AuditLogDiff.trigger_metadata`
|
||||||
|
- :attr:`~AuditLogDiff.actions`
|
||||||
|
- :attr:`~AuditLogDiff.exempt_roles`
|
||||||
|
- :attr:`~AuditLogDiff.exempt_channels`
|
||||||
|
|
||||||
|
.. versionadded:: 2.0
|
||||||
|
|
||||||
|
.. attribute:: automod_block_message
|
||||||
|
|
||||||
|
An automod rule blocked a message from being sent.
|
||||||
|
|
||||||
|
When this is the action, the type of :attr:`~AuditLogEntry.target` is
|
||||||
|
a :class:`Member` with the ID of the person who triggered the automod rule.
|
||||||
|
|
||||||
|
When this is the action, the type of :attr:`~AuditLogEntry.extra` is
|
||||||
|
set to an unspecified proxy object with 3 attributes:
|
||||||
|
|
||||||
|
- ``automod_rule_name``: The name of the automod rule that was triggered.
|
||||||
|
- ``automod_rule_trigger``: A :class:`AutoModRuleTriggerType` representation of the rule type that was triggered.
|
||||||
|
- ``channel``: The channel in which the automod rule was triggered.
|
||||||
|
|
||||||
|
When this is the action, :attr:`AuditLogEntry.changes` is empty.
|
||||||
|
|
||||||
|
.. versionadded:: 2.0
|
||||||
|
|
||||||
.. class:: AuditLogActionCategory
|
.. class:: AuditLogActionCategory
|
||||||
|
|
||||||
Represents the category that the :class:`AuditLogAction` belongs to.
|
Represents the category that the :class:`AuditLogAction` belongs to.
|
||||||
@ -2950,6 +3075,56 @@ of :class:`enum.Enum`.
|
|||||||
|
|
||||||
An alias for :attr:`completed`.
|
An alias for :attr:`completed`.
|
||||||
|
|
||||||
|
.. class:: AutoModRuleTriggerType
|
||||||
|
|
||||||
|
Represents the trigger type of an auto mod rule.
|
||||||
|
|
||||||
|
.. versionadded:: 2.0
|
||||||
|
|
||||||
|
.. attribute:: keyword
|
||||||
|
|
||||||
|
The rule will trigger when a keyword is mentioned.
|
||||||
|
|
||||||
|
.. attribute:: harmful_link
|
||||||
|
|
||||||
|
The rule will trigger when a harmful link is posted.
|
||||||
|
|
||||||
|
.. attribute:: spam
|
||||||
|
|
||||||
|
The rule will trigger when a spam message is posted.
|
||||||
|
|
||||||
|
.. attribute:: keyword_preset
|
||||||
|
|
||||||
|
The rule will trigger when something triggers based on the set keyword preset types.
|
||||||
|
|
||||||
|
.. class:: AutoModRuleEventType
|
||||||
|
|
||||||
|
Represents the event type of an auto mod rule.
|
||||||
|
|
||||||
|
.. versionadded:: 2.0
|
||||||
|
|
||||||
|
.. attribute:: message_send
|
||||||
|
|
||||||
|
The rule will trigger when a message is sent.
|
||||||
|
|
||||||
|
.. class:: AutoModRuleActionType
|
||||||
|
|
||||||
|
Represents the action type of an auto mod rule.
|
||||||
|
|
||||||
|
.. versionadded:: 2.0
|
||||||
|
|
||||||
|
.. attribute:: block_message
|
||||||
|
|
||||||
|
The rule will block a message from being sent.
|
||||||
|
|
||||||
|
.. attribute:: send_alert_message
|
||||||
|
|
||||||
|
The rule will send an alert message to a predefined channel.
|
||||||
|
|
||||||
|
.. attribute:: timeout
|
||||||
|
|
||||||
|
The rule will timeout a user.
|
||||||
|
|
||||||
.. _discord-api-audit-logs:
|
.. _discord-api-audit-logs:
|
||||||
|
|
||||||
Audit Log Data
|
Audit Log Data
|
||||||
@ -3543,6 +3718,48 @@ AuditLogDiff
|
|||||||
|
|
||||||
:type: :class:`~discord.app_commands.AppCommandPermissions`
|
:type: :class:`~discord.app_commands.AppCommandPermissions`
|
||||||
|
|
||||||
|
.. attribute:: enabled
|
||||||
|
|
||||||
|
Whether the automod rule is active or not.
|
||||||
|
|
||||||
|
:type: :class:`bool`
|
||||||
|
|
||||||
|
.. attribute:: event_type
|
||||||
|
|
||||||
|
The event type for triggering the automod rule.
|
||||||
|
|
||||||
|
:type: :class:`str`
|
||||||
|
|
||||||
|
.. attribute:: trigger_type
|
||||||
|
|
||||||
|
The trigger type for the automod rule.
|
||||||
|
|
||||||
|
:type: :class:`AutoModRuleTriggerType`
|
||||||
|
|
||||||
|
.. attribute:: trigger_metadata
|
||||||
|
|
||||||
|
The trigger metadata for the automod rule.
|
||||||
|
|
||||||
|
:type: Dict[:class:`str`, Any]
|
||||||
|
|
||||||
|
.. attribute:: actions
|
||||||
|
|
||||||
|
The actions to take when an automod rule is triggered.
|
||||||
|
|
||||||
|
:type: List[Dict[:class:`str`, Any]]
|
||||||
|
|
||||||
|
.. attribute:: exempt_roles
|
||||||
|
|
||||||
|
The list of roles that are exempt from the automod rule.
|
||||||
|
|
||||||
|
:type: List[:class:`str`]
|
||||||
|
|
||||||
|
.. attribute:: exempt_channels
|
||||||
|
|
||||||
|
The list of channels that are exempt from the automod rule.
|
||||||
|
|
||||||
|
:type: List[:class:`str`]
|
||||||
|
|
||||||
.. this is currently missing the following keys: reason and application_id
|
.. this is currently missing the following keys: reason and application_id
|
||||||
I'm not sure how to about porting these
|
I'm not sure how to about porting these
|
||||||
|
|
||||||
@ -3699,6 +3916,15 @@ User
|
|||||||
.. automethod:: typing
|
.. automethod:: typing
|
||||||
:async-with:
|
:async-with:
|
||||||
|
|
||||||
|
AutoMod
|
||||||
|
~~~~~~~
|
||||||
|
|
||||||
|
.. autoclass:: AutoModRule()
|
||||||
|
:members:
|
||||||
|
|
||||||
|
.. autoclass:: AutoModAction()
|
||||||
|
:members:
|
||||||
|
|
||||||
Attachment
|
Attachment
|
||||||
~~~~~~~~~~~
|
~~~~~~~~~~~
|
||||||
|
|
||||||
@ -4295,6 +4521,29 @@ ChannelFlags
|
|||||||
.. autoclass:: ChannelFlags
|
.. autoclass:: ChannelFlags
|
||||||
:members:
|
:members:
|
||||||
|
|
||||||
|
AutoModPresets
|
||||||
|
~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
.. attributetable:: AutoModPresets
|
||||||
|
|
||||||
|
.. autoclass:: AutoModPresets
|
||||||
|
:members:
|
||||||
|
|
||||||
|
AutoModRuleAction
|
||||||
|
~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
.. attributetable:: AutoModRuleAction
|
||||||
|
|
||||||
|
.. autoclass:: AutoModRuleAction
|
||||||
|
:members:
|
||||||
|
|
||||||
|
AutoModTrigger
|
||||||
|
~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
.. attributetable:: AutoModTrigger
|
||||||
|
|
||||||
|
.. autoclass:: AutoModTrigger
|
||||||
|
:members:
|
||||||
|
|
||||||
File
|
File
|
||||||
~~~~~
|
~~~~~
|
||||||
|
Loading…
x
Reference in New Issue
Block a user