Browse Source

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

pull/7927/head
Lilly Rose Berner 3 years ago
committed by GitHub
parent
commit
277d35c9b2
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 34
      discord/raw_models.py
  2. 25
      discord/state.py
  3. 23
      docs/api.rst

34
discord/raw_models.py

@ -24,9 +24,11 @@ DEALINGS IN THE SOFTWARE.
from __future__ import annotations
import datetime
from typing import TYPE_CHECKING, Optional, Set, List, Tuple, Union
from .enums import ChannelType, try_enum
from .utils import _get_as_snowflake
if TYPE_CHECKING:
from .types.gateway import (
@ -39,11 +41,13 @@ if TYPE_CHECKING:
MessageUpdateEvent,
IntegrationDeleteEvent,
ThreadDeleteEvent,
TypingStartEvent,
)
from .message import Message
from .partial_emoji import PartialEmoji
from .member import Member
from .threads import Thread
from .user import User
ReactionActionEvent = Union[MessageReactionAddEvent, MessageReactionRemoveEvent]
@ -57,6 +61,7 @@ __all__ = (
'RawReactionClearEmojiEvent',
'RawIntegrationDeleteEvent',
'RawThreadDeleteEvent',
'RawTypingEvent',
)
@ -314,3 +319,32 @@ class RawThreadDeleteEvent(_RawReprMixin):
self.guild_id: int = int(data['guild_id'])
self.parent_id: int = int(data['parent_id'])
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')

25
discord/state.py

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

23
docs/api.rst

@ -273,6 +273,9 @@ Channels
If the ``channel`` is a :class:`TextChannel` then the ``user`` parameter
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.
: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.
: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
~~~~~~~~~~~
@ -4015,6 +4030,14 @@ RawThreadDeleteEvent
.. autoclass:: RawThreadDeleteEvent()
:members:
RawTypingEvent
~~~~~~~~~~~~~~~~
.. attributetable:: RawTypingEvent
.. autoclass:: RawTypingEvent()
:members:
PartialWebhookGuild
~~~~~~~~~~~~~~~~~~~~

Loading…
Cancel
Save