From e5ca2d1669b2d719a51859f29c3fb473dde9c09c Mon Sep 17 00:00:00 2001 From: Lumouille <144063653+Lumabots@users.noreply.github.com> Date: Tue, 14 Oct 2025 16:23:12 +0300 Subject: [PATCH 01/15] feat: add incident management functionality to guilds --- discord/__init__.py | 1 + discord/guild.py | 61 +++++++++++++++++++++++++++++++++- discord/http.py | 15 ++++++++- discord/incidents.py | 74 ++++++++++++++++++++++++++++++++++++++++++ discord/types/guild.py | 13 ++++++++ pyproject.toml | 3 ++ 6 files changed, 165 insertions(+), 2 deletions(-) create mode 100644 discord/incidents.py diff --git a/discord/__init__.py b/discord/__init__.py index dbd87452b2..14fd48a781 100644 --- a/discord/__init__.py +++ b/discord/__init__.py @@ -56,6 +56,7 @@ from .monetization import * from .object import * from .onboarding import * +from .incidents import * from .partial_emoji import * from .permissions import * from .player import * diff --git a/discord/guild.py b/discord/guild.py index ff4c9e04b2..acb57f2cc5 100644 --- a/discord/guild.py +++ b/discord/guild.py @@ -26,6 +26,7 @@ from __future__ import annotations import copy +import datetime import unicodedata from typing import ( TYPE_CHECKING, @@ -80,6 +81,7 @@ from .mixins import Hashable from .monetization import Entitlement from .onboarding import Onboarding +from .incidents import IncidentsData from .permissions import PermissionOverwrite from .role import Role, RoleColours from .scheduled_events import ScheduledEvent, ScheduledEventLocation @@ -111,7 +113,10 @@ from .state import ConnectionState from .template import Template from .types.guild import Ban as BanPayload - from .types.guild import Guild as GuildPayload + from .types.guild import ( + Guild as GuildPayload, + IncidentsData as IncidentsDataPayload, + ) from .types.guild import GuildFeature, MFALevel from .types.member import Member as MemberPayload from .types.threads import Thread as ThreadPayload @@ -290,6 +295,7 @@ class Guild(Hashable): "approximate_member_count", "approximate_presence_count", "_sounds", + "incidents", ) _PREMIUM_GUILD_LIMITS: ClassVar[dict[int | None, _GuildLimit]] = { @@ -569,6 +575,13 @@ def _from_data(self, guild: GuildPayload) -> None: sound = SoundboardSound(state=state, http=state.http, data=sound) self._add_sound(sound) + incidents_payload = guild.get("incidents_data") + self.incidents: IncidentsData | None = ( + IncidentsData(data=incidents_payload, guild=self) + if incidents_payload is not None + else None + ) + def _add_sound(self, sound: SoundboardSound) -> None: self._sounds[sound.id] = sound self._state._add_sound(sound) @@ -4405,6 +4418,52 @@ async def edit_onboarding( new = await self._state.http.edit_onboarding(self.id, fields, reason=reason) return Onboarding(data=new, guild=self) + async def modify_incident_actions( + self, + *, + invites_disabled_until: datetime.datetime | None = MISSING, + dms_disabled_until: datetime.datetime | None = MISSING, + reason: str | None = MISSING, + ) -> IncidentsData: + """|coro| + + Modify the guild's incident actions (invites or DMs disabled until a + given ISO8601 timestamp). Supplying ``None`` disables the respective + action. Requires :attr:`~Permissions.manage_guild`. + + Parameters + ---------- + invites_disabled_until: Optional[:class:`str`] + ISO8601 timestamp indicating when invites will be enabled again, or + ``None`` to disable. + dms_disabled_until: Optional[:class:`str`] + ISO8601 timestamp indicating when DMs will be enabled again, or + ``None`` to disable. + reason: Optional[:class:`str`] + Audit log reason. + + Returns + ------- + :class:`IncidentsData` + The updated incidents data for the guild. + """ + + fields: IncidentsDataPayload = {} + if invites_disabled_until is not MISSING: + fields["invites_disabled_until"] = ( + invites_disabled_until and invites_disabled_until.isoformat() + ) + + if dms_disabled_until is not MISSING: + fields["dms_disabled_until"] = ( + dms_disabled_until and dms_disabled_until.isoformat() + ) + + new = await self._state.http.modify_guild_incident_actions( + self.id, fields, reason=reason + ) + return IncidentsData(data=new, guild=self) + async def delete_auto_moderation_rule( self, id: int, diff --git a/discord/http.py b/discord/http.py index bfefed91d1..238d467187 100644 --- a/discord/http.py +++ b/discord/http.py @@ -47,7 +47,7 @@ from .file import VoiceMessage from .gateway import DiscordClientWebSocketResponse from .soundboard import PartialSoundboardSound, SoundboardSound -from .utils import MISSING, warn_deprecated +from .utils import MISSING _log = logging.getLogger(__name__) @@ -3135,6 +3135,19 @@ def edit_onboarding( reason=reason, ) + def modify_guild_incident_actions( + self, + guild_id: Snowflake, + payload: guild.IncidentsData, + *, + reason: str | None = None, + ) -> Response[guild.IncidentsData]: + return self.request( + Route("PUT", "/guilds/{guild_id}/incident-actions", guild_id=guild_id), + json=payload, + reason=reason, + ) + # Polls def expire_poll( diff --git a/discord/incidents.py b/discord/incidents.py new file mode 100644 index 0000000000..4071947dbf --- /dev/null +++ b/discord/incidents.py @@ -0,0 +1,74 @@ +from __future__ import annotations + +import datetime +from typing import TYPE_CHECKING, Optional + +if TYPE_CHECKING: + from .guild import Guild + from .types.guild import IncidentsData as IncidentsDataPayload + +__all__ = ("IncidentsData",) + + +class IncidentsData: + """Represents the incidents data object for a guild. + + Attributes + ---------- + invites_disabled_until: Optional[datetime.datetime] + When invites will be enabled again as a :class:`datetime.datetime`, or ``None``. + dms_disabled_until: Optional[datetime.datetime] + When direct messages will be enabled again as a :class:`datetime.datetime`, or ``None``. + dm_spam_detected_at: Optional[datetime.datetime] + When DM spam was detected, or ``None``. + raid_detected_at: Optional[datetime.datetime] + When a raid was detected, or ``None``. + """ + + __slots__ = ( + "guild", + "invites_disabled_until", + "dms_disabled_until", + "dm_spam_detected_at", + "raid_detected_at", + ) + + def __init__(self, data: IncidentsDataPayload, guild: Optional[Guild] = None): + self.guild = guild + + self.invites_disabled_until: datetime.datetime | None = ( + datetime.datetime.fromisoformat(s) + if (s := data.get("invites_disabled_until")) + else None + ) + + self.dms_disabled_until: datetime.datetime | None = ( + datetime.datetime.fromisoformat(s) + if (s := data.get("dms_disabled_until")) + else None + ) + + self.dm_spam_detected_at: datetime.datetime | None = ( + datetime.datetime.fromisoformat(s) + if (s := data.get("dm_spam_detected_at")) + else None + ) + + self.raid_detected_at: datetime.datetime | None = ( + datetime.datetime.fromisoformat(s) + if (s := data.get("raid_detected_at")) + else None + ) + + def to_dict(self) -> IncidentsDataPayload: + """Converts this object back to a raw payload suitable for API use.""" + return { + "invites_disabled_until": self.invites_disabled_until + and self.invites_disabled_until.isoformat(), + "dms_disabled_until": self.dms_disabled_until + and self.dms_disabled_until.isoformat(), + "dm_spam_detected_at": self.dm_spam_detected_at + and self.dm_spam_detected_at.isoformat(), + "raid_detected_at": self.raid_detected_at + and self.raid_detected_at.isoformat(), + } diff --git a/discord/types/guild.py b/discord/types/guild.py index 342686af9e..3c71c8647e 100644 --- a/discord/types/guild.py +++ b/discord/types/guild.py @@ -164,6 +164,7 @@ class Guild(_BaseGuildPreview): premium_tier: PremiumTier preferred_locale: str public_updates_channel_id: Snowflake | None + incidents_data: IncidentsData | None class InviteGuild(Guild, total=False): @@ -197,3 +198,15 @@ class GuildMFAModify(TypedDict): class GuildBulkBan(TypedDict): banned_users: list[Snowflake] failed_users: list[Snowflake] + + +class IncidentsData(TypedDict, total=False): + invites_disabled_until: str | None + dms_disabled_until: str | None + dm_spam_detected_at: str | None + raid_detected_at: str | None + + +class ModifyIncidents(TypedDict, total=False): + invites_disabled_until: str | None + dms_disabled_until: str | None diff --git a/pyproject.toml b/pyproject.toml index 7f2930ee65..f7425ef6f2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -105,3 +105,6 @@ max-line-length = 120 [tool.pytest.ini_options] asyncio_mode = "auto" + +[tool.basedpyright] +typeCheckingMode = "strict" \ No newline at end of file From 438dd0c28712e41540230314257f62d855d7091f Mon Sep 17 00:00:00 2001 From: Lumouille <144063653+Lumabots@users.noreply.github.com> Date: Tue, 14 Oct 2025 16:23:52 +0300 Subject: [PATCH 02/15] fix: remove deprecated type checking configuration for basedpyright --- pyproject.toml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index f7425ef6f2..8b9392085f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -104,7 +104,4 @@ indent-string = ' ' max-line-length = 120 [tool.pytest.ini_options] -asyncio_mode = "auto" - -[tool.basedpyright] -typeCheckingMode = "strict" \ No newline at end of file +asyncio_mode = "auto" \ No newline at end of file From ab784013ee79194e875be926a5dc1e6f3e821504 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 14 Oct 2025 13:26:08 +0000 Subject: [PATCH 03/15] style(pre-commit): auto fixes from pre-commit.com hooks --- discord/__init__.py | 2 +- discord/guild.py | 11 +++++++---- discord/incidents.py | 2 +- pyproject.toml | 2 +- 4 files changed, 10 insertions(+), 7 deletions(-) diff --git a/discord/__init__.py b/discord/__init__.py index 14fd48a781..1524dc4c3f 100644 --- a/discord/__init__.py +++ b/discord/__init__.py @@ -47,6 +47,7 @@ from .flags import * from .guild import * from .http import * +from .incidents import * from .integrations import * from .interactions import * from .invite import * @@ -56,7 +57,6 @@ from .monetization import * from .object import * from .onboarding import * -from .incidents import * from .partial_emoji import * from .permissions import * from .player import * diff --git a/discord/guild.py b/discord/guild.py index acb57f2cc5..da678374dc 100644 --- a/discord/guild.py +++ b/discord/guild.py @@ -69,6 +69,7 @@ from .errors import ClientException, InvalidArgument, InvalidData from .file import File from .flags import SystemChannelFlags +from .incidents import IncidentsData from .integrations import Integration, _integration_factory from .invite import Invite from .iterators import ( @@ -81,7 +82,6 @@ from .mixins import Hashable from .monetization import Entitlement from .onboarding import Onboarding -from .incidents import IncidentsData from .permissions import PermissionOverwrite from .role import Role, RoleColours from .scheduled_events import ScheduledEvent, ScheduledEventLocation @@ -113,11 +113,14 @@ from .state import ConnectionState from .template import Template from .types.guild import Ban as BanPayload + from .types.guild import Guild as GuildPayload + from .types.guild import ( + GuildFeature, + ) + from .types.guild import IncidentsData as IncidentsDataPayload from .types.guild import ( - Guild as GuildPayload, - IncidentsData as IncidentsDataPayload, + MFALevel, ) - from .types.guild import GuildFeature, MFALevel from .types.member import Member as MemberPayload from .types.threads import Thread as ThreadPayload from .types.voice import GuildVoiceState diff --git a/discord/incidents.py b/discord/incidents.py index 4071947dbf..0620b8e362 100644 --- a/discord/incidents.py +++ b/discord/incidents.py @@ -33,7 +33,7 @@ class IncidentsData: "raid_detected_at", ) - def __init__(self, data: IncidentsDataPayload, guild: Optional[Guild] = None): + def __init__(self, data: IncidentsDataPayload, guild: Guild | None = None): self.guild = guild self.invites_disabled_until: datetime.datetime | None = ( diff --git a/pyproject.toml b/pyproject.toml index 8b9392085f..7f2930ee65 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -104,4 +104,4 @@ indent-string = ' ' max-line-length = 120 [tool.pytest.ini_options] -asyncio_mode = "auto" \ No newline at end of file +asyncio_mode = "auto" From 67fdcaba2e7de69d8ccba895fc51141bd504c7a6 Mon Sep 17 00:00:00 2001 From: Lumouille <144063653+Lumabots@users.noreply.github.com> Date: Tue, 14 Oct 2025 16:29:36 +0300 Subject: [PATCH 04/15] fix: rename incidents attribute to incidents_data to follow api --- discord/guild.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/discord/guild.py b/discord/guild.py index acb57f2cc5..ccfd9edbf9 100644 --- a/discord/guild.py +++ b/discord/guild.py @@ -576,7 +576,7 @@ def _from_data(self, guild: GuildPayload) -> None: self._add_sound(sound) incidents_payload = guild.get("incidents_data") - self.incidents: IncidentsData | None = ( + self.incidents_data: IncidentsData | None = ( IncidentsData(data=incidents_payload, guild=self) if incidents_payload is not None else None From 9fd5c309dade4f56f334ff91f114c7e4c8908c4f Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 14 Oct 2025 13:30:43 +0000 Subject: [PATCH 05/15] style(pre-commit): auto fixes from pre-commit.com hooks --- discord/incidents.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/discord/incidents.py b/discord/incidents.py index 0620b8e362..6b9bf86796 100644 --- a/discord/incidents.py +++ b/discord/incidents.py @@ -1,7 +1,7 @@ from __future__ import annotations import datetime -from typing import TYPE_CHECKING, Optional +from typing import TYPE_CHECKING if TYPE_CHECKING: from .guild import Guild From f3e7c40f6faa6495d0070f2dcffa7d3d9cc50349 Mon Sep 17 00:00:00 2001 From: Lumouille <144063653+Lumabots@users.noreply.github.com> Date: Tue, 14 Oct 2025 15:36:47 +0200 Subject: [PATCH 06/15] Update discord/http.py Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Signed-off-by: Lumouille <144063653+Lumabots@users.noreply.github.com> --- discord/http.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/discord/http.py b/discord/http.py index 238d467187..47ecfb0325 100644 --- a/discord/http.py +++ b/discord/http.py @@ -3138,7 +3138,7 @@ def edit_onboarding( def modify_guild_incident_actions( self, guild_id: Snowflake, - payload: guild.IncidentsData, + payload: guild.ModifyIncidents, *, reason: str | None = None, ) -> Response[guild.IncidentsData]: From 356c343a20a555b365e88c1e1580a28a2ab819af Mon Sep 17 00:00:00 2001 From: Lumouille <144063653+Lumabots@users.noreply.github.com> Date: Tue, 14 Oct 2025 15:36:58 +0200 Subject: [PATCH 07/15] Update discord/guild.py Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Signed-off-by: Lumouille <144063653+Lumabots@users.noreply.github.com> --- discord/guild.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/discord/guild.py b/discord/guild.py index 107e9e8660..ee1196b8a9 100644 --- a/discord/guild.py +++ b/discord/guild.py @@ -4436,10 +4436,10 @@ async def modify_incident_actions( Parameters ---------- - invites_disabled_until: Optional[:class:`str`] + invites_disabled_until: Optional[:class:`datetime.datetime`] ISO8601 timestamp indicating when invites will be enabled again, or ``None`` to disable. - dms_disabled_until: Optional[:class:`str`] + dms_disabled_until: Optional[:class:`datetime.datetime`] ISO8601 timestamp indicating when DMs will be enabled again, or ``None`` to disable. reason: Optional[:class:`str`] From f45b897e1573dcf45845b91c623dce30b40e59e3 Mon Sep 17 00:00:00 2001 From: Lumouille <144063653+Lumabots@users.noreply.github.com> Date: Tue, 14 Oct 2025 15:41:06 +0200 Subject: [PATCH 08/15] Update discord/incidents.py Co-authored-by: Soheab <33902984+Soheab@users.noreply.github.com> Signed-off-by: Lumouille <144063653+Lumabots@users.noreply.github.com> --- discord/incidents.py | 1 - 1 file changed, 1 deletion(-) diff --git a/discord/incidents.py b/discord/incidents.py index 6b9bf86796..fa1edbbd54 100644 --- a/discord/incidents.py +++ b/discord/incidents.py @@ -61,7 +61,6 @@ def __init__(self, data: IncidentsDataPayload, guild: Guild | None = None): ) def to_dict(self) -> IncidentsDataPayload: - """Converts this object back to a raw payload suitable for API use.""" return { "invites_disabled_until": self.invites_disabled_until and self.invites_disabled_until.isoformat(), From 97a14e59a379cc9baee08eb808a4ed1d12aa7e9a Mon Sep 17 00:00:00 2001 From: Lumouille <144063653+Lumabots@users.noreply.github.com> Date: Tue, 14 Oct 2025 16:54:53 +0300 Subject: [PATCH 09/15] refactor(incidents): simplify datetime parsing using parse_time utility --- discord/incidents.py | 25 +++++++++---------------- 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/discord/incidents.py b/discord/incidents.py index fa1edbbd54..36567d278e 100644 --- a/discord/incidents.py +++ b/discord/incidents.py @@ -2,6 +2,7 @@ import datetime from typing import TYPE_CHECKING +from .utils import parse_time if TYPE_CHECKING: from .guild import Guild @@ -36,28 +37,20 @@ class IncidentsData: def __init__(self, data: IncidentsDataPayload, guild: Guild | None = None): self.guild = guild - self.invites_disabled_until: datetime.datetime | None = ( - datetime.datetime.fromisoformat(s) - if (s := data.get("invites_disabled_until")) - else None + self.invites_disabled_until: datetime.datetime | None = parse_time( + data.get("invites_disabled_until") ) - self.dms_disabled_until: datetime.datetime | None = ( - datetime.datetime.fromisoformat(s) - if (s := data.get("dms_disabled_until")) - else None + self.dms_disabled_until: datetime.datetime | None = parse_time( + data.get("dms_disabled_until") ) - self.dm_spam_detected_at: datetime.datetime | None = ( - datetime.datetime.fromisoformat(s) - if (s := data.get("dm_spam_detected_at")) - else None + self.dm_spam_detected_at: datetime.datetime | None = parse_time( + data.get("dm_spam_detected_at") ) - self.raid_detected_at: datetime.datetime | None = ( - datetime.datetime.fromisoformat(s) - if (s := data.get("raid_detected_at")) - else None + self.raid_detected_at: datetime.datetime | None = parse_time( + data.get("raid_detected_at") ) def to_dict(self) -> IncidentsDataPayload: From 068e2c7ee8b9207bab4f430870dba3f7ce3035c2 Mon Sep 17 00:00:00 2001 From: Lumouille <144063653+Lumabots@users.noreply.github.com> Date: Tue, 14 Oct 2025 16:54:53 +0300 Subject: [PATCH 10/15] removal of guild --- discord/guild.py | 22 +++++++++++----------- discord/incidents.py | 5 +---- 2 files changed, 12 insertions(+), 15 deletions(-) diff --git a/discord/guild.py b/discord/guild.py index ee1196b8a9..5b047ab1cb 100644 --- a/discord/guild.py +++ b/discord/guild.py @@ -117,7 +117,7 @@ from .types.guild import ( GuildFeature, ) - from .types.guild import IncidentsData as IncidentsDataPayload + from .types.guild import ModifyIncidents as ModifyIncidentsPayload from .types.guild import ( MFALevel, ) @@ -4430,20 +4430,20 @@ async def modify_incident_actions( ) -> IncidentsData: """|coro| - Modify the guild's incident actions (invites or DMs disabled until a - given ISO8601 timestamp). Supplying ``None`` disables the respective - action. Requires :attr:`~Permissions.manage_guild`. + Modify the guild's incident actions, controlling when invites or DMs + are re-enabled after being temporarily disabled. Requires + :attr:`~Permissions.manage_guild`. Parameters ---------- invites_disabled_until: Optional[:class:`datetime.datetime`] - ISO8601 timestamp indicating when invites will be enabled again, or - ``None`` to disable. + The ISO8601 timestamp indicating when invites will be enabled again, + or ``None`` to enable invites immediately. dms_disabled_until: Optional[:class:`datetime.datetime`] - ISO8601 timestamp indicating when DMs will be enabled again, or - ``None`` to disable. + The ISO8601 timestamp indicating when DMs will be enabled again, + or ``None`` to enable DMs immediately. reason: Optional[:class:`str`] - Audit log reason. + The reason for this action, used for the audit log. Returns ------- @@ -4451,7 +4451,7 @@ async def modify_incident_actions( The updated incidents data for the guild. """ - fields: IncidentsDataPayload = {} + fields: ModifyIncidentsPayload = {} if invites_disabled_until is not MISSING: fields["invites_disabled_until"] = ( invites_disabled_until and invites_disabled_until.isoformat() @@ -4465,7 +4465,7 @@ async def modify_incident_actions( new = await self._state.http.modify_guild_incident_actions( self.id, fields, reason=reason ) - return IncidentsData(data=new, guild=self) + return IncidentsData(data=new) async def delete_auto_moderation_rule( self, diff --git a/discord/incidents.py b/discord/incidents.py index 36567d278e..e131eae7f4 100644 --- a/discord/incidents.py +++ b/discord/incidents.py @@ -5,7 +5,6 @@ from .utils import parse_time if TYPE_CHECKING: - from .guild import Guild from .types.guild import IncidentsData as IncidentsDataPayload __all__ = ("IncidentsData",) @@ -34,9 +33,7 @@ class IncidentsData: "raid_detected_at", ) - def __init__(self, data: IncidentsDataPayload, guild: Guild | None = None): - self.guild = guild - + def __init__(self, data: IncidentsDataPayload = None): self.invites_disabled_until: datetime.datetime | None = parse_time( data.get("invites_disabled_until") ) From 1cfa614a441be25bd562147d75f597bc3215638e Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 14 Oct 2025 13:55:29 +0000 Subject: [PATCH 11/15] style(pre-commit): auto fixes from pre-commit.com hooks --- discord/guild.py | 4 +--- discord/incidents.py | 1 + 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/discord/guild.py b/discord/guild.py index 5b047ab1cb..fd0ff3b07b 100644 --- a/discord/guild.py +++ b/discord/guild.py @@ -116,11 +116,9 @@ from .types.guild import Guild as GuildPayload from .types.guild import ( GuildFeature, - ) - from .types.guild import ModifyIncidents as ModifyIncidentsPayload - from .types.guild import ( MFALevel, ) + from .types.guild import ModifyIncidents as ModifyIncidentsPayload from .types.member import Member as MemberPayload from .types.threads import Thread as ThreadPayload from .types.voice import GuildVoiceState diff --git a/discord/incidents.py b/discord/incidents.py index e131eae7f4..9c969d20f4 100644 --- a/discord/incidents.py +++ b/discord/incidents.py @@ -2,6 +2,7 @@ import datetime from typing import TYPE_CHECKING + from .utils import parse_time if TYPE_CHECKING: From 1d160c18f0114337a1bdfaa59afc7fabde78c254 Mon Sep 17 00:00:00 2001 From: Lumouille <144063653+Lumabots@users.noreply.github.com> Date: Tue, 14 Oct 2025 15:57:31 +0200 Subject: [PATCH 12/15] Update discord/guild.py Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Signed-off-by: Lumouille <144063653+Lumabots@users.noreply.github.com> --- discord/guild.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/discord/guild.py b/discord/guild.py index fd0ff3b07b..e2ccb32534 100644 --- a/discord/guild.py +++ b/discord/guild.py @@ -578,7 +578,7 @@ def _from_data(self, guild: GuildPayload) -> None: incidents_payload = guild.get("incidents_data") self.incidents_data: IncidentsData | None = ( - IncidentsData(data=incidents_payload, guild=self) + IncidentsData(data=incidents_payload) if incidents_payload is not None else None ) From 64965b305648cc9186c7dc81c2de3f967eae5167 Mon Sep 17 00:00:00 2001 From: Lumouille <144063653+Lumabots@users.noreply.github.com> Date: Tue, 14 Oct 2025 17:00:25 +0300 Subject: [PATCH 13/15] fix(incidents): require data parameter in IncidentsData constructor --- discord/incidents.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/discord/incidents.py b/discord/incidents.py index 9c969d20f4..e3f45d2b28 100644 --- a/discord/incidents.py +++ b/discord/incidents.py @@ -27,14 +27,13 @@ class IncidentsData: """ __slots__ = ( - "guild", "invites_disabled_until", "dms_disabled_until", "dm_spam_detected_at", "raid_detected_at", ) - def __init__(self, data: IncidentsDataPayload = None): + def __init__(self, data: IncidentsDataPayload): self.invites_disabled_until: datetime.datetime | None = parse_time( data.get("invites_disabled_until") ) From 475a248be42a3fd5cd8f1aa8d481b50ad54eddb5 Mon Sep 17 00:00:00 2001 From: Lumouille <144063653+Lumabots@users.noreply.github.com> Date: Tue, 14 Oct 2025 17:13:15 +0300 Subject: [PATCH 14/15] fix(guild): rename incidents attribute to incidents_data for clarity --- discord/guild.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/discord/guild.py b/discord/guild.py index e2ccb32534..46e93935e0 100644 --- a/discord/guild.py +++ b/discord/guild.py @@ -296,7 +296,7 @@ class Guild(Hashable): "approximate_member_count", "approximate_presence_count", "_sounds", - "incidents", + "incidents_data", ) _PREMIUM_GUILD_LIMITS: ClassVar[dict[int | None, _GuildLimit]] = { From c2bba6f6f1fef7bdada8d9e982cc9239edf2cf2f Mon Sep 17 00:00:00 2001 From: Lumouille <144063653+Lumabots@users.noreply.github.com> Date: Fri, 17 Oct 2025 16:00:45 +0200 Subject: [PATCH 15/15] Update guild.py Co-authored-by: Soheab <33902984+Soheab@users.noreply.github.com> Signed-off-by: Lumouille <144063653+Lumabots@users.noreply.github.com> --- discord/guild.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/discord/guild.py b/discord/guild.py index 46e93935e0..087c1349e3 100644 --- a/discord/guild.py +++ b/discord/guild.py @@ -4430,7 +4430,7 @@ async def modify_incident_actions( Modify the guild's incident actions, controlling when invites or DMs are re-enabled after being temporarily disabled. Requires - :attr:`~Permissions.manage_guild`. + the :attr:`~Permissions.manage_guild` permission. Parameters ----------