From 51359747ca5ded729a34b6cf226df7361834133e Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Sun, 4 Feb 2018 23:17:37 +0200 Subject: [PATCH] Add Telegram->Matrix message pinning support --- README.md | 2 +- mautrix_appservice/intent_api.py | 22 ++++++++++++++++++++++ mautrix_telegram/portal.py | 7 +++++++ mautrix_telegram/user.py | 10 +++++++++- 4 files changed, 39 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index c1d31531..b7ba988f 100644 --- a/README.md +++ b/README.md @@ -105,7 +105,7 @@ The bridge does not do this automatically. * [x] Avatars * [x] Presence * [x] Typing notifications - * [ ] Pinning messages + * [x] Pinning messages * [x] Admin/chat creator status * [ ] Supergroup/channel permissions * [x] Membership actions diff --git a/mautrix_appservice/intent_api.py b/mautrix_appservice/intent_api.py index 67c7d7ff..f08b3c3e 100644 --- a/mautrix_appservice/intent_api.py +++ b/mautrix_appservice/intent_api.py @@ -231,6 +231,28 @@ class IntentAPI: self.state_store.set_power_levels(room_id, content) return response + def get_pinned_messages(self, room_id): + self.ensure_joined(room_id) + response = self.client._send("GET", f"/rooms/{room_id}/state/m.room.pinned_events") + return response["content"]["pinned"] + + def set_pinned_messages(self, room_id, events): + return self.send_state_event(room_id, "m.room.pinned_events", { + "pinned": events + }) + + def pin_message(self, room_id, event_id): + events = self.get_pinned_messages(room_id) + if event_id not in events: + events.append(event_id) + self.set_pinned_messages(room_id, events) + + def unpin_message(self, room_id, event_id): + events = self.get_pinned_messages(room_id) + if event_id in events: + events.remove(event_id) + self.set_pinned_messages(room_id, events) + def set_typing(self, room_id, is_typing=True, timeout=5000): self.ensure_joined(room_id) return self.client.set_typing(room_id, is_typing, timeout) diff --git a/mautrix_telegram/portal.py b/mautrix_telegram/portal.py index 09040f4f..0fb9b367 100644 --- a/mautrix_telegram/portal.py +++ b/mautrix_telegram/portal.py @@ -652,6 +652,13 @@ class Portal: levels["users"][puppet.mxid] = 50 self.main_intent.set_power_levels(self.mxid, levels) + def update_telegram_pin(self, source, id): + message = DBMessage.query.get((id, source.tgid)) + if message: + self.main_intent.set_pinned_messages(self.mxid, [message.mxid]) + else: + self.main_intent.set_pinned_messages(self.mxid, []) + def update_telegram_participants(self, participants): levels = self.main_intent.get_power_levels(self.mxid) changed = False diff --git a/mautrix_telegram/user.py b/mautrix_telegram/user.py index 0bfc0801..c0add044 100644 --- a/mautrix_telegram/user.py +++ b/mautrix_telegram/user.py @@ -216,9 +216,13 @@ class User: elif isinstance(update, (UpdateChatAdmins, UpdateChatParticipantAdmin)): self.update_admin(update) elif isinstance(update, UpdateChatParticipants): - portal = po.Portal.get_by_tgid(update.participants.chat_id, peer_type=None) + portal = po.Portal.get_by_tgid(update.participants.chat_id) if portal and portal.mxid: portal.update_telegram_participants(update.participants.participants) + elif isinstance(update, UpdateChannelPinnedMessage): + portal = po.Portal.get_by_tgid(update.channel_id, peer_type="channel") + if portal and portal.mxid: + portal.update_telegram_pin(self, update.id) else: self.log.debug("Unhandled update: %s", update) @@ -262,6 +266,10 @@ class User: else: portal = po.Portal.get_by_entity(update.to_id, receiver_id=self.tgid) sender = pu.Puppet.get(update.from_id) + else: + self.log.warning( + f"Unexpected message type in User#get_message_details: {type(update)}") + return update, None, None return update, sender, portal def update_message(self, update):