mirror of
https://github.com/Rapptz/discord.py.git
synced 2025-06-08 04:38:42 +00:00
Add support for message call
This commit is contained in:
parent
9d7c253535
commit
20c543f672
@ -76,6 +76,7 @@ if TYPE_CHECKING:
|
|||||||
MessageActivity as MessageActivityPayload,
|
MessageActivity as MessageActivityPayload,
|
||||||
RoleSubscriptionData as RoleSubscriptionDataPayload,
|
RoleSubscriptionData as RoleSubscriptionDataPayload,
|
||||||
MessageInteractionMetadata as MessageInteractionMetadataPayload,
|
MessageInteractionMetadata as MessageInteractionMetadataPayload,
|
||||||
|
CallMessage as CallMessagePayload,
|
||||||
)
|
)
|
||||||
|
|
||||||
from .types.interactions import MessageInteraction as MessageInteractionPayload
|
from .types.interactions import MessageInteraction as MessageInteractionPayload
|
||||||
@ -112,6 +113,7 @@ __all__ = (
|
|||||||
'MessageApplication',
|
'MessageApplication',
|
||||||
'RoleSubscriptionInfo',
|
'RoleSubscriptionInfo',
|
||||||
'MessageInteractionMetadata',
|
'MessageInteractionMetadata',
|
||||||
|
'CallMessage',
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -810,6 +812,51 @@ class MessageApplication:
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
class CallMessage:
|
||||||
|
"""Represents a message's call data in a private channel from a :class:`~discord.Message`.
|
||||||
|
|
||||||
|
.. versionadded:: 2.5
|
||||||
|
|
||||||
|
Attributes
|
||||||
|
-----------
|
||||||
|
ended_timestamp: Optional[:class:`datetime.datetime`]
|
||||||
|
The timestamp the call has ended.
|
||||||
|
participants: List[:class:`User`]
|
||||||
|
A list of users that participated in the call.
|
||||||
|
"""
|
||||||
|
|
||||||
|
__slots__ = ('_message', 'ended_timestamp', 'participants')
|
||||||
|
|
||||||
|
def __repr__(self) -> str:
|
||||||
|
return f'<CallMessage participants={self.participants!r}>'
|
||||||
|
|
||||||
|
def __init__(self, *, state: ConnectionState, message: Message, data: CallMessagePayload):
|
||||||
|
self._message: Message = message
|
||||||
|
self.ended_timestamp: Optional[datetime.datetime] = utils.parse_time(data.get('ended_timestamp'))
|
||||||
|
self.participants: List[User] = []
|
||||||
|
|
||||||
|
for user_id in data['participants']:
|
||||||
|
user_id = int(user_id)
|
||||||
|
if user_id == self._message.author.id:
|
||||||
|
self.participants.append(self._message.author) # type: ignore # can't be a Member here
|
||||||
|
else:
|
||||||
|
user = state.get_user(user_id)
|
||||||
|
if user is not None:
|
||||||
|
self.participants.append(user)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def duration(self) -> datetime.timedelta:
|
||||||
|
""":class:`datetime.timedelta`: The duration the call has lasted or is already ongoing."""
|
||||||
|
if self.ended_timestamp is None:
|
||||||
|
return utils.utcnow() - self._message.created_at
|
||||||
|
else:
|
||||||
|
return self.ended_timestamp - self._message.created_at
|
||||||
|
|
||||||
|
def is_ended(self) -> bool:
|
||||||
|
""":class:`bool`: Whether the call is ended or not."""
|
||||||
|
return self.ended_timestamp is not None
|
||||||
|
|
||||||
|
|
||||||
class RoleSubscriptionInfo:
|
class RoleSubscriptionInfo:
|
||||||
"""Represents a message's role subscription information.
|
"""Represents a message's role subscription information.
|
||||||
|
|
||||||
@ -1770,6 +1817,10 @@ class Message(PartialMessage, Hashable):
|
|||||||
The poll attached to this message.
|
The poll attached to this message.
|
||||||
|
|
||||||
.. versionadded:: 2.4
|
.. versionadded:: 2.4
|
||||||
|
call: Optional[:class:`CallMessage`]
|
||||||
|
The call associated with this message.
|
||||||
|
|
||||||
|
.. versionadded:: 2.5
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__slots__ = (
|
__slots__ = (
|
||||||
@ -1806,6 +1857,7 @@ class Message(PartialMessage, Hashable):
|
|||||||
'position',
|
'position',
|
||||||
'interaction_metadata',
|
'interaction_metadata',
|
||||||
'poll',
|
'poll',
|
||||||
|
'call',
|
||||||
)
|
)
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
@ -1931,7 +1983,7 @@ class Message(PartialMessage, Hashable):
|
|||||||
else:
|
else:
|
||||||
self.role_subscription = RoleSubscriptionInfo(role_subscription)
|
self.role_subscription = RoleSubscriptionInfo(role_subscription)
|
||||||
|
|
||||||
for handler in ('author', 'member', 'mentions', 'mention_roles', 'components'):
|
for handler in ('author', 'member', 'mentions', 'mention_roles', 'components', 'call'):
|
||||||
try:
|
try:
|
||||||
getattr(self, f'_handle_{handler}')(data[handler])
|
getattr(self, f'_handle_{handler}')(data[handler])
|
||||||
except KeyError:
|
except KeyError:
|
||||||
@ -2117,6 +2169,13 @@ class Message(PartialMessage, Hashable):
|
|||||||
def _handle_interaction_metadata(self, data: MessageInteractionMetadataPayload):
|
def _handle_interaction_metadata(self, data: MessageInteractionMetadataPayload):
|
||||||
self.interaction_metadata = MessageInteractionMetadata(state=self._state, guild=self.guild, data=data)
|
self.interaction_metadata = MessageInteractionMetadata(state=self._state, guild=self.guild, data=data)
|
||||||
|
|
||||||
|
def _handle_call(self, data: CallMessagePayload):
|
||||||
|
self.call: Optional[CallMessage]
|
||||||
|
if data is not None:
|
||||||
|
self.call = CallMessage(state=self._state, message=self, data=data)
|
||||||
|
else:
|
||||||
|
self.call = None
|
||||||
|
|
||||||
def _rebind_cached_references(
|
def _rebind_cached_references(
|
||||||
self,
|
self,
|
||||||
new_guild: Guild,
|
new_guild: Guild,
|
||||||
@ -2421,6 +2480,22 @@ class Message(PartialMessage, Hashable):
|
|||||||
if self.type is MessageType.guild_incident_report_false_alarm:
|
if self.type is MessageType.guild_incident_report_false_alarm:
|
||||||
return f'{self.author.name} reported a false alarm in {self.guild}.'
|
return f'{self.author.name} reported a false alarm in {self.guild}.'
|
||||||
|
|
||||||
|
if self.type is MessageType.call:
|
||||||
|
call_ended = self.call.ended_timestamp is not None # type: ignore # call can't be None here
|
||||||
|
missed = self._state.user not in self.call.participants # type: ignore # call can't be None here
|
||||||
|
|
||||||
|
if call_ended:
|
||||||
|
duration = utils._format_call_duration(self.call.duration) # type: ignore # call can't be None here
|
||||||
|
if missed:
|
||||||
|
return 'You missed a call from {0.author.name} that lasted {1}.'.format(self, duration)
|
||||||
|
else:
|
||||||
|
return '{0.author.name} started a call that lasted {1}.'.format(self, duration)
|
||||||
|
else:
|
||||||
|
if missed:
|
||||||
|
return '{0.author.name} started a call. \N{EM DASH} Join the call'.format(self)
|
||||||
|
else:
|
||||||
|
return '{0.author.name} started a call.'.format(self)
|
||||||
|
|
||||||
# Fallback for unknown message types
|
# Fallback for unknown message types
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
|
@ -116,6 +116,11 @@ class RoleSubscriptionData(TypedDict):
|
|||||||
is_renewal: bool
|
is_renewal: bool
|
||||||
|
|
||||||
|
|
||||||
|
class CallMessage(TypedDict):
|
||||||
|
participants: SnowflakeList
|
||||||
|
ended_timestamp: NotRequired[Optional[str]]
|
||||||
|
|
||||||
|
|
||||||
MessageType = Literal[
|
MessageType = Literal[
|
||||||
0,
|
0,
|
||||||
1,
|
1,
|
||||||
@ -187,6 +192,7 @@ class Message(PartialMessage):
|
|||||||
position: NotRequired[int]
|
position: NotRequired[int]
|
||||||
role_subscription_data: NotRequired[RoleSubscriptionData]
|
role_subscription_data: NotRequired[RoleSubscriptionData]
|
||||||
thread: NotRequired[Thread]
|
thread: NotRequired[Thread]
|
||||||
|
call: NotRequired[CallMessage]
|
||||||
|
|
||||||
|
|
||||||
AllowedMentionType = Literal['roles', 'users', 'everyone']
|
AllowedMentionType = Literal['roles', 'users', 'everyone']
|
||||||
|
@ -1468,3 +1468,55 @@ else:
|
|||||||
return msg.decode('utf-8')
|
return msg.decode('utf-8')
|
||||||
|
|
||||||
_ActiveDecompressionContext: Type[_DecompressionContext] = _ZlibDecompressionContext
|
_ActiveDecompressionContext: Type[_DecompressionContext] = _ZlibDecompressionContext
|
||||||
|
|
||||||
|
|
||||||
|
def _format_call_duration(duration: datetime.timedelta) -> str:
|
||||||
|
seconds = duration.total_seconds()
|
||||||
|
|
||||||
|
minutes_s = 60
|
||||||
|
hours_s = minutes_s * 60
|
||||||
|
days_s = hours_s * 24
|
||||||
|
# Discord uses approx. 1/12 of 365.25 days (avg. days per year)
|
||||||
|
months_s = days_s * 30.4375
|
||||||
|
years_s = months_s * 12
|
||||||
|
|
||||||
|
threshold_s = 45
|
||||||
|
threshold_m = 45
|
||||||
|
threshold_h = 21.5
|
||||||
|
threshold_d = 25.5
|
||||||
|
threshold_M = 10.5
|
||||||
|
|
||||||
|
if seconds < threshold_s:
|
||||||
|
formatted = "a few seconds"
|
||||||
|
elif seconds < (threshold_m * minutes_s):
|
||||||
|
minutes = round(seconds / minutes_s)
|
||||||
|
if minutes == 1:
|
||||||
|
formatted = "a minute"
|
||||||
|
else:
|
||||||
|
formatted = f"{minutes} minutes"
|
||||||
|
elif seconds < (threshold_h * hours_s):
|
||||||
|
hours = round(seconds / hours_s)
|
||||||
|
if hours == 1:
|
||||||
|
formatted = "an hour"
|
||||||
|
else:
|
||||||
|
formatted = f"{hours} hours"
|
||||||
|
elif seconds < (threshold_d * days_s):
|
||||||
|
days = round(seconds / days_s)
|
||||||
|
if days == 1:
|
||||||
|
formatted = "a day"
|
||||||
|
else:
|
||||||
|
formatted = f"{days} days"
|
||||||
|
elif seconds < (threshold_M * months_s):
|
||||||
|
months = round(seconds / months_s)
|
||||||
|
if months == 1:
|
||||||
|
formatted = "a month"
|
||||||
|
else:
|
||||||
|
formatted = f"{months} months"
|
||||||
|
else:
|
||||||
|
years = round(seconds / years_s)
|
||||||
|
if years == 1:
|
||||||
|
formatted = "a year"
|
||||||
|
else:
|
||||||
|
formatted = f"{years} years"
|
||||||
|
|
||||||
|
return formatted
|
||||||
|
@ -5626,6 +5626,14 @@ PollMedia
|
|||||||
.. autoclass:: PollMedia
|
.. autoclass:: PollMedia
|
||||||
:members:
|
:members:
|
||||||
|
|
||||||
|
CallMessage
|
||||||
|
~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
.. attributetable:: CallMessage
|
||||||
|
|
||||||
|
.. autoclass:: CallMessage()
|
||||||
|
:members:
|
||||||
|
|
||||||
|
|
||||||
Exceptions
|
Exceptions
|
||||||
------------
|
------------
|
||||||
|
Loading…
x
Reference in New Issue
Block a user