mirror of
https://github.com/Rapptz/discord.py.git
synced 2025-05-16 18:59:09 +00:00
Add support for voice messages
Co-authored-by: Danny <1695103+Rapptz@users.noreply.github.com>
This commit is contained in:
parent
bee2db805d
commit
1767be0081
@ -451,6 +451,14 @@ class MessageFlags(BaseFlags):
|
|||||||
"""
|
"""
|
||||||
return 4096
|
return 4096
|
||||||
|
|
||||||
|
@flag_value
|
||||||
|
def voice(self):
|
||||||
|
""":class:`bool`: Returns ``True`` if the message is a voice message.
|
||||||
|
|
||||||
|
.. versionadded:: 2.3
|
||||||
|
"""
|
||||||
|
return 8192
|
||||||
|
|
||||||
|
|
||||||
@fill_with_flags()
|
@fill_with_flags()
|
||||||
class PublicUserFlags(BaseFlags):
|
class PublicUserFlags(BaseFlags):
|
||||||
|
@ -183,6 +183,14 @@ class Attachment(Hashable):
|
|||||||
Whether the attachment is ephemeral.
|
Whether the attachment is ephemeral.
|
||||||
|
|
||||||
.. versionadded:: 2.0
|
.. versionadded:: 2.0
|
||||||
|
duration: Optional[:class:`float`]
|
||||||
|
The duration of the audio file in seconds. Returns ``None`` if it's not a voice message.
|
||||||
|
|
||||||
|
.. versionadded:: 2.3
|
||||||
|
waveform: Optional[:class:`bytes`]
|
||||||
|
The waveform (amplitudes) of the audio in bytes. Returns ``None`` if it's not a voice message.
|
||||||
|
|
||||||
|
.. versionadded:: 2.3
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__slots__ = (
|
__slots__ = (
|
||||||
@ -197,6 +205,8 @@ class Attachment(Hashable):
|
|||||||
'content_type',
|
'content_type',
|
||||||
'description',
|
'description',
|
||||||
'ephemeral',
|
'ephemeral',
|
||||||
|
'duration',
|
||||||
|
'waveform',
|
||||||
)
|
)
|
||||||
|
|
||||||
def __init__(self, *, data: AttachmentPayload, state: ConnectionState):
|
def __init__(self, *, data: AttachmentPayload, state: ConnectionState):
|
||||||
@ -211,11 +221,19 @@ class Attachment(Hashable):
|
|||||||
self.content_type: Optional[str] = data.get('content_type')
|
self.content_type: Optional[str] = data.get('content_type')
|
||||||
self.description: Optional[str] = data.get('description')
|
self.description: Optional[str] = data.get('description')
|
||||||
self.ephemeral: bool = data.get('ephemeral', False)
|
self.ephemeral: bool = data.get('ephemeral', False)
|
||||||
|
self.duration: Optional[float] = data.get('duration_secs')
|
||||||
|
|
||||||
|
waveform = data.get('waveform')
|
||||||
|
self.waveform: Optional[bytes] = utils._base64_to_bytes(waveform) if waveform is not None else None
|
||||||
|
|
||||||
def is_spoiler(self) -> bool:
|
def is_spoiler(self) -> bool:
|
||||||
""":class:`bool`: Whether this attachment contains a spoiler."""
|
""":class:`bool`: Whether this attachment contains a spoiler."""
|
||||||
return self.filename.startswith('SPOILER_')
|
return self.filename.startswith('SPOILER_')
|
||||||
|
|
||||||
|
def is_voice_message(self) -> bool:
|
||||||
|
""":class:`bool`: Whether this attachment is a voice message."""
|
||||||
|
return self.duration is not None and 'voice-message' in self.url
|
||||||
|
|
||||||
def __repr__(self) -> str:
|
def __repr__(self) -> str:
|
||||||
return f'<Attachment id={self.id} filename={self.filename!r} url={self.url!r}>'
|
return f'<Attachment id={self.id} filename={self.filename!r} url={self.url!r}>'
|
||||||
|
|
||||||
|
@ -177,7 +177,7 @@ class Permissions(BaseFlags):
|
|||||||
"""A factory method that creates a :class:`Permissions` with all
|
"""A factory method that creates a :class:`Permissions` with all
|
||||||
permissions set to ``True``.
|
permissions set to ``True``.
|
||||||
"""
|
"""
|
||||||
return cls(0b1111111111111111111111111111111111111111111111)
|
return cls(0b11111111111111111111111111111111111111111111111)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def _timeout_mask(cls) -> int:
|
def _timeout_mask(cls) -> int:
|
||||||
@ -261,8 +261,11 @@ class Permissions(BaseFlags):
|
|||||||
.. versionchanged:: 2.0
|
.. versionchanged:: 2.0
|
||||||
Added :attr:`create_public_threads`, :attr:`create_private_threads`, :attr:`manage_threads`,
|
Added :attr:`create_public_threads`, :attr:`create_private_threads`, :attr:`manage_threads`,
|
||||||
:attr:`send_messages_in_threads` and :attr:`use_external_stickers` permissions.
|
:attr:`send_messages_in_threads` and :attr:`use_external_stickers` permissions.
|
||||||
|
|
||||||
|
.. versionchanged:: 2.3
|
||||||
|
Added :attr:`send_voice_messages` permission.
|
||||||
"""
|
"""
|
||||||
return cls(0b111110010000000000001111111100001000000)
|
return cls(0b10000000111110010000000000001111111100001000000)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def voice(cls) -> Self:
|
def voice(cls) -> Self:
|
||||||
@ -671,6 +674,14 @@ class Permissions(BaseFlags):
|
|||||||
"""
|
"""
|
||||||
return 1 << 45
|
return 1 << 45
|
||||||
|
|
||||||
|
@flag_value
|
||||||
|
def send_voice_messages(self) -> int:
|
||||||
|
""":class:`bool`: Returns ``True`` if a user can send voice messages.
|
||||||
|
|
||||||
|
.. versionadded:: 2.3
|
||||||
|
"""
|
||||||
|
return 1 << 46
|
||||||
|
|
||||||
|
|
||||||
def _augment_from_permissions(cls):
|
def _augment_from_permissions(cls):
|
||||||
cls.VALID_NAMES = set(Permissions.VALID_FLAGS)
|
cls.VALID_NAMES = set(Permissions.VALID_FLAGS)
|
||||||
@ -788,6 +799,7 @@ class PermissionOverwrite:
|
|||||||
moderate_members: Optional[bool]
|
moderate_members: Optional[bool]
|
||||||
use_soundboard: Optional[bool]
|
use_soundboard: Optional[bool]
|
||||||
use_external_sounds: Optional[bool]
|
use_external_sounds: Optional[bool]
|
||||||
|
send_voice_messages: Optional[bool]
|
||||||
|
|
||||||
def __init__(self, **kwargs: Optional[bool]):
|
def __init__(self, **kwargs: Optional[bool]):
|
||||||
self._values: Dict[str, Optional[bool]] = {}
|
self._values: Dict[str, Optional[bool]] = {}
|
||||||
|
@ -68,6 +68,8 @@ class Attachment(TypedDict):
|
|||||||
content_type: NotRequired[str]
|
content_type: NotRequired[str]
|
||||||
spoiler: NotRequired[bool]
|
spoiler: NotRequired[bool]
|
||||||
ephemeral: NotRequired[bool]
|
ephemeral: NotRequired[bool]
|
||||||
|
duration_secs: NotRequired[float]
|
||||||
|
waveform: NotRequired[str]
|
||||||
|
|
||||||
|
|
||||||
MessageActivityType = Literal[1, 2, 3, 5]
|
MessageActivityType = Literal[1, 2, 3, 5]
|
||||||
|
@ -56,7 +56,7 @@ from typing import (
|
|||||||
TYPE_CHECKING,
|
TYPE_CHECKING,
|
||||||
)
|
)
|
||||||
import unicodedata
|
import unicodedata
|
||||||
from base64 import b64encode
|
from base64 import b64encode, b64decode
|
||||||
from bisect import bisect_left
|
from bisect import bisect_left
|
||||||
import datetime
|
import datetime
|
||||||
import functools
|
import functools
|
||||||
@ -628,6 +628,10 @@ def _bytes_to_base64_data(data: bytes) -> str:
|
|||||||
return fmt.format(mime=mime, data=b64)
|
return fmt.format(mime=mime, data=b64)
|
||||||
|
|
||||||
|
|
||||||
|
def _base64_to_bytes(data: str) -> bytes:
|
||||||
|
return b64decode(data.encode('ascii'))
|
||||||
|
|
||||||
|
|
||||||
def _is_submodule(parent: str, child: str) -> bool:
|
def _is_submodule(parent: str, child: str) -> bool:
|
||||||
return parent == child or child.startswith(parent + '.')
|
return parent == child or child.startswith(parent + '.')
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user