Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add more raw events #1880

Merged
merged 21 commits into from
Feb 10, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ These changes are available on the `master` branch, but have not yet been releas
([#1912](https://github.com/Pycord-Development/pycord/pull/1912))
- Added GIF sticker format type to the `StickerFormatType` enum.
([#1915](https://github.com/Pycord-Development/pycord/pull/1915))
- Added new raw events: `raw_member_remove`, `raw_thread_update`, and
`raw_thread_member_remove`.
([#1880](https://github.com/Pycord-Development/pycord/pull/1880))

### Changed

Expand Down
1 change: 1 addition & 0 deletions discord/flags.py
Original file line number Diff line number Diff line change
Expand Up @@ -689,6 +689,7 @@ def members(self):

- :func:`on_member_join`
- :func:`on_member_remove`
- :func:`on_raw_member_remove`
- :func:`on_member_update`
- :func:`on_user_update`

Expand Down
85 changes: 85 additions & 0 deletions discord/raw_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@

from .automod import AutoModAction, AutoModTriggerType
from .enums import ChannelType, try_enum
from .types.user import User

if TYPE_CHECKING:
from .abc import MessageableChannel
Expand All @@ -43,13 +44,16 @@
from .types.raw_models import (
BulkMessageDeleteEvent,
IntegrationDeleteEvent,
MemberRemoveEvent,
MessageDeleteEvent,
MessageUpdateEvent,
ReactionActionEvent,
ReactionClearEmojiEvent,
ReactionClearEvent,
ScheduledEventSubscription,
ThreadDeleteEvent,
ThreadMembersUpdateEvent,
ThreadUpdateEvent,
TypingEvent,
)

Expand All @@ -62,10 +66,13 @@
"RawReactionClearEvent",
"RawReactionClearEmojiEvent",
"RawIntegrationDeleteEvent",
"RawThreadUpdateEvent",
"RawThreadDeleteEvent",
"RawTypingEvent",
"RawMemberRemoveEvent",
"RawScheduledEventSubscription",
"AutoModActionExecutionEvent",
"RawThreadMembersUpdateEvent",
)


Expand Down Expand Up @@ -305,6 +312,38 @@ def __init__(self, data: IntegrationDeleteEvent) -> None:
self.application_id: int | None = None


class RawThreadUpdateEvent(_RawReprMixin):
"""Represents the payload for an :func:`on_raw_thread_update` event.

.. versionadded:: 2.4

Attributes
----------
thread_id: :class:`int`
The ID of the updated thread.
thread_type: :class:`discord.ChannelType`
The channel type of the updated thread.
guild_id: :class:`int`
The ID of the guild the thread belongs to.
parent_id: :class:`int`
The ID of the channel the thread belongs to.
data: :class:`dict`
The raw data given by the `gateway <https://discord.com/developers/docs/topics/gateway-events#thread-update>`_.
thread: :class:`discord.Thread` | None
The thread, if it could be found in the internal cache.
"""

__slots__ = ("thread_id", "thread_type", "parent_id", "guild_id", "data", "thread")

def __init__(self, data: ThreadUpdateEvent) -> None:
self.thread_id: int = int(data["id"])
self.thread_type: ChannelType = try_enum(ChannelType, data["type"])
self.guild_id: int = int(data["guild_id"])
self.parent_id: int = int(data["parent_id"])
self.data: ThreadUpdateEvent = data
self.thread: Thread | None = None


class RawThreadDeleteEvent(_RawReprMixin):
"""Represents the payload for :func:`on_raw_thread_delete` event.

Expand Down Expand Up @@ -370,6 +409,26 @@ def __init__(self, data: TypingEvent) -> None:
self.guild_id: int | None = None


class RawMemberRemoveEvent(_RawReprMixin):
"""Represents the payload for an :func:`on_raw_member_remove` event.

.. versionadded:: 2.4

Attributes
----------
user: :class:`discord.User`
The user that left the guild.
guild_id: :class:`int`
The ID of the guild the user left.
"""

__slots__ = ("user", "guild_id")

def __init__(self, data: MemberRemoveEvent, user: User):
self.user: User = user
self.guild_id: int = int(data["guild_id"])


class RawScheduledEventSubscription(_RawReprMixin):
"""Represents the payload for a :func:`raw_scheduled_event_user_add` or
:func:`raw_scheduled_event_user_remove` event.
Expand Down Expand Up @@ -516,3 +575,29 @@ def __repr__(self) -> str:
f"rule_id={self.rule_id!r} guild_id={self.guild_id!r} "
f"user_id={self.user_id!r}>"
)


class RawThreadMembersUpdateEvent(_RawReprMixin):
"""Represents the payload for an :func:`on_raw_thread_member_remove` event.

.. versionadded:: 2.4

Attributes
----------
thread_id: :class:`int`
The ID of the thread that was updated.
guild_id: :class:`int`
The ID of the guild the thread is in.
member_count: :class:`int`
The approximate number of members in the thread. Maximum of 50.
data: :class:`dict`
The raw data given by the `gateway <https://discord.com/developers/docs/topics/gateway-events#thread-members-update>`_.
"""

__slots__ = ("thread_id", "guild_id", "member_count", "data")

def __init__(self, data: ThreadMembersUpdateEvent) -> None:
self.thread_id = int(data["id"])
self.guild_id = int(data["guild_id"])
self.member_count = int(data["member_count"])
self.data = data
35 changes: 23 additions & 12 deletions discord/state.py
Original file line number Diff line number Diff line change
Expand Up @@ -969,23 +969,28 @@ def parse_thread_create(self, data) -> None:
def parse_thread_update(self, data) -> None:
guild_id = int(data["guild_id"])
guild = self._get_guild(guild_id)
raw = RawThreadUpdateEvent(data)
if guild is None:
_log.debug(
"THREAD_UPDATE referencing an unknown guild ID: %s. Discarding",
guild_id,
)
return

thread_id = int(data["id"])
thread = guild.get_thread(thread_id)
if thread is not None:
old = copy.copy(thread)
thread._update(data)
self.dispatch("thread_update", old, thread)
else:
thread = Thread(guild=guild, state=guild._state, data=data)
guild._add_thread(thread)
self.dispatch("thread_join", thread)
thread = guild.get_thread(raw.thread_id)
if thread is not None:
old = copy.copy(thread)
thread._update(data)
if thread.archived:
guild._remove_thread(thread)
self.dispatch("thread_update", old, thread)
else:
thread = Thread(guild=guild, state=guild._state, data=data)
if not thread.archived:
guild._add_thread(thread)
self.dispatch("thread_join", thread)
raw.thread = thread
self.dispatch("raw_thread_update", raw)

def parse_thread_delete(self, data) -> None:
guild_id = int(data["guild_id"])
Expand Down Expand Up @@ -1084,6 +1089,7 @@ def parse_thread_members_update(self, data) -> None:

thread_id = int(data["id"])
thread: Thread | None = guild.get_thread(thread_id)
raw = RawThreadMembersUpdateEvent(data)
if thread is None:
_log.debug(
(
Expand All @@ -1108,6 +1114,7 @@ def parse_thread_members_update(self, data) -> None:
for member_id in removed_member_ids:
if member_id != self_id:
member = thread._pop_member(member_id)
self.dispatch("raw_thread_member_remove", raw)
if member is not None:
self.dispatch("thread_member_remove", member)
else:
Expand All @@ -1134,23 +1141,27 @@ def parse_guild_member_add(self, data) -> None:
self.dispatch("member_join", member)

def parse_guild_member_remove(self, data) -> None:
user = self.store_user(data["user"])
raw = RawMemberRemoveEvent(data, user)

guild = self._get_guild(int(data["guild_id"]))
if guild is not None:
try:
guild._member_count -= 1
except AttributeError:
pass

user_id = int(data["user"]["id"])
member = guild.get_member(user_id)
member = guild.get_member(user.id)
if member is not None:
raw.user = member
guild._remove_member(member) # type: ignore
self.dispatch("member_remove", member)
else:
_log.debug(
"GUILD_MEMBER_REMOVE referencing an unknown guild ID: %s. Discarding.",
data["guild_id"],
)
self.dispatch("raw_member_remove", raw)

def parse_guild_member_update(self, data) -> None:
guild = self._get_guild(int(data["guild_id"]))
Expand Down
18 changes: 18 additions & 0 deletions discord/types/raw_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
from .emoji import PartialEmoji
from .member import Member
from .snowflake import Snowflake
from .threads import Thread, ThreadMember
from .user import User


class _MessageEventOptional(TypedDict, total=False):
Expand Down Expand Up @@ -79,6 +81,9 @@ class IntegrationDeleteEvent(TypedDict):
guild_id: Snowflake


ThreadUpdateEvent = Thread


class ThreadDeleteEvent(TypedDict, total=False):
thread_id: Snowflake
thread_type: int
Expand Down Expand Up @@ -112,3 +117,16 @@ class AutoModActionExecutionEvent(TypedDict):
rule_trigger_type: AutoModTriggerType
user_id: Snowflake
content: str


class MemberRemoveEvent(TypedDict):
guild_id: Snowflake
user: User


class ThreadMembersUpdateEvent(TypedDict):
id: Snowflake
guild_id: Snowflake
member_count: int
added_members: NotRequired[list[ThreadMember]]
removed_member_ids: NotRequired[list[Snowflake]]
65 changes: 62 additions & 3 deletions docs/api/events.rst
Original file line number Diff line number Diff line change
Expand Up @@ -581,15 +581,40 @@ Invites
Members/Users
-------------
.. function:: on_member_join(member)
on_member_remove(member)

Called when a :class:`Member` leaves or joins a :class:`Guild`.
Called when a :class:`Member` joins a :class:`Guild`.

This requires :attr:`Intents.members` to be enabled.

:param member: The member who joined or left.
:param member: The member who joined.
:type member: :class:`Member`

.. function:: on_member_remove(member)

Called when a :class:`Member` leaves a :class:`Guild`.

If the guild or member could not be found in the internal cache, this event will not
be called. Alternatively, :func:`on_raw_member_remove` is called regardless of the
internal cache.

This requires :attr:`Intents.members` to be enabled.

:param member: The member who left.
:type member: :class:`Member`

.. function:: on_raw_member_remove(payload)

Called when a :class:`Member` leaves a :class:`Guild`. Unlike
:func:`on_member_remove`, this is called regardless of the state of the internal
member cache.

This requires :attr:`Intents.members` to be enabled.

.. versionadded:: 2.4

:param payload: The raw event payload data.
:type payload: :class:`RawMemberRemoveEvent`

.. function:: on_member_update(before, after)

Called when a :class:`Member` updates their profile.
Expand Down Expand Up @@ -1102,19 +1127,53 @@ Threads
:param member: The member who joined or left.
:type member: :class:`ThreadMember`


.. function:: on_raw_thread_member_remove(payload)

Called when a :class:`ThreadMember` leaves a :class:`Thread`. Unlike :func:`on_thread_member_remove` this
is called regardless of the member being in the thread's internal cache of members or not.

This requires :attr:`Intents.members` to be enabled.

.. versionadded:: 2.4

:param payload: The raw event payload data.
:type member: :class:`RawThreadMembersUpdateEvent`



.. function:: on_thread_update(before, after)

Called whenever a thread is updated.

This requires :attr:`Intents.guilds` to be enabled.

If the thread could not be found in the internal cache, this event will not be called.
Threads will not be in the cache if they are archived. Alternatively,
:func:`on_raw_thread_update` is called regardless of the internal cache.

.. versionadded:: 2.0

:param before: The updated thread's old info.
:type before: :class:`Thread`
:param after: The updated thread's new info.
:type after: :class:`Thread`


.. function:: on_raw_thread_update(payload)

Called whenever a thread is updated.

Unlike :func:`on_thread_update` this is called regardless of if the thread is in the
internal thread cache or not.

This requires :attr:`Intents.guilds` to be enabled.

.. versionadded:: 2.4

:param payload: The raw event payload data.
:type payload: :class:`RawThreadUpdateEvent`

Typing
------
.. function:: on_typing(channel, user, when)
Expand Down
17 changes: 17 additions & 0 deletions docs/api/models.rst
Original file line number Diff line number Diff line change
Expand Up @@ -502,6 +502,23 @@ Events
.. autoclass:: RawScheduledEventSubscription()
:members:

.. attributetable:: RawMemberRemoveEvent

.. autoclass:: RawMemberRemoveEvent()
:members:

.. attributetable:: RawThreadUpdateEvent

.. autoclass:: RawThreadUpdateEvent()
:members:

.. attributetable:: RawThreadMembersUpdateEvent

.. autoclass:: RawThreadMembersUpdateEvent()
:members:



Webhooks
--------

Expand Down