From b896c215ec50220ddbf457ebde9a88bd7f8bc86c Mon Sep 17 00:00:00 2001 From: mid <> Date: Sun, 22 Feb 2026 23:41:59 +0200 Subject: [PATCH] Matrix updates --- gateway_matrix/__init__.py | 74 +++++++++++++++++++++++--------------- 1 file changed, 46 insertions(+), 28 deletions(-) diff --git a/gateway_matrix/__init__.py b/gateway_matrix/__init__.py index c6dcc57..bfc8716 100644 --- a/gateway_matrix/__init__.py +++ b/gateway_matrix/__init__.py @@ -8,6 +8,8 @@ import os import asyncache, cachetools import aiohttp import re +import urllib.parse +import markdownify # For Matrix, dynamic thumbnails and unauthorized media should be both enabled. @@ -66,7 +68,7 @@ class GatewayMatrix: if was_edit: async def q_msg(): - await puppet["intent"].send_message_event(room_id = self.room_name_to_room_id[room_name], event_type = mautrix.types.event.type.EventType.ROOM_MESSAGE, content = mautrix.types.event.message.TextMessageEventContent(msgtype = mautrix.types.event.message.MessageType.TEXT, format = mautrix.types.event.message.Format.HTML, formatted_body = body, relates_to = mautrix.types.event.message.RelatesTo(rel_type = mautrix.types.event.message.RelationType.REPLACE, event_id = self.msg_unique_id_to_event_id[msg_unique_id]))) + await puppet["intent"].send_message_event(room_id = self.room_name_to_room_id[room_name], event_type = mautrix.types.event.type.EventType.ROOM_MESSAGE, content = mautrix.types.event.message.TextMessageEventContent(msgtype = mautrix.types.event.message.MessageType.TEXT, format = None, formatted_body = None, body = body, relates_to = mautrix.types.event.message.RelatesTo(rel_type = mautrix.types.event.message.RelationType.REPLACE, event_id = self.msg_unique_id_to_event_id[msg_unique_id]))) return True puppet["queue"].append(q_msg) @@ -79,7 +81,7 @@ class GatewayMatrix: puppet["last_avatar_hash"] = avatar_hash await puppet["intent"].set_avatar_url(await puppet["intent"].upload_media(data = avatar)) - event_id = await puppet["intent"].send_message_event(room_id = self.room_name_to_room_id[room_name], event_type = mautrix.types.event.type.EventType.ROOM_MESSAGE, content = mautrix.types.event.message.TextMessageEventContent(msgtype = mautrix.types.event.message.MessageType.TEXT, format = mautrix.types.event.message.Format.HTML, formatted_body = body)) + event_id = await puppet["intent"].send_message_event(room_id = self.room_name_to_room_id[room_name], event_type = mautrix.types.event.type.EventType.ROOM_MESSAGE, content = mautrix.types.event.message.TextMessageEventContent(msgtype = mautrix.types.event.message.MessageType.TEXT, format = None, formatted_body = None, body = body)) self.msg_unique_id_to_event_id[msg_unique_id] = event_id self.event_id_to_msg_unique_id[event_id] = msg_unique_id @@ -128,34 +130,48 @@ class GatewayMatrix: return if re.match(re.compile(f"@{re.escape(self.bot_localpart)}[^:]*\\:{re.escape(self.domain)}"), event.sender): + # Ignore ours return if str(event.type) == "m.room.message": - if str(event.content.msgtype) != "m.text": - return - - was_edit = event.content._relates_to and str(event.content._relates_to.rel_type) == "m.replace" - - if was_edit: - msg_unique_id = self.event_id_to_msg_unique_id[event.content._relates_to.event_id] - else: - msg_unique_id = os.urandom(16) - self.msg_unique_id_to_event_id[msg_unique_id] = event.event_id - self.event_id_to_msg_unique_id[event.event_id] = msg_unique_id - self.msg_original_sender[msg_unique_id] = ("matrix", self.gateway_name, event.sender) - - room_name = self.room_id_to_room_name[event.room_id] - nick_name = (await self.appserv.intent.get_displayname(event.sender)) or event.sender - avatar = await self.get_native_user_avatar(event.sender) - - body = event.content.formatted_body if event.content.format else event.content.body - attachments = [] - - if ("matrix", self.gateway_name, event.sender) not in self.active_users: - self.active_users[("matrix", self.gateway_name, event.sender)] = None - PLEXUS.pub("new_user", ("matrix", self.gateway_name, event.sender), nick_name) - - PLEXUS.pub("message", msg_unique_id, room_name, nick_name, avatar, "matrix", self.gateway_name, event.sender, body, attachments, was_edit) + if isinstance(event.content, mautrix.types.event.message.TextMessageEventContent): + was_edit = event.content._relates_to and str(event.content._relates_to.rel_type) == "m.replace" + + if was_edit: + msg_unique_id = self.event_id_to_msg_unique_id[event.content._relates_to.event_id] + else: + msg_unique_id = os.urandom(16) + self.msg_unique_id_to_event_id[msg_unique_id] = event.event_id + self.event_id_to_msg_unique_id[event.event_id] = msg_unique_id + self.msg_original_sender[msg_unique_id] = ("matrix", self.gateway_name, event.sender) + + room_name = self.room_id_to_room_name[event.room_id] + nick_name = (await self.appserv.intent.get_displayname(event.sender)) or event.sender + avatar = await self.get_native_user_avatar(event.sender) + + if isinstance(event.content, mautrix.types.event.message.MediaMessageEventContent): + content_url = str(self.appserv.intent.api.get_download_url(event.content.url)) + content_url = urllib.parse.urlparse(content_url)._replace(netloc = "matrix." + self.domain).geturl() + + body = "" + attachments = [content_url] + else: + body = event.content.formatted_body if event.content.format else event.content.body + attachments = [] + + def code_language_callback(el): + c = el.find("code") + if c is not None and c["class"]: + c = c["class"][0] + return c[9:] if "language-" in c else c + return None + body = markdownify.markdownify(body, newline_style = 'backslash', code_language_callback = code_language_callback) + + if ("matrix", self.gateway_name, event.sender) not in self.active_users: + self.active_users[("matrix", self.gateway_name, event.sender)] = None + PLEXUS.pub("new_user", ("matrix", self.gateway_name, event.sender), nick_name) + + PLEXUS.pub("message", msg_unique_id, room_name, nick_name, avatar, "matrix", self.gateway_name, event.sender, body, attachments, was_edit) elif str(event.type) == "m.room.redaction": if event.redacts not in self.event_id_to_msg_unique_id: return @@ -208,7 +224,9 @@ class GatewayMatrix: if mxc_uri: # https://mementomori.social/@rolle/113732824034474418 async with self.appserv.http_session.get(str(self.appserv.intent.api.get_download_url(mxc_uri, download_type = "thumbnail")) + "?width=128&height=128&method=scale&allow_redirect=true") as resp: - return await resp.read() + if resp.status == 200: + return await resp.read() + return None return None