From 8ec591e46b85bdd39663aa27ca85a70c0db7bf72 Mon Sep 17 00:00:00 2001 From: Wasi Master <63045920+wasi-master@users.noreply.github.com> Date: Mon, 30 Aug 2021 11:43:03 +0600 Subject: [PATCH] Add support for creating parties --- discord/channel.py | 58 +++++++++++++++++++++++++++++++++++++++- discord/enums.py | 9 +++++++ discord/http.py | 18 +++++++++++++ discord/types/channel.py | 7 +++++ 4 files changed, 91 insertions(+), 1 deletion(-) diff --git a/discord/channel.py b/discord/channel.py index be3315cf..9b4eeee7 100644 --- a/discord/channel.py +++ b/discord/channel.py @@ -45,7 +45,7 @@ import datetime import discord.abc from .permissions import PermissionOverwrite, Permissions -from .enums import ChannelType, StagePrivacyLevel, try_enum, VoiceRegion, VideoQualityMode +from .enums import ChannelType, StagePrivacyLevel, try_enum, VoiceRegion, VideoQualityMode, PartyType from .mixins import Hashable from .object import Object from . import utils @@ -1037,6 +1037,38 @@ class VoiceChannel(VocalGuildChannel): # the payload will always be the proper channel payload return self.__class__(state=self._state, guild=self.guild, data=payload) # type: ignore + async def create_party(self, application_id: PartyType, max_age: int = 86400 , max_uses: int = 0): + """|coro| + Creates a party in this voice channel. + + .. versionadded:: 2.0 + + Parameters + ---------- + application_id : :class:`PartyType` + The id of the application the party belongs to. currently any of + ``PartyType.youtube``, ``PartyType.poker``, ``PartyType.betrayal``, ``PartyType.fishing``, ``PartyType.chess``. + max_age : :class:`int`, optional + Duration in seconds after which the invite expires, by default 1 day. + max_uses : :class:`int`, optional + maximum number of times this invite can be used, by default unlimited. + + Raises + ------- + Forbidden + You do not have permissions to create a party. + HTTPException + Party creation failed. + + Returns + -------- + :class:`Party` + The created party. + """ + return Party(await self._state.http.create_party(self.id, application_id.value, max_age=max_age, max_uses=max_uses)) + + + class StageChannel(VocalGuildChannel): """Represents a Discord guild stage channel. @@ -2038,6 +2070,30 @@ class PartialMessageable(discord.abc.Messageable, Hashable): return PartialMessage(channel=self, id=message_id) +class Party: + """Represents a party in a voice channel.""" + + __slots__ = ('code', 'uses', 'max_uses', 'max_age', 'temporary', 'created_at') + + def __init__(self, data): + self.code: str = data['code'] + self.uses: Optional[int] = data.get('uses') + self.max_uses: Optional[int] = data.get('max_uses') + self.max_age: Optional[int] = data.get('max_age') + self.temporary: Optional[bool] = data.get('temporary') + self.created_at: Optional[datetime.datetime] = utils.parse_time(data.get('created_at')) + # TODO: add more fields here such as guild. raw data: https://mystb.in/AdvertisersExperiencesMothers.json + + def __repr__(self): + return f'' + + def __str__(self): + return f'https://discord.gg/{self.code}' + + def __eq__(self, other): + return isinstance(other, Party) and self.code == other.code + + def _guild_channel_factory(channel_type: int): value = try_enum(ChannelType, channel_type) diff --git a/discord/enums.py b/discord/enums.py index af8ee2b0..6a26bc41 100644 --- a/discord/enums.py +++ b/discord/enums.py @@ -30,6 +30,7 @@ __all__ = ( 'Enum', 'ChannelType', 'MessageType', + 'PartyType', 'VoiceRegion', 'SpeakingState', 'VerificationLevel', @@ -214,6 +215,14 @@ class MessageType(Enum): guild_invite_reminder = 22 +class PartyType(Enum): + youtube = 755600276941176913 + poker = 755827207812677713 + betrayal = 773336526917861400 + fishing = 814288819477020702 + chess = 832012774040141894 + + class VoiceRegion(Enum): us_west = 'us-west' us_east = 'us-east' diff --git a/discord/http.py b/discord/http.py index 7a4c2adc..625a206d 100644 --- a/discord/http.py +++ b/discord/http.py @@ -880,6 +880,24 @@ class HTTPClient: ) -> Response[None]: return self.request(Route('DELETE', '/channels/{channel_id}', channel_id=channel_id), reason=reason) + def create_party( + self, + channel_id: Snowflake, + application_id: Snowflake, + max_age: int, + max_uses: int, + ) -> Response[channel.Party]: + payload = { + 'max_age': max_age, + 'max_uses': max_uses, + 'target_application_id': application_id, + 'target_type': 2, + 'temporary': False, + 'validate': None + } + return self.request(Route("POST", "/channels/{channel_id}/invites", channel_id=channel_id), json=payload) + + # Thread management def start_thread_with_message( diff --git a/discord/types/channel.py b/discord/types/channel.py index a35351e4..c2b0b524 100644 --- a/discord/types/channel.py +++ b/discord/types/channel.py @@ -155,3 +155,10 @@ class StageInstance(TypedDict): topic: str privacy_level: PrivacyLevel discoverable_disabled: bool + +class Party(TypedDict): + uses: int + max_uses: int + max_age: int + temporary: bool + created_at: str