Add support for creating parties #35

Open
wasi-master wants to merge 2 commits from wasi-master/2.0 into 2.0
4 changed files with 137 additions and 1 deletions

View File

@ -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,76 @@ class PartialMessageable(discord.abc.Messageable, Hashable):
return PartialMessage(channel=self, id=message_id)
class Party:
"""Represents a party in a voice channel.
.. container:: operations
.. describe:: x == y
Checks if two party are equal.
.. describe:: x != y
Checks if two party are not equal.
.. describe:: hash(x)
Returns the party hash.
.. describe:: str(x)
Returns the party URL.
Attributes
-----------
code: :class:`str`
The URL fragment used for the party.
uses: :class:`int`
How many times the invite has been used.
max_uses: :class:`int`
How many times the invite can be used.
A value of ``0`` indicates that it has unlimited uses.
max_age: :class:`int`
How long before the party expires in seconds.
A value of ``0`` indicates that it doesn't expire.
temporary: :class:`bool`
Indicates that the invite grants temporary membership.
If ``True``, members who joined via this invite will be kicked upon disconnect.
created_at: :class:`datetime.datetime`
An aware UTC datetime object denoting the time the invite was created.
Note
----
Parties are still in BETA so there are some limitations.
Currently this BETA feature is only supported on web and updated PC app versions of Discord and is not supported on mobile.
First someone has to to click the blue link itself and not the join button, then everyone else can click the join button normally.
"""
__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'<Party code={self.code}>'
def __str__(self):
return f'https://discord.gg/{self.code}'
def __hash__(self) -> int:
return hash(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)

View File

@ -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'

View File

@ -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(

View File

@ -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