Add raw typing event and fix typing event not working for DMs

This commit is contained in:
Lilly Rose Berner 2022-04-24 04:25:07 +02:00 committed by GitHub
parent e5f3706c02
commit 277d35c9b2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 68 additions and 14 deletions

View File

@ -24,9 +24,11 @@ DEALINGS IN THE SOFTWARE.
from __future__ import annotations from __future__ import annotations
import datetime
from typing import TYPE_CHECKING, Optional, Set, List, Tuple, Union from typing import TYPE_CHECKING, Optional, Set, List, Tuple, Union
from .enums import ChannelType, try_enum from .enums import ChannelType, try_enum
from .utils import _get_as_snowflake
if TYPE_CHECKING: if TYPE_CHECKING:
from .types.gateway import ( from .types.gateway import (
@ -39,11 +41,13 @@ if TYPE_CHECKING:
MessageUpdateEvent, MessageUpdateEvent,
IntegrationDeleteEvent, IntegrationDeleteEvent,
ThreadDeleteEvent, ThreadDeleteEvent,
TypingStartEvent,
) )
from .message import Message from .message import Message
from .partial_emoji import PartialEmoji from .partial_emoji import PartialEmoji
from .member import Member from .member import Member
from .threads import Thread from .threads import Thread
from .user import User
ReactionActionEvent = Union[MessageReactionAddEvent, MessageReactionRemoveEvent] ReactionActionEvent = Union[MessageReactionAddEvent, MessageReactionRemoveEvent]
@ -57,6 +61,7 @@ __all__ = (
'RawReactionClearEmojiEvent', 'RawReactionClearEmojiEvent',
'RawIntegrationDeleteEvent', 'RawIntegrationDeleteEvent',
'RawThreadDeleteEvent', 'RawThreadDeleteEvent',
'RawTypingEvent',
) )
@ -314,3 +319,32 @@ class RawThreadDeleteEvent(_RawReprMixin):
self.guild_id: int = int(data['guild_id']) self.guild_id: int = int(data['guild_id'])
self.parent_id: int = int(data['parent_id']) self.parent_id: int = int(data['parent_id'])
self.thread: Optional[Thread] = None self.thread: Optional[Thread] = None
class RawTypingEvent(_RawReprMixin):
"""Represents the payload for a :func:`on_raw_typing` event.
.. versionadded:: 2.0
Attributes
----------
channel_id: :class:`int`
The ID of the channel the user started typing in.
user_id: :class:`int`
The ID of the user that started typing.
user: Optional[Union[:class:`discord.User`, :class:`discord.Member`]]
The user that started typing, if they could be found in the internal cache.
timestamp: :class:`datetime.datetime`
When the typing started as an aware datetime in UTC.
guild_id: Optional[:class:`int`]
The ID of the guild the user started typing in, if applicable.
"""
__slots__ = ('channel_id', 'user_id', 'user', 'timestamp', 'guild_id')
def __init__(self, data: TypingStartEvent, /) -> None:
self.channel_id: int = int(data['channel_id'])
self.user_id: int = int(data['user_id'])
self.user: Optional[Union[User, Member]] = None
self.timestamp: datetime.datetime = datetime.datetime.fromtimestamp(data['timestamp'], tz=datetime.timezone.utc)
self.guild_id: Optional[int] = _get_as_snowflake(data, 'guild_id')

View File

@ -27,7 +27,6 @@ from __future__ import annotations
import asyncio import asyncio
from collections import deque, OrderedDict from collections import deque, OrderedDict
import copy import copy
import datetime
import itertools import itertools
import logging import logging
from typing import ( from typing import (
@ -1443,27 +1442,25 @@ class ConnectionState:
asyncio.create_task(logging_coroutine(coro, info='Voice Protocol voice server update handler')) asyncio.create_task(logging_coroutine(coro, info='Voice Protocol voice server update handler'))
def parse_typing_start(self, data: gw.TypingStartEvent) -> None: def parse_typing_start(self, data: gw.TypingStartEvent) -> None:
raw = RawTypingEvent(data)
raw.user = self.get_user(raw.user_id)
channel, guild = self._get_guild_channel(data) channel, guild = self._get_guild_channel(data)
if channel is not None: if channel is not None:
member = None
user_id = int(data['user_id'])
if isinstance(channel, DMChannel): if isinstance(channel, DMChannel):
member = channel.recipient channel.recipient = raw.user
elif guild is not None:
raw.user = guild.get_member(raw.user_id)
elif isinstance(channel, (Thread, TextChannel)) and guild is not None: if raw.user is None:
member = guild.get_member(user_id)
if member is None:
member_data = data.get('member') member_data = data.get('member')
if member_data: if member_data:
member = Member(data=member_data, state=self, guild=guild) raw.user = Member(data=member_data, state=self, guild=guild)
elif isinstance(channel, GroupChannel): if raw.user is not None:
member = utils.find(lambda x: x.id == user_id, channel.recipients) self.dispatch('typing', channel, raw.user, raw.timestamp)
if member is not None: self.dispatch('raw_typing', raw)
timestamp = datetime.datetime.fromtimestamp(data['timestamp'], tz=datetime.timezone.utc)
self.dispatch('typing', channel, member, timestamp)
def _get_reaction_user(self, channel: MessageableChannel, user_id: int) -> Optional[Union[User, Member]]: def _get_reaction_user(self, channel: MessageableChannel, user_id: int) -> Optional[Union[User, Member]]:
if isinstance(channel, TextChannel): if isinstance(channel, TextChannel):

View File

@ -273,6 +273,9 @@ Channels
If the ``channel`` is a :class:`TextChannel` then the ``user`` parameter If the ``channel`` is a :class:`TextChannel` then the ``user`` parameter
is a :class:`Member`, otherwise it is a :class:`User`. is a :class:`Member`, otherwise it is a :class:`User`.
If the channel or user could not be found in the internal cache this event
will not be called, you may use :func:`on_raw_typing` instead.
This requires :attr:`Intents.typing` to be enabled. This requires :attr:`Intents.typing` to be enabled.
:param channel: The location where the typing originated from. :param channel: The location where the typing originated from.
@ -282,6 +285,18 @@ Channels
:param when: When the typing started as an aware datetime in UTC. :param when: When the typing started as an aware datetime in UTC.
:type when: :class:`datetime.datetime` :type when: :class:`datetime.datetime`
.. function:: on_raw_typing(payload)
Called when someone begins typing a message. Unlike :func:`on_typing` this
is called regardless of the channel and user being in the internal cache.
This requires :attr:`Intents.typing` to be enabled.
.. versionadded:: 2.0
:param payload: The raw event payload data.
:type payload: :class:`RawTypingEvent`
Connection Connection
~~~~~~~~~~~ ~~~~~~~~~~~
@ -4015,6 +4030,14 @@ RawThreadDeleteEvent
.. autoclass:: RawThreadDeleteEvent() .. autoclass:: RawThreadDeleteEvent()
:members: :members:
RawTypingEvent
~~~~~~~~~~~~~~~~
.. attributetable:: RawTypingEvent
.. autoclass:: RawTypingEvent()
:members:
PartialWebhookGuild PartialWebhookGuild
~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~