Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Add support for guild incidents #9590

Merged
merged 15 commits into from
Jan 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 85 additions & 0 deletions discord/guild.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@
Guild as GuildPayload,
RolePositionUpdate as RolePositionUpdatePayload,
GuildFeature,
IncidentData,
)
from .types.threads import (
Thread as ThreadPayload,
Expand Down Expand Up @@ -320,6 +321,7 @@ class Guild(Hashable):
'premium_progress_bar_enabled',
'_safety_alerts_channel_id',
'max_stage_video_users',
'_incidents_data',
)

_PREMIUM_GUILD_LIMITS: ClassVar[Dict[Optional[int], _GuildLimit]] = {
Expand Down Expand Up @@ -509,6 +511,7 @@ def _from_data(self, guild: GuildPayload) -> None:
self.owner_id: Optional[int] = utils._get_as_snowflake(guild, 'owner_id')
self._large: Optional[bool] = None if self._member_count is None else self._member_count >= 250
self._afk_channel_id: Optional[int] = utils._get_as_snowflake(guild, 'afk_channel_id')
self._incidents_data: Optional[IncidentData] = guild.get('incidents_data')

if 'channels' in guild:
channels = guild['channels']
Expand Down Expand Up @@ -1843,6 +1846,8 @@ async def edit(
mfa_level: MFALevel = MISSING,
raid_alerts_disabled: bool = MISSING,
safety_alerts_channel: TextChannel = MISSING,
invites_disabled_until: datetime.datetime = MISSING,
dms_disabled_until: datetime.datetime = MISSING,
) -> Guild:
r"""|coro|

Expand Down Expand Up @@ -1969,6 +1974,18 @@ async def edit(

.. versionadded:: 2.3

invites_disabled_until: Optional[:class:`datetime.datetime`]
The time when invites should be enabled again, or ``None`` to disable the action.
This must be a timezone-aware datetime object. Consider using :func:`utils.utcnow`.

.. versionadded:: 2.4

dms_disabled_until: Optional[:class:`datetime.datetime`]
The time when direct messages should be allowed again, or ``None`` to disable the action.
This must be a timezone-aware datetime object. Consider using :func:`utils.utcnow`.

.. versionadded:: 2.4

Raises
-------
Forbidden
Expand Down Expand Up @@ -2157,6 +2174,30 @@ async def edit(

await http.edit_guild_mfa_level(self.id, mfa_level=mfa_level.value)

incident_actions_payload: IncidentData = {}
if invites_disabled_until is not MISSING:
if invites_disabled_until is None:
incident_actions_payload['invites_disabled_until'] = None
else:
if invites_disabled_until.tzinfo is None:
raise TypeError(
'invites_disabled_until must be an aware datetime. Consider using discord.utils.utcnow() or datetime.datetime.now().astimezone() for local time.'
)
incident_actions_payload['invites_disabled_until'] = invites_disabled_until.isoformat()

if dms_disabled_until is not MISSING:
if dms_disabled_until is None:
incident_actions_payload['dms_disabled_until'] = None
else:
if dms_disabled_until.tzinfo is None:
raise TypeError(
'dms_disabled_until must be an aware datetime. Consider using discord.utils.utcnow() or datetime.datetime.now().astimezone() for local time.'
)
incident_actions_payload['dms_disabled_until'] = dms_disabled_until.isoformat()

if incident_actions_payload:
await http.edit_incident_actions(self.id, payload=incident_actions_payload)

data = await http.edit_guild(self.id, reason=reason, **fields)
return Guild(data=data, state=self._state)

Expand Down Expand Up @@ -4292,3 +4333,47 @@ async def create_automod_rule(
)

return AutoModRule(data=data, guild=self, state=self._state)

@property
def invites_paused_until(self) -> Optional[datetime.datetime]:
"""Optional[:class:`datetime.datetime`]: If invites are paused, returns when
invites will get enabled in UTC, otherwise returns None.

.. versionadded:: 2.4
"""
if not self._incidents_data:
return None

return utils.parse_time(self._incidents_data.get('invites_disabled_until'))

@property
def dms_paused_until(self) -> Optional[datetime.datetime]:
"""Optional[:class:`datetime.datetime`]: If DMs are paused, returns when DMs
will get enabled in UTC, otherwise returns None.

.. versionadded:: 2.4
"""
if not self._incidents_data:
return None

return utils.parse_time(self._incidents_data.get('dms_disabled_until'))

def invites_paused(self) -> bool:
""":class:`bool`: Whether invites are paused in the guild.

.. versionadded:: 2.4
"""
if not self.invites_paused_until:
return False

return self.invites_paused_until > utils.utcnow()

def dms_paused(self) -> bool:
""":class:`bool`: Whether DMs are paused in the guild.

.. versionadded:: 2.4
"""
if not self.dms_paused_until:
return False

return self.dms_paused_until > utils.utcnow()
3 changes: 3 additions & 0 deletions discord/http.py
Original file line number Diff line number Diff line change
Expand Up @@ -1764,6 +1764,9 @@ def edit_widget(
) -> Response[widget.WidgetSettings]:
return self.request(Route('PATCH', '/guilds/{guild_id}/widget', guild_id=guild_id), json=payload, reason=reason)

def edit_incident_actions(self, guild_id: Snowflake, payload: guild.IncidentData) -> Response[guild.IncidentData]:
return self.request(Route('PUT', '/guilds/{guild_id}/incident-actions', guild_id=guild_id), json=payload)

# Invite management

def create_invite(
Expand Down
6 changes: 6 additions & 0 deletions discord/types/guild.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,11 @@ class UnavailableGuild(TypedDict):
unavailable: NotRequired[bool]


class IncidentData(TypedDict):
invites_disabled_until: NotRequired[Optional[str]]
dms_disabled_until: NotRequired[Optional[str]]


DefaultMessageNotificationLevel = Literal[0, 1]
ExplicitContentFilterLevel = Literal[0, 1, 2]
MFALevel = Literal[0, 1]
Expand Down Expand Up @@ -97,6 +102,7 @@ class _BaseGuildPreview(UnavailableGuild):
stickers: List[GuildSticker]
features: List[GuildFeature]
description: Optional[str]
incidents_data: Optional[IncidentData]


class _GuildPreviewUnique(TypedDict):
Expand Down
Loading