Source code for osmium_chat.reaction
"""Message reaction model.
A :class:`Reaction` groups every user who reacted to a message with the same
emoji into one object. The :attr:`~Reaction.emoji` is either a
:class:`~osmium_chat.content.UnicodeEmoji` (standard Unicode) or a
:class:`~osmium_chat.emoji.CustomEmoji` stub (community emoji).
**Reading reactions**
Reactions arrive in :attr:`~osmium_chat.message.Message.reactions` after a
message is parsed from the gateway::
for reaction in message.reactions:
print(reaction.emoji, reaction.count, reaction.users)
**Adding and removing reactions**
Use :meth:`~osmium_chat.message.Message.add_reaction` and
:meth:`~osmium_chat.message.Message.remove_reaction` to react to a message.
Both accept a plain Unicode string, a :class:`~osmium_chat.content.UnicodeEmoji`,
or a :class:`~osmium_chat.emoji.CustomEmoji`::
await message.add_reaction("👍")
await message.add_reaction(UnicodeEmoji("🎉"))
await message.add_reaction(custom_emoji)
await message.remove_reaction("👍")
.. note::
The :attr:`~Reaction.users` list is a gateway-provided preview and may be
truncated for reactions with many participants. :attr:`~Reaction.count` is
always the authoritative total.
"""
from typing import TYPE_CHECKING
from osmium_protos import PB_MessageReactionField
from osmium_chat.content import UnicodeEmoji
if TYPE_CHECKING:
from osmium_chat.emoji import CustomEmoji
__all__: tuple[str, ...] = (
"Reaction",
)
[docs]
class Reaction:
"""A single reaction type on a message.
Groups all users who reacted with the same emoji under one
:class:`Reaction`. The :attr:`emoji` is either a
:class:`~osmium_chat.content.UnicodeEmoji` (for standard Unicode emoji) or
a :class:`~osmium_chat.emoji.CustomEmoji` stub carrying only the server id
(for community custom emoji received from the gateway). :attr:`users` holds
the preview list of user ids the gateway provided — it may be truncated for
reactions with many participants.
:param emoji: The emoji this reaction represents.
:param count: Total number of users who added this reaction.
:param users: Preview list of user ids who added this reaction.
"""
__slots__ = ("emoji", "count", "users")
def __init__(
self,
emoji: "CustomEmoji | UnicodeEmoji",
count: int,
users: list[int],
) -> None:
self.emoji: "CustomEmoji | UnicodeEmoji" = emoji
self.count: int = count
self.users: list[int] = users
def __repr__(self) -> str:
return f"Reaction(emoji={self.emoji!r}, count={self.count!r})"
def _reaction_from_field(
field: PB_MessageReactionField,
community_id: int = 0,
) -> "Reaction":
"""Build a :class:`Reaction` from a raw protobuf field.
Custom emoji reactions are returned as a minimal
:class:`~osmium_chat.emoji.CustomEmoji` stub (id only, no client, no pack)
since the full metadata is not available in a reaction update.
"""
pb_emoji = field.emoji
if pb_emoji is not None and pb_emoji.custom_emoji is not None:
from osmium_chat.emoji import CustomEmoji
emoji: "CustomEmoji | UnicodeEmoji" = CustomEmoji(
emoji_id=pb_emoji.custom_emoji,
name=str(pb_emoji.custom_emoji),
community_id=community_id,
pack_id=0,
client=None, # type: ignore[arg-type]
)
else:
raw = (pb_emoji.unicode_emoji or "") if pb_emoji is not None else ""
emoji = UnicodeEmoji(raw)
return Reaction(
emoji=emoji,
count=field.count,
users=list(field.preview_user_ids),
)