Handle leaving Matrix rooms

Fixes #28 - Leaving group chat portals leaves the Telegram chat
Fixes #29 - Leaving private chat portals makes the bridge forget that room
This commit is contained in:
Tulir Asokan
2018-01-29 23:01:03 +02:00
parent 4593e1c857
commit b8bcd84c68
4 changed files with 24 additions and 7 deletions
+1 -1
View File
@@ -79,7 +79,7 @@ The bridge does not do this automatically.
* [ ] Inviting Matrix users who have logged in to Telegram * [ ] Inviting Matrix users who have logged in to Telegram
* [ ] Kicking * [ ] Kicking
* [ ] Joining (once room aliases have been implemented) * [ ] Joining (once room aliases have been implemented)
* [ ] Leaving * [x] Leaving
* [ ] Room metadata changes * [ ] Room metadata changes
* Telegram → Matrix * Telegram → Matrix
* [x] Plaintext messages * [x] Plaintext messages
+4 -1
View File
@@ -126,7 +126,10 @@ class MatrixHandler:
def handle_part(self, room, user): def handle_part(self, room, user):
self.log.debug(f"{user} left {room}") 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): def is_command(self, message):
text = message.get("body", "") text = message.get("body", "")
+16 -3
View File
@@ -16,9 +16,10 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
from telethon.tl.functions.messages import (GetFullChatRequest, EditChatAdminRequest, from telethon.tl.functions.messages import (GetFullChatRequest, EditChatAdminRequest,
CreateChatRequest, AddChatUserRequest, CreateChatRequest, AddChatUserRequest,
ExportChatInviteRequest) ExportChatInviteRequest, DeleteChatUserRequest)
from telethon.tl.functions.channels import (GetParticipantsRequest, CreateChannelRequest, from telethon.tl.functions.channels import (GetParticipantsRequest, CreateChannelRequest,
InviteToChannelRequest, ExportInviteRequest) InviteToChannelRequest, ExportInviteRequest,
LeaveChannelRequest)
from telethon.errors.rpc_error_list import ChatAdminRequiredError, LocationInvalidError from telethon.errors.rpc_error_list import ChatAdminRequiredError, LocationInvalidError
from telethon.tl.types import * from telethon.tl.types import *
from PIL import Image from PIL import Image
@@ -267,6 +268,17 @@ class Portal:
file_name = f"matrix_upload{mimetypes.guess_extension(mime)}" file_name = f"matrix_upload{mimetypes.guess_extension(mime)}"
return file_name, None if file_name == body else body 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): def handle_matrix_message(self, sender, message, event_id):
type = message["msgtype"] type = message["msgtype"]
if type in {"m.text", "m.emote"}: if type in {"m.text", "m.emote"}:
@@ -581,7 +593,7 @@ class Portal:
existing = DBPortal.query.get(self.tgid_full) existing = DBPortal.query.get(self.tgid_full)
if existing: if existing:
self.db.object_session(existing).delete(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.tgid = new_id
self.by_tgid[self.tgid_full] = self self.by_tgid[self.tgid_full] = self
self.save() self.save()
@@ -592,6 +604,7 @@ class Portal:
def delete(self): def delete(self):
self.db.delete(self.to_db()) self.db.delete(self.to_db())
self.db.commit()
@classmethod @classmethod
def from_db(cls, db_portal): def from_db(cls, db_portal):
+3 -2
View File
@@ -210,8 +210,9 @@ class User:
elif isinstance(update, (UpdateChatAdmins, UpdateChatParticipantAdmin)): elif isinstance(update, (UpdateChatAdmins, UpdateChatParticipantAdmin)):
self.update_admin(update) self.update_admin(update)
elif isinstance(update, UpdateChatParticipants): elif isinstance(update, UpdateChatParticipants):
portal = po.Portal.get_by_tgid(update.participants.chat_id, peer_type="chat") portal = po.Portal.get_by_tgid(update.participants.chat_id, peer_type=None)
portal.update_telegram_participants(update.participants.participants) if portal and portal.mxid:
portal.update_telegram_participants(update.participants.participants)
else: else:
self.log.debug("Unhandled update: %s", update) self.log.debug("Unhandled update: %s", update)