Skip to content

Commit

Permalink
feat(Guild): add support for raid alerts (#899)
Browse files Browse the repository at this point in the history
  • Loading branch information
Victorsitou authored May 21, 2023
1 parent 09fce91 commit 53095a6
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 6 deletions.
3 changes: 3 additions & 0 deletions changelog/899.feature.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Add support for raid alerts.
- Add :attr:`Guild.safety_alerts_channel`.
- Add ``raid_alerts_disabled`` and ``safety_alerts_channel`` parameters to :meth:`Guild.edit`.
68 changes: 64 additions & 4 deletions disnake/guild.py
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,7 @@ class Guild(Hashable):
- ``PARTNERED``: Guild is a partnered server.
- ``PREVIEW_ENABLED``: Guild can be viewed before being accepted via Membership Screening.
- ``PRIVATE_THREADS``: Guild has access to create private threads (no longer has any effect).
- ``RAID_ALERTS_DISABLED``: Guild has disabled alerts for join raids in the configured safety alerts channel.
- ``ROLE_ICONS``: Guild has access to role icons.
- ``ROLE_SUBSCRIPTIONS_AVAILABLE_FOR_PURCHASE``: Guild has role subscriptions that can be purchased.
- ``ROLE_SUBSCRIPTIONS_ENABLED``: Guild has enabled role subscriptions.
Expand Down Expand Up @@ -352,6 +353,7 @@ class Guild(Hashable):
"_scheduled_events",
"_threads",
"_region",
"_safety_alerts_channel_id",
)

_PREMIUM_GUILD_LIMITS: ClassVar[Dict[Optional[int], _GuildLimit]] = {
Expand Down Expand Up @@ -572,6 +574,9 @@ def _from_data(self, guild: GuildPayload) -> None:
self.widget_enabled: Optional[bool] = guild.get("widget_enabled")
self.widget_channel_id: Optional[int] = utils._get_as_snowflake(guild, "widget_channel_id")
self.vanity_url_code: Optional[str] = guild.get("vanity_url_code")
self._safety_alerts_channel_id: Optional[int] = utils._get_as_snowflake(
guild, "safety_alerts_channel_id"
)

stage_instances = guild.get("stage_instances")
if stage_instances is not None:
Expand Down Expand Up @@ -835,7 +840,7 @@ def system_channel_flags(self) -> SystemChannelFlags:

@property
def rules_channel(self) -> Optional[TextChannel]:
"""Optional[:class:`TextChannel`]: Return's the guild's channel used for the rules.
"""Optional[:class:`TextChannel`]: Returns the guild's channel used for the rules.
The guild must be a Community guild.
If no channel is set, then this returns ``None``.
Expand All @@ -847,7 +852,7 @@ def rules_channel(self) -> Optional[TextChannel]:

@property
def public_updates_channel(self) -> Optional[TextChannel]:
"""Optional[:class:`TextChannel`]: Return's the guild's channel where admins and
"""Optional[:class:`TextChannel`]: Returns the guild's channel where admins and
moderators of the guild receive notices from Discord. The guild must be a
Community guild.
Expand All @@ -858,6 +863,19 @@ def public_updates_channel(self) -> Optional[TextChannel]:
channel_id = self._public_updates_channel_id
return channel_id and self._channels.get(channel_id) # type: ignore

@property
def safety_alerts_channel(self) -> Optional[TextChannel]:
"""Optional[:class:`TextChannel`]: Returns the guild's channel where admins and
moderators of the guild receive safety alerts from Discord. The guild must be a
Community guild.
If no channel is set, then this returns ``None``.
.. versionadded:: 2.9
"""
channel_id = self._safety_alerts_channel_id
return channel_id and self._channels.get(channel_id) # type: ignore

@property
def emoji_limit(self) -> int:
""":class:`int`: The maximum number of emoji slots this guild has.
Expand Down Expand Up @@ -1843,6 +1861,7 @@ async def edit(
discovery_splash: Optional[AssetBytes] = MISSING,
community: bool = MISSING,
invites_disabled: bool = MISSING,
raid_alerts_disabled: bool = MISSING,
afk_channel: Optional[VoiceChannel] = MISSING,
owner: Snowflake = MISSING,
afk_timeout: int = MISSING,
Expand All @@ -1855,6 +1874,7 @@ async def edit(
preferred_locale: Locale = MISSING,
rules_channel: Optional[TextChannel] = MISSING,
public_updates_channel: Optional[TextChannel] = MISSING,
safety_alerts_channel: Optional[TextChannel] = MISSING,
premium_progress_bar_enabled: bool = MISSING,
) -> Guild:
"""|coro|
Expand Down Expand Up @@ -1935,6 +1955,16 @@ async def edit(
.. versionadded:: 2.6
raid_alerts_disabled: :class:`bool`
Whether the guild has disabled join raid alerts.
This is only available to guilds that contain ``COMMUNITY``
in :attr:`Guild.features`.
This cannot be changed at the same time as the ``community`` feature due a Discord API limitation.
.. versionadded:: 2.9
afk_channel: Optional[:class:`VoiceChannel`]
The new channel that is the AFK channel. Could be ``None`` for no AFK channel.
afk_timeout: :class:`int`
Expand Down Expand Up @@ -1969,6 +1999,13 @@ async def edit(
The new channel that is used for public updates from Discord. This is only available to
guilds that contain ``COMMUNITY`` in :attr:`Guild.features`. Could be ``None`` for no
public updates channel.
safety_alerts_channel: Optional[:class:`TextChannel`]
The new channel that is used for safety alerts. This is only available to
guilds that contain ``COMMUNITY`` in :attr:`Guild.features`. Could be ``None`` for no
safety alerts channel.
.. versionadded:: 2.9
premium_progress_bar_enabled: :class:`bool`
Whether the server boost progress bar is enabled.
reason: Optional[:class:`str`]
Expand All @@ -1991,7 +2028,7 @@ async def edit(
``community`` was set without setting both ``rules_channel`` and ``public_updates_channel`` parameters,
or if you are not the owner of the guild and request an ownership transfer,
or the image format passed in to ``icon`` is invalid,
or both ``community`` and ``invites_disabled`` were provided.
or both ``community`` and ``invites_disabled` or ``raid_alerts_disabled`` were provided.
Returns
-------
Expand Down Expand Up @@ -2058,6 +2095,12 @@ async def edit(
else:
fields["public_updates_channel_id"] = public_updates_channel.id

if safety_alerts_channel is not MISSING:
if safety_alerts_channel is None:
fields["safety_alerts_channel_id"] = safety_alerts_channel
else:
fields["safety_alerts_channel_id"] = safety_alerts_channel.id

if owner is not MISSING:
if self.owner_id != self._state.self_id:
raise ValueError("To transfer ownership you must be the owner of the guild.")
Expand All @@ -2082,7 +2125,11 @@ async def edit(

fields["system_channel_flags"] = system_channel_flags.value

if community is not MISSING or invites_disabled is not MISSING:
if (
community is not MISSING
or invites_disabled is not MISSING
or raid_alerts_disabled is not MISSING
):
# If we don't have complete feature information for the guild,
# it is possible to disable or enable other features that we didn't intend to touch.
# To enable or disable a feature, we will need to provide all of the existing features in advance.
Expand Down Expand Up @@ -2117,6 +2164,19 @@ async def edit(
else:
features.discard("INVITES_DISABLED")

if raid_alerts_disabled is not MISSING:
if community is not MISSING:
raise ValueError(
"cannot modify both the COMMUNITY feature and RAID_ALERTS_DISABLED feature at the "
"same time due to a discord limitation."
)
if not isinstance(raid_alerts_disabled, bool):
raise TypeError("raid_alerts_disabled must be a bool")
if raid_alerts_disabled:
features.add("RAID_ALERTS_DISABLED")
else:
features.discard("RAID_ALERTS_DISABLED")

fields["features"] = list(features)

if premium_progress_bar_enabled is not MISSING:
Expand Down
1 change: 1 addition & 0 deletions disnake/http.py
Original file line number Diff line number Diff line change
Expand Up @@ -1370,6 +1370,7 @@ def edit_guild(
"public_updates_channel_id",
"preferred_locale",
"premium_progress_bar_enabled",
"safety_alerts_channel_id",
)

payload = {k: v for k, v in fields.items() if k in valid_keys}
Expand Down
2 changes: 2 additions & 0 deletions disnake/types/guild.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ class UnavailableGuild(TypedDict):
"PARTNERED",
"PREVIEW_ENABLED",
"PRIVATE_THREADS", # deprecated
"RAID_ALERTS_DISABLED",
"RELAY_ENABLED",
"ROLE_ICONS",
"ROLE_SUBSCRIPTIONS_AVAILABLE_FOR_PURCHASE",
Expand Down Expand Up @@ -128,6 +129,7 @@ class Guild(_BaseGuildPreview):
nsfw_level: NSFWLevel
stickers: NotRequired[List[GuildSticker]]
premium_progress_bar_enabled: bool
safety_alerts_channel_id: Optional[Snowflake]

# specific to GUILD_CREATE event
joined_at: NotRequired[Optional[str]]
Expand Down
4 changes: 2 additions & 2 deletions docs/locale/ja/LC_MESSAGES/api.po
Original file line number Diff line number Diff line change
Expand Up @@ -10504,13 +10504,13 @@ msgstr ":class:`bytes`"

#: disnake.Guild.rules_channel:1 of
msgid ""
"Return's the guild's channel used for the rules. Must be a discoverable "
"Returns the guild's channel used for the rules. Must be a discoverable "
"guild."
msgstr ""

#: disnake.Guild.public_updates_channel:1 of
msgid ""
"Return's the guild's channel where admins and moderators of the guilds "
"Returns the guild's channel where admins and moderators of the guilds "
"receive notices from Discord. This is only available to guilds that "
"contain ``PUBLIC`` in :attr:`Guild.features`."
msgstr ""
Expand Down

0 comments on commit 53095a6

Please sign in to comment.