Add invite targets for voice channel invites
This commit is contained in:
parent
f321efd4de
commit
b48f510e15
@ -62,6 +62,7 @@ if TYPE_CHECKING:
|
||||
from .channel import CategoryChannel
|
||||
from .embeds import Embed
|
||||
from .message import Message, MessageReference
|
||||
from .enums import InviteTarget
|
||||
|
||||
SnowflakeTime = Union["Snowflake", datetime]
|
||||
|
||||
@ -1013,6 +1014,9 @@ class GuildChannel:
|
||||
max_uses: int = 0,
|
||||
temporary: bool = False,
|
||||
unique: bool = True,
|
||||
target_type: Optional[InviteTarget] = None,
|
||||
target_user: Optional[User] = None,
|
||||
target_application_id: Optional[int] = None
|
||||
) -> Invite:
|
||||
"""|coro|
|
||||
|
||||
@ -1038,6 +1042,20 @@ class GuildChannel:
|
||||
invite.
|
||||
reason: Optional[:class:`str`]
|
||||
The reason for creating this invite. Shows up on the audit log.
|
||||
target_type: Optional[:class:`InviteTarget`]
|
||||
The type of target for the voice channel invite, if any.
|
||||
|
||||
.. versionadded:: 2.0
|
||||
|
||||
target_user: Optional[:class:`User`]
|
||||
The user whose stream to display for this invite, required if `target_type` is `TargetType.stream`. The user must be streaming in the channel.
|
||||
|
||||
.. versionadded:: 2.0
|
||||
|
||||
target_application_id:: Optional[:class:`int`]
|
||||
The id of the embedded application for the invite, required if `target_type` is `TargetType.embedded_application`.
|
||||
|
||||
.. versionadded:: 2.0
|
||||
|
||||
Raises
|
||||
-------
|
||||
@ -1060,6 +1078,9 @@ class GuildChannel:
|
||||
max_uses=max_uses,
|
||||
temporary=temporary,
|
||||
unique=unique,
|
||||
target_type=target_type.value if target_type else None,
|
||||
target_user_id=target_user.id if target_user else None,
|
||||
target_application_id=target_application_id
|
||||
)
|
||||
return Invite.from_incomplete(data=data, state=self._state)
|
||||
|
||||
|
@ -22,13 +22,22 @@ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING, Optional
|
||||
|
||||
from . import utils
|
||||
from .user import User
|
||||
from .asset import Asset
|
||||
from .team import Team
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from .guild import Guild
|
||||
from .types.appinfo import AppInfo as AppInfoPayload, PartialAppInfo as PartialAppInfoPayload
|
||||
|
||||
from .state import ConnectionState
|
||||
|
||||
__all__ = (
|
||||
'AppInfo',
|
||||
'PartialAppInfo',
|
||||
)
|
||||
|
||||
|
||||
@ -49,7 +58,7 @@ class AppInfo:
|
||||
|
||||
.. versionadded:: 1.3
|
||||
|
||||
description: Optional[:class:`str`]
|
||||
description: :class:`str`
|
||||
The application description.
|
||||
bot_public: :class:`bool`
|
||||
Whether the bot can be invited by anyone or if it is locked
|
||||
@ -122,9 +131,10 @@ class AppInfo:
|
||||
'privacy_policy_url',
|
||||
)
|
||||
|
||||
def __init__(self, state, data):
|
||||
self._state = state
|
||||
def __init__(self, state, data: AppInfoPayload):
|
||||
from .team import Team
|
||||
|
||||
self._state = state
|
||||
self.id = int(data['id'])
|
||||
self.name = data['name']
|
||||
self.description = data['description']
|
||||
@ -132,7 +142,7 @@ class AppInfo:
|
||||
self.rpc_origins = data['rpc_origins']
|
||||
self.bot_public = data['bot_public']
|
||||
self.bot_require_code_grant = data['bot_require_code_grant']
|
||||
self.owner = User(state=self._state, data=data['owner'])
|
||||
self.owner = state.store_user(data['owner'])
|
||||
|
||||
team = data.get('team')
|
||||
self.team = Team(state, team) if team else None
|
||||
@ -148,7 +158,7 @@ class AppInfo:
|
||||
self.terms_of_service_url = data.get('terms_of_service_url')
|
||||
self.privacy_policy_url = data.get('privacy_policy_url')
|
||||
|
||||
def __repr__(self):
|
||||
def __repr__(self) -> str:
|
||||
return (
|
||||
f'<{self.__class__.__name__} id={self.id} name={self.name!r} '
|
||||
f'description={self.description!r} public={self.bot_public} '
|
||||
@ -156,14 +166,14 @@ class AppInfo:
|
||||
)
|
||||
|
||||
@property
|
||||
def icon(self):
|
||||
def icon(self) -> Optional[Asset]:
|
||||
"""Optional[:class:`.Asset`]: Retrieves the application's icon asset, if any."""
|
||||
if self._icon is None:
|
||||
return None
|
||||
return Asset._from_icon(self._state, self.id, self._icon, path='app')
|
||||
|
||||
@property
|
||||
def cover_image(self):
|
||||
def cover_image(self) -> Optional[Asset]:
|
||||
"""Optional[:class:`.Asset`]: Retrieves the cover image on a store embed, if any.
|
||||
|
||||
This is only available if the application is a game sold on Discord.
|
||||
@ -173,10 +183,61 @@ class AppInfo:
|
||||
return Asset._from_cover_image(self._state, self.id, self._cover_image)
|
||||
|
||||
@property
|
||||
def guild(self):
|
||||
def guild(self) -> Optional[Guild]:
|
||||
"""Optional[:class:`Guild`]: If this application is a game sold on Discord,
|
||||
this field will be the guild to which it has been linked
|
||||
|
||||
.. versionadded:: 1.3
|
||||
"""
|
||||
return self._state._get_guild(int(self.guild_id))
|
||||
return self._state._get_guild(self.guild_id)
|
||||
|
||||
class PartialAppInfo:
|
||||
"""Represents a partial AppInfo given by :func:`~GuildChannel.create_invite`
|
||||
|
||||
.. versionadded:: 2.0
|
||||
|
||||
Attributes
|
||||
-------------
|
||||
id: :class:`int`
|
||||
The application ID.
|
||||
name: :class:`str`
|
||||
The application name.
|
||||
description: :class:`str`
|
||||
The application description.
|
||||
rpc_origins: Optional[List[:class:`str`]]
|
||||
A list of RPC origin URLs, if RPC is enabled.
|
||||
summary: :class:`str`
|
||||
If this application is a game sold on Discord,
|
||||
this field will be the summary field for the store page of its primary SKU.
|
||||
verify_key: :class:`str`
|
||||
The hex encoded key for verification in interactions and the
|
||||
GameSDK's `GetTicket <https://discord.com/developers/docs/game-sdk/applications#getticket>`_.
|
||||
terms_of_service_url: Optional[:class:`str`]
|
||||
The application's terms of service URL, if set.
|
||||
privacy_policy_url: Optional[:class:`str`]
|
||||
The application's privacy policy URL, if set.
|
||||
"""
|
||||
|
||||
__slots__ = ('_state', 'id', 'name', 'description', 'rpc_origins', 'summary', 'verify_key', 'terms_of_service_url', 'privacy_policy_url', '_icon')
|
||||
|
||||
def __init__(self, *, state: ConnectionState, data: PartialAppInfoPayload):
|
||||
self._state = state
|
||||
self.id = int(data['id'])
|
||||
self.name = data['name']
|
||||
self._icon = data.get('icon')
|
||||
self.description = data['description']
|
||||
self.rpc_origins = data.get('rpc_origins')
|
||||
self.summary = data['summary']
|
||||
self.verify_key = data['verify_key']
|
||||
self.terms_of_service_url = data.get('terms_of_service_url')
|
||||
self.privacy_policy_url = data.get('privacy_policy_url')
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f'<{self.__class__.__name__} id={self.id} name={self.name!r} description={self.description!r}>'
|
||||
|
||||
@property
|
||||
def icon(self) -> Optional[Asset]:
|
||||
"""Optional[:class:`.Asset`]: Retrieves the application's icon asset, if any."""
|
||||
if self._icon is None:
|
||||
return None
|
||||
return Asset._from_icon(self._state, self.id, self._icon, path='app')
|
||||
|
@ -431,7 +431,7 @@ class StickerType(Enum):
|
||||
|
||||
class InviteTarget(Enum):
|
||||
unknown = 0
|
||||
stream = 1
|
||||
stream = 1
|
||||
embedded_application = 2
|
||||
|
||||
class InteractionType(Enum):
|
||||
|
@ -981,6 +981,9 @@ class HTTPClient:
|
||||
max_uses: int = 0,
|
||||
temporary: bool = False,
|
||||
unique: bool = True,
|
||||
target_type: Optional[int] = None,
|
||||
target_user_id: Optional[int] = None,
|
||||
target_application_id: Optional[int] = None
|
||||
) -> Response[invite.Invite]:
|
||||
r = Route('POST', '/channels/{channel_id}/invites', channel_id=channel_id)
|
||||
payload = {
|
||||
@ -990,6 +993,15 @@ class HTTPClient:
|
||||
'unique': unique,
|
||||
}
|
||||
|
||||
if target_type:
|
||||
payload['target_type'] = target_type
|
||||
|
||||
if target_user_id:
|
||||
payload['target_user_id'] = target_user_id
|
||||
|
||||
if target_application_id:
|
||||
payload['target_application_id'] = str(target_application_id)
|
||||
|
||||
return self.request(r, reason=reason, json=payload)
|
||||
|
||||
def get_invite(self, invite_id, *, with_counts=True, with_expiration=True):
|
||||
|
@ -30,6 +30,7 @@ from .utils import parse_time, snowflake_time, _get_as_snowflake
|
||||
from .object import Object
|
||||
from .mixins import Hashable
|
||||
from .enums import ChannelType, VerificationLevel, InviteTarget, try_enum
|
||||
from .appinfo import PartialAppInfo
|
||||
|
||||
__all__ = (
|
||||
'PartialInviteChannel',
|
||||
@ -277,12 +278,18 @@ class Invite(Hashable):
|
||||
|
||||
channel: Union[:class:`abc.GuildChannel`, :class:`Object`, :class:`PartialInviteChannel`]
|
||||
The channel the invite is for.
|
||||
target_type: :class:`InviteTarget`
|
||||
The type of target for the voice channel invite.
|
||||
|
||||
.. versionadded:: 2.0
|
||||
|
||||
target_user: Optional[:class:`User`]
|
||||
The target of this invite in the case of stream invites.
|
||||
The user whose stream to display for this invite, if any.
|
||||
|
||||
.. versionadded:: 2.0
|
||||
target_type: :class:`InviteTarget`
|
||||
The invite's target type.
|
||||
|
||||
target_application: Optional[:class:`PartialAppInfo`]
|
||||
The embedded application the invite targets, if any.
|
||||
|
||||
.. versionadded:: 2.0
|
||||
"""
|
||||
@ -303,6 +310,7 @@ class Invite(Hashable):
|
||||
'_state',
|
||||
'approximate_member_count',
|
||||
'approximate_presence_count',
|
||||
'target_application',
|
||||
'expires_at',
|
||||
)
|
||||
|
||||
@ -328,7 +336,11 @@ class Invite(Hashable):
|
||||
self.channel = data.get('channel')
|
||||
target_user_data = data.get('target_user')
|
||||
self.target_user = None if target_user_data is None else self._state.store_user(target_user_data)
|
||||
self.target_type = try_enum(InviteTarget, data.get('target_type', 0))
|
||||
|
||||
self.target_type = try_enum(InviteTarget, data.get("target_type", 0))
|
||||
|
||||
application = data.get('target_application')
|
||||
self.target_application = PartialAppInfo(data=application, state=state) if application else None
|
||||
|
||||
@classmethod
|
||||
def from_incomplete(cls, *, state, data):
|
||||
|
@ -22,11 +22,21 @@ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from . import utils
|
||||
from .user import BaseUser
|
||||
from .asset import Asset
|
||||
from .enums import TeamMembershipState, try_enum
|
||||
|
||||
from typing import TYPE_CHECKING, Optional
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from .types.team import (
|
||||
Team as TeamPayload,
|
||||
TeamMember as TeamMemberPayload,
|
||||
)
|
||||
|
||||
__all__ = (
|
||||
'Team',
|
||||
'TeamMember',
|
||||
@ -52,7 +62,7 @@ class Team:
|
||||
|
||||
__slots__ = ('_state', 'id', 'name', '_icon', 'owner_id', 'members')
|
||||
|
||||
def __init__(self, state, data):
|
||||
def __init__(self, state, data: TeamPayload):
|
||||
self._state = state
|
||||
|
||||
self.id = int(data['id'])
|
||||
@ -61,18 +71,18 @@ class Team:
|
||||
self.owner_id = utils._get_as_snowflake(data, 'owner_user_id')
|
||||
self.members = [TeamMember(self, self._state, member) for member in data['members']]
|
||||
|
||||
def __repr__(self):
|
||||
def __repr__(self) -> str:
|
||||
return f'<{self.__class__.__name__} id={self.id} name={self.name}>'
|
||||
|
||||
@property
|
||||
def icon(self):
|
||||
def icon(self) -> Optional[Asset]:
|
||||
"""Optional[:class:`.Asset`]: Retrieves the team's icon asset, if any."""
|
||||
if self._icon is None:
|
||||
return None
|
||||
return Asset._from_icon(self._state, self.id, self._icon, path='team')
|
||||
|
||||
@property
|
||||
def owner(self):
|
||||
def owner(self) -> Optional[TeamMember]:
|
||||
"""Optional[:class:`TeamMember`]: The team's owner."""
|
||||
return utils.get(self.members, id=self.owner_id)
|
||||
|
||||
@ -120,13 +130,13 @@ class TeamMember(BaseUser):
|
||||
|
||||
__slots__ = BaseUser.__slots__ + ('team', 'membership_state', 'permissions')
|
||||
|
||||
def __init__(self, team, state, data):
|
||||
def __init__(self, team: Team, state, data: TeamMemberPayload):
|
||||
self.team = team
|
||||
self.membership_state = try_enum(TeamMembershipState, data['membership_state'])
|
||||
self.permissions = data['permissions']
|
||||
super().__init__(state=state, data=data['user'])
|
||||
|
||||
def __repr__(self):
|
||||
def __repr__(self) -> str:
|
||||
return (
|
||||
f'<{self.__class__.__name__} id={self.id} name={self.name!r} '
|
||||
f'discriminator={self.discriminator!r} membership_state={self.membership_state!r}>'
|
||||
|
66
discord/types/appinfo.py
Normal file
66
discord/types/appinfo.py
Normal file
@ -0,0 +1,66 @@
|
||||
"""
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015-present Rapptz
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import TypedDict, List, Optional
|
||||
|
||||
from .user import User
|
||||
from .team import Team
|
||||
from .snowflake import Snowflake
|
||||
|
||||
class BaseAppInfo(TypedDict):
|
||||
id: Snowflake
|
||||
name: str
|
||||
verify_key: str
|
||||
icon: Optional[str]
|
||||
summary: str
|
||||
description: str
|
||||
|
||||
class _AppInfoOptional(TypedDict, total=False):
|
||||
team: Team
|
||||
guild_id: Snowflake
|
||||
primary_sku_id: Snowflake
|
||||
slug: str
|
||||
terms_of_service_url: str
|
||||
privacy_policy_url: str
|
||||
hook: bool
|
||||
max_participants: int
|
||||
|
||||
class AppInfo(BaseAppInfo, _AppInfoOptional):
|
||||
rpc_origins: List[str]
|
||||
owner: User
|
||||
bot_public: bool
|
||||
bot_require_code_grant: bool
|
||||
|
||||
class _PartialAppInfoOptional(TypedDict, total=False):
|
||||
rpc_origins: List[str]
|
||||
cover_image: str
|
||||
hook: bool
|
||||
terms_of_service_url: str
|
||||
privacy_policy_url: str
|
||||
max_participants: int
|
||||
|
||||
class PartialAppInfo(_PartialAppInfoOptional, BaseAppInfo):
|
||||
pass
|
@ -29,15 +29,17 @@ from typing import Literal, TypedDict
|
||||
from .guild import InviteGuild, _GuildPreviewUnique
|
||||
from .channel import PartialChannel
|
||||
from .user import PartialUser
|
||||
from .appinfo import PartialAppInfo
|
||||
|
||||
TargetUserType = Literal[1]
|
||||
InviteTargetType = Literal[1, 2]
|
||||
|
||||
|
||||
class _InviteOptional(TypedDict, total=False):
|
||||
guild: InviteGuild
|
||||
inviter: PartialUser
|
||||
target_user: PartialUser
|
||||
target_user_type: TargetUserType
|
||||
target_type: InviteTargetType
|
||||
target_application: PartialAppInfo
|
||||
|
||||
|
||||
class _InviteMetadata(TypedDict, total=False):
|
||||
|
43
discord/types/team.py
Normal file
43
discord/types/team.py
Normal file
@ -0,0 +1,43 @@
|
||||
"""
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015-present Rapptz
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import TypedDict, List
|
||||
|
||||
from .user import PartialUser
|
||||
from .snowflake import Snowflake
|
||||
|
||||
class TeamMember(TypedDict):
|
||||
user: PartialUser
|
||||
membership_state: int
|
||||
permissions: List[str]
|
||||
team_id: Snowflake
|
||||
|
||||
class Team(TypedDict):
|
||||
id: Snowflake
|
||||
name: str
|
||||
owner_id: Snowflake
|
||||
members: List[TeamMember]
|
||||
icon: str
|
15
docs/api.rst
15
docs/api.rst
@ -64,6 +64,14 @@ AppInfo
|
||||
.. autoclass:: AppInfo()
|
||||
:members:
|
||||
|
||||
PartialAppInfo
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
.. attributetable:: PartialAppInfo
|
||||
|
||||
.. autoclass:: PartialAppInfo()
|
||||
:members:
|
||||
|
||||
Team
|
||||
~~~~~
|
||||
|
||||
@ -2076,7 +2084,7 @@ of :class:`enum.Enum`.
|
||||
|
||||
.. class:: InviteTarget
|
||||
|
||||
Represents the type of target an invite contains.
|
||||
Represents the invite type for voice channel invites.
|
||||
|
||||
.. versionadded:: 2.0
|
||||
|
||||
@ -2086,11 +2094,11 @@ of :class:`enum.Enum`.
|
||||
|
||||
.. attribute:: stream
|
||||
|
||||
The invite targets a stream.
|
||||
A stream invite that targets a user.
|
||||
|
||||
.. attribute:: embedded_application
|
||||
|
||||
The invite targets an embedded application activity.
|
||||
A stream invite that targets an embedded application.
|
||||
|
||||
.. class:: VideoQualityMode
|
||||
|
||||
@ -2106,6 +2114,7 @@ of :class:`enum.Enum`.
|
||||
|
||||
Represents full camera video quality.
|
||||
|
||||
|
||||
Async Iterator
|
||||
----------------
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user