Browse Source

Add support for voice messages

Co-authored-by: Danny <[email protected]>
pull/10109/head
Andrin S 2 years ago
committed by dolfies
parent
commit
f066597a02
  1. 6
      discord/flags.py
  2. 21
      discord/message.py
  3. 16
      discord/permissions.py
  4. 2
      discord/types/message.py
  5. 6
      discord/utils.py

6
discord/flags.py

@ -619,10 +619,10 @@ class MessageFlags(BaseFlags):
return 4096
@flag_value
def is_voice_message(self):
""":class:`bool`: Returns ``True`` if the message's audio attachments are rendered as voice messages.
def voice(self):
""":class:`bool`: Returns ``True`` if the message is a voice message.
.. versionadded:: 2.0
.. versionadded:: 2.1
"""
return 8192

21
discord/message.py

@ -191,6 +191,14 @@ class Attachment(Hashable):
Whether the attachment is ephemeral.
.. 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.1
waveform: Optional[:class:`bytes`]
The waveform (amplitudes) of the audio in bytes. Returns ``None`` if it's not a voice message.
.. versionadded:: 2.1
"""
__slots__ = (
@ -205,6 +213,8 @@ class Attachment(Hashable):
'content_type',
'description',
'ephemeral',
'duration',
'waveform',
)
def __init__(self, *, data: AttachmentPayload, state: ConnectionState):
@ -219,11 +229,22 @@ class Attachment(Hashable):
self.content_type: Optional[str] = data.get('content_type')
self.description: Optional[str] = data.get('description')
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:
""":class:`bool`: Whether this attachment contains a spoiler."""
return self.filename.startswith('SPOILER_')
def is_voice_message(self) -> bool:
""":class:`bool`: Whether this attachment is a voice message.
.. versionadded:: 2.1
"""
return self.waveform is not None
def __repr__(self) -> str:
return f'<Attachment id={self.id} filename={self.filename!r} url={self.url!r}>'

16
discord/permissions.py

@ -177,7 +177,7 @@ class Permissions(BaseFlags):
"""A factory method that creates a :class:`Permissions` with all
permissions set to ``True``.
"""
return cls(0b1111111111111111111111111111111111111111111111)
return cls(0b11111111111111111111111111111111111111111111111)
@classmethod
def _timeout_mask(cls) -> int:
@ -261,8 +261,11 @@ class Permissions(BaseFlags):
.. versionchanged:: 2.0
Added :attr:`create_public_threads`, :attr:`create_private_threads`, :attr:`manage_threads`,
:attr:`send_messages_in_threads` and :attr:`use_external_stickers` permissions.
.. versionchanged:: 2.1
Added :attr:`send_voice_messages` permission.
"""
return cls(0b111110010000000000001111111100001000000)
return cls(0b10000000111110010000000000001111111100001000000)
@classmethod
def voice(cls) -> Self:
@ -671,6 +674,14 @@ class Permissions(BaseFlags):
"""
return 1 << 45
@flag_value
def send_voice_messages(self) -> int:
""":class:`bool`: Returns ``True`` if a user can send voice messages.
.. versionadded:: 2.1
"""
return 1 << 46
def _augment_from_permissions(cls):
cls.VALID_NAMES = set(Permissions.VALID_FLAGS)
@ -788,6 +799,7 @@ class PermissionOverwrite:
moderate_members: Optional[bool]
use_soundboard: Optional[bool]
use_external_sounds: Optional[bool]
send_voice_messages: Optional[bool]
def __init__(self, **kwargs: Optional[bool]):
self._values: Dict[str, Optional[bool]] = {}

2
discord/types/message.py

@ -70,6 +70,8 @@ class Attachment(TypedDict):
content_type: NotRequired[str]
spoiler: NotRequired[bool]
ephemeral: NotRequired[bool]
duration_secs: NotRequired[float]
waveform: NotRequired[str]
MessageActivityType = Literal[1, 2, 3, 5]

6
discord/utils.py

@ -56,7 +56,7 @@ from typing import (
)
import collections
import unicodedata
from base64 import b64encode
from base64 import b64encode, b64decode
from bisect import bisect_left
import datetime
import functools
@ -705,6 +705,10 @@ def _bytes_to_base64_data(data: bytes) -> str:
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:
return parent == child or child.startswith(parent + '.')

Loading…
Cancel
Save