diff --git a/README.md b/README.md index 8a3b9f61..249a48cd 100644 --- a/README.md +++ b/README.md @@ -79,7 +79,7 @@ The bridge does not do this automatically. * [ ] Inviting Matrix users who have logged in to Telegram * [ ] Kicking * [ ] Joining (once room aliases have been implemented) - * [ ] Leaving + * [x] Leaving * [ ] Room metadata changes * Telegram → Matrix * [x] Plaintext messages diff --git a/mautrix_telegram/matrix.py b/mautrix_telegram/matrix.py index 8bdee033..02d80dc2 100644 --- a/mautrix_telegram/matrix.py +++ b/mautrix_telegram/matrix.py @@ -126,7 +126,10 @@ class MatrixHandler: def handle_part(self, room, user): self.log.debug(f"{user} left {room}") - # user = User.get_by_mxid(user, create=False) + user = User.get_by_mxid(user, create=False) + portal = Portal.get_by_mxid(room) + if portal and user.logged_in: + portal.leave_matrix(user) def is_command(self, message): text = message.get("body", "") diff --git a/mautrix_telegram/portal.py b/mautrix_telegram/portal.py index ff20afff..4b4221ea 100644 --- a/mautrix_telegram/portal.py +++ b/mautrix_telegram/portal.py @@ -16,9 +16,10 @@ # along with this program. If not, see . from telethon.tl.functions.messages import (GetFullChatRequest, EditChatAdminRequest, CreateChatRequest, AddChatUserRequest, - ExportChatInviteRequest) + ExportChatInviteRequest, DeleteChatUserRequest) from telethon.tl.functions.channels import (GetParticipantsRequest, CreateChannelRequest, - InviteToChannelRequest, ExportInviteRequest) + InviteToChannelRequest, ExportInviteRequest, + LeaveChannelRequest) from telethon.errors.rpc_error_list import ChatAdminRequiredError, LocationInvalidError from telethon.tl.types import * from PIL import Image @@ -267,6 +268,17 @@ class Portal: file_name = f"matrix_upload{mimetypes.guess_extension(mime)}" return file_name, None if file_name == body else body + def leave_matrix(self, user): + if self.peer_type == "user": + self.main_intent.leave_room(self.mxid) + self.delete() + del self.by_tgid[self.tgid_full] + del self.by_mxid[self.mxid] + elif self.peer_type == "chat": + user.client(DeleteChatUserRequest(chat_id=self.tgid, user_id=InputUserSelf())) + elif self.peer_type == "channel": + user.client(LeaveChannelRequest(channel=user.client.get_input_entity(self.peer))) + def handle_matrix_message(self, sender, message, event_id): type = message["msgtype"] if type in {"m.text", "m.emote"}: @@ -581,7 +593,7 @@ class Portal: existing = DBPortal.query.get(self.tgid_full) if existing: self.db.object_session(existing).delete(existing) - self.by_tgid[self.tgid_full] = None + del self.by_tgid[self.tgid_full] self.tgid = new_id self.by_tgid[self.tgid_full] = self self.save() @@ -592,6 +604,7 @@ class Portal: def delete(self): self.db.delete(self.to_db()) + self.db.commit() @classmethod def from_db(cls, db_portal): diff --git a/mautrix_telegram/user.py b/mautrix_telegram/user.py index 9a729852..69eb0e1f 100644 --- a/mautrix_telegram/user.py +++ b/mautrix_telegram/user.py @@ -210,8 +210,9 @@ 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="chat") - portal.update_telegram_participants(update.participants.participants) + portal = po.Portal.get_by_tgid(update.participants.chat_id, peer_type=None) + if portal and portal.mxid: + portal.update_telegram_participants(update.participants.participants) else: self.log.debug("Unhandled update: %s", update)