-
Notifications
You must be signed in to change notification settings - Fork 0
Refactor Message Handling and Reaction API #9
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
base: main
Are you sure you want to change the base?
Changes from 37 commits
66f8722
28d5ce7
c40bca9
ca82eb5
7cd47d2
e1f328b
3120737
7cdd0bd
02ec9d3
b57b463
e2b8f09
384ea9f
cb1fe10
7575446
e8c5449
1455278
a00ad7f
febbc44
c610201
9e164a2
73ba151
e520f40
3d4e6b8
dbc46f9
1e650c5
5b7df41
3b0c266
36929c3
5d3bbe1
3573f8b
53e4923
51f69b1
b849b0b
909cbd2
ab2498a
d069c99
9b3ea48
e5b0102
dafcbd6
07b4598
68ae7f9
26c95c3
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -4,7 +4,7 @@ | |
| from nio import Event | ||
|
|
||
| if TYPE_CHECKING: | ||
| from .bot import Bot # pragma: no cover | ||
| from matrix.bot import Bot # pragma: no cover | ||
|
|
||
|
|
||
| class Message: | ||
|
|
@@ -15,15 +15,27 @@ class Message: | |
| formatting the message content as either plain text or HTML. | ||
|
|
||
| :param bot: The bot instance to use for messages. | ||
| :type bot: Bot | ||
| :param id: The unique identifier of the message event. | ||
| :param content: The content of the message. | ||
| :param sender: The sender of the message. | ||
| """ | ||
|
|
||
| MESSAGE_TYPE = "m.room.message" | ||
| MATRIX_CUSTOM_HTML = "org.matrix.custom.html" | ||
| TEXT_MESSAGE_TYPE = "m.text" | ||
|
|
||
| def __init__(self, bot: "Bot") -> None: | ||
| def __init__( | ||
| self, | ||
| bot: "Bot", | ||
| *, | ||
| id: Optional[str] = None, | ||
| content: Optional[str] = None, | ||
| sender: Optional[str] = None, | ||
| ) -> None: | ||
| self.bot = bot | ||
| self.id = id | ||
| self.content = content | ||
| self.sender = sender | ||
|
|
||
| async def _send_to_room( | ||
| self, room_id: str, content: Dict, message_type: str = MESSAGE_TYPE | ||
|
|
@@ -32,11 +44,8 @@ async def _send_to_room( | |
| Send a message to the Matrix room. | ||
|
|
||
| :param room_id: The ID of the room to send the message to. | ||
| :type room_id: str | ||
| :param content: The matrix JSON payload. | ||
| :type content: Dict | ||
| :param message_type: The type of the message. | ||
| :type message_type: str | ||
|
|
||
| :raise MatrixError: If sending the message fails. | ||
| """ | ||
|
|
@@ -54,22 +63,15 @@ def _make_content( | |
| body: str = "", | ||
| html: Optional[bool] = None, | ||
| reaction: Optional[bool] = None, | ||
| event_id: Optional[str] = None, | ||
| key: Optional[str] = None, | ||
| ) -> Dict: | ||
| """ | ||
| Create the content dictionary for a message. | ||
|
|
||
| :param body: The body of the message. | ||
| :type body: str | ||
| :param html: Wheter to format the message as HTML. | ||
| :type html: Optional[bool] | ||
| :param reaction: Wheter to format the context with a reaction event. | ||
| :type reaction: Optional[bool] | ||
| :param event_id: The ID of the event to react to. | ||
| :type event_id: Optional[str] | ||
| :param key: The reaction to the message. | ||
| :type key: Optional[str] | ||
|
|
||
| :return: The content of the dictionary. | ||
| """ | ||
|
|
@@ -85,50 +87,66 @@ def _make_content( | |
|
|
||
| if reaction: | ||
| base["m.relates_to"] = { | ||
| "event_id": event_id, | ||
| "event_id": self.id, | ||
chrisdedman marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| "key": key, | ||
| "rel_type": "m.annotation", | ||
| } | ||
|
|
||
| return base | ||
|
|
||
| async def send( | ||
| async def send_message( | ||
| self, room_id: str, message: str, format_markdown: Optional[bool] = True | ||
| ) -> None: | ||
| """ | ||
| Send a message to a Matrix room. | ||
|
|
||
| :param room_id: The ID of the room to send the message to. | ||
| :type room_id: str | ||
| :param message: The message to send. | ||
| :type message: str | ||
| :param format_markdown: Whether to format the message as Markdown | ||
| (default to True). | ||
| :type format_markdown: Optional[bool] | ||
| """ | ||
| await self._send_to_room( | ||
| room_id=room_id, | ||
| content=self._make_content(body=str(message), html=format_markdown), | ||
| ) | ||
|
|
||
| async def send_reaction(self, room_id: str, event: Event, key: str) -> None: | ||
| async def send_reaction(self, room_id: str, key: str) -> None: | ||
| """ | ||
| Send a reaction to a message from a user in a Matrix room. | ||
|
|
||
| :param room_id: The ID of the room to send the message to. | ||
| :type room_id: str | ||
| :param event: The event object to react to. | ||
| :type event: Event | ||
| :param key: The reaction to the message. | ||
| :type key: str | ||
| """ | ||
| if isinstance(event, Event): | ||
| event_id = event.event_id | ||
| else: | ||
| event_id = event | ||
|
|
||
| await self._send_to_room( | ||
| room_id=room_id, | ||
| content=self._make_content(event_id=event_id, key=key, reaction=True), | ||
| content=self._make_content(key=key, reaction=True), | ||
| message_type="m.reaction", | ||
| ) | ||
|
|
||
| @staticmethod | ||
| def from_event(bot: "Bot", event: Optional[Event] = None) -> "Message": | ||
chrisdedman marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| """ | ||
| Method to construct a Message instance from event. | ||
| Support regular message events and reaction events. | ||
|
|
||
| :param bot: The bot instance to use for messages. | ||
| :param event: The event object to construct the message from. | ||
|
|
||
| :return: The constructed Message instance. | ||
| """ | ||
| if event is None: | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is not necessary since we pass an event. |
||
| return Message(bot=bot) | ||
|
|
||
| if isinstance(event, Event) and event.source["type"] == "m.reaction": | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This doesn't make sense either. It should always be an instance of event.cif they goal is to check the type just check the types you don't have to check the instance |
||
| event_id = event.source["content"]["m.relates_to"]["event_id"] | ||
| body = event.source["content"] | ||
| else: | ||
| event_id = event.event_id | ||
| body = event.body | ||
|
|
||
| return Message( | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I feel like we should pass the the event now |
||
| bot=bot, | ||
| id=event_id, | ||
| content=body, | ||
| sender=event.sender, | ||
| ) | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -12,9 +12,7 @@ class Room: | |
| Represents a Matrix room and provides methods to interact with it. | ||
|
|
||
| :param room_id: The unique identifier of the room. | ||
| :type room_id: str | ||
| :param bot: The bot instance used to send messages. | ||
| :type bot: Bot | ||
| """ | ||
|
|
||
| def __init__(self, room_id: str, bot: "Bot") -> None: | ||
|
|
@@ -32,22 +30,44 @@ async def send( | |
| Send a message to the room. | ||
|
|
||
| :param message: The message to send. | ||
| :type message: str | ||
| :param markdown: Whether to format the message as Markdown. | ||
| :type markdown: Optional[bool] | ||
| :param event: An event object to react to. | ||
| :type event: Optional[Event] | ||
| :param key: The reaction to the message. | ||
| :type key: Optional[str] | ||
|
|
||
| :raises MatrixError: If sending the message fails. | ||
| """ | ||
| try: | ||
| msg = Message(self.bot) | ||
| msg = self.get_message(self.bot, event) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We can probably get ride of get_message for now and use from_event directly |
||
| if key: | ||
| await msg.send_reaction(self.room_id, event, key) | ||
| await msg.send_reaction(self.room_id, key) | ||
| else: | ||
| await msg.send(self.room_id, message, markdown) | ||
| await msg.send_message(self.room_id, message, markdown) | ||
| except Exception as e: | ||
| raise MatrixError(f"Failed to send message: {e}") | ||
|
|
||
| @staticmethod | ||
| def get_message(bot: "Bot", event: Event) -> Message: | ||
| """ | ||
| Get a Message instance from an event. | ||
| :param bot: The bot instance to use for messages. | ||
| :param event: The event object to construct the message from. | ||
|
|
||
| :return: The constructed Message instance. | ||
| """ | ||
| if not event and not bot: | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This shouldn't happen since we have bot and event as parameter |
||
| raise MatrixError("Failed to get message.") | ||
|
|
||
| return Message.from_event(bot, event) | ||
|
|
||
| async def react(self, event: Event, key: str) -> None: | ||
| """ | ||
| Send a reaction to a message in the room. | ||
|
|
||
| :param event: The event to react to. | ||
| :param key: The reaction to the message. | ||
| """ | ||
| try: | ||
| await self.send(event=event, key=key) | ||
| except Exception as e: | ||
| raise MatrixError(f"Failed to send message: {e}") | ||
|
|
||
|
|
@@ -70,9 +90,7 @@ async def ban_user(self, user_id: str, reason: Optional[str] = None) -> None: | |
| Ban a user from a room. | ||
|
|
||
| :param user_id: The ID of the user to ban of the room. | ||
| :type user_id: str | ||
| :param reason: The reason to ban the user. | ||
| :type reason: Optional[str] | ||
|
|
||
| :raises MatrixError: If banning the user fails. | ||
| """ | ||
|
|
@@ -89,7 +107,6 @@ async def unban_user(self, user_id: str) -> None: | |
| Unban a user from a room. | ||
|
|
||
| :param user_id: The ID of the user to unban of the room. | ||
| :type user_id: str | ||
|
|
||
| :raises MatrixError: If unbanning the user fails. | ||
| """ | ||
|
|
@@ -104,9 +121,7 @@ async def kick_user(self, user_id: str, reason: Optional[str] = None) -> None: | |
| Kick a user from a room. | ||
|
|
||
| :param user_id: The ID of the user to kick of the room. | ||
| :type user_id: str | ||
| :param reason: The reason to kick the user. | ||
| :type reason: Optional[str] | ||
|
|
||
| :raises MatrixError: If kicking the user fails. | ||
| """ | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.