From 429cb07b79ad3b29cf57545f56af2aaf9de4a6d5 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Sun, 14 Feb 2021 16:36:21 +0200 Subject: [PATCH] Handle missing input entities better when creating groups. Fixes #379 --- .../commands/portal/create_chat.py | 8 +++- mautrix_telegram/portal/metadata.py | 38 ++++++++++++------- 2 files changed, 31 insertions(+), 15 deletions(-) diff --git a/mautrix_telegram/commands/portal/create_chat.py b/mautrix_telegram/commands/portal/create_chat.py index c2271b38..c48a0f47 100644 --- a/mautrix_telegram/commands/portal/create_chat.py +++ b/mautrix_telegram/commands/portal/create_chat.py @@ -52,8 +52,14 @@ async def create(evt: CommandEvent) -> EventID: portal = po.Portal(tgid=TelegramID(0), peer_type=type, mxid=evt.room_id, title=title, about=about, encrypted=encrypted) + invites, errors = await portal.get_telegram_users_in_matrix_room(evt.sender) + if len(errors) > 0: + error_list = "\n".join(f"* [{mxid}](https://matrix.to/#/{mxid})" for mxid in errors) + await evt.reply(f"Failed to add the following users to the chat:\n\n{error_list}\n\n" + "You can try `$cmdprefix+sp search -r ` to help the bridge find " + "those users.") try: - await portal.create_telegram_chat(evt.sender, supergroup=supergroup) + await portal.create_telegram_chat(evt.sender, invites=invites, supergroup=supergroup) except ValueError as e: await portal.delete() return await evt.reply(e.args[0]) diff --git a/mautrix_telegram/portal/metadata.py b/mautrix_telegram/portal/metadata.py index a8c18702..7f7d3660 100644 --- a/mautrix_telegram/portal/metadata.py +++ b/mautrix_telegram/portal/metadata.py @@ -13,7 +13,7 @@ # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . -from typing import List, Optional, Iterable, Union, Dict, Any, TYPE_CHECKING +from typing import List, Optional, Iterable, Union, Dict, Any, Tuple, TYPE_CHECKING from abc import ABC import asyncio @@ -26,7 +26,8 @@ from telethon.tl.types import ( Channel, ChatBannedRights, ChannelParticipantsRecent, ChannelParticipantsSearch, ChatPhoto, PhotoEmpty, InputChannel, InputUser, ChatPhotoEmpty, PeerUser, Photo, TypeChat, TypeInputPeer, TypeUser, User, InputPeerPhotoFileLocation, ChatParticipantAdmin, ChannelParticipantAdmin, - ChatParticipantCreator, ChannelParticipantCreator, UserProfilePhoto, UserProfilePhotoEmpty) + ChatParticipantCreator, ChannelParticipantCreator, UserProfilePhoto, UserProfilePhotoEmpty, + InputPeerUser) from mautrix.errors import MForbidden from mautrix.types import (RoomID, UserID, RoomCreatePreset, EventType, Membership, @@ -58,21 +59,30 @@ class PortalMetadata(BasePortal, ABC): # region Matrix -> Telegram - async def _get_telegram_users_in_matrix_room(self) -> List[Union[InputUser, PeerUser]]: - user_tgids = set() + async def get_telegram_users_in_matrix_room(self, source: 'u.User' + ) -> Tuple[List[InputPeerUser], List[UserID]]: + user_tgids = {} user_mxids = await self.main_intent.get_room_members(self.mxid, (Membership.JOIN, Membership.INVITE)) - for user_str in user_mxids: - user = UserID(user_str) - if user == self.az.bot_mxid: + for mxid in user_mxids: + if mxid == self.az.bot_mxid: continue - mx_user = u.User.get_by_mxid(user, create=False) + mx_user = u.User.get_by_mxid(mxid, create=False) if mx_user and mx_user.tgid: - user_tgids.add(mx_user.tgid) - puppet_id = p.Puppet.get_id_from_mxid(user) + user_tgids[mx_user.tgid] = mxid + puppet_id = p.Puppet.get_id_from_mxid(mxid) if puppet_id: - user_tgids.add(puppet_id) - return [PeerUser(user_id) for user_id in user_tgids] + user_tgids[puppet_id] = mxid + input_users = [] + errors = [] + for tgid, mxid in user_tgids.items(): + try: + input_users.append(await source.client.get_input_entity(tgid)) + except ValueError as e: + source.log.debug(f"Failed to find the input entity for {tgid} ({mxid}) for " + f"creating a group: {e}") + errors.append(mxid) + return input_users, errors async def upgrade_telegram_chat(self, source: 'u.User') -> None: if self.peer_type != "chat": @@ -116,13 +126,13 @@ class PortalMetadata(BasePortal, ABC): if await self._update_username(username): await self.save() - async def create_telegram_chat(self, source: 'u.User', supergroup: bool = False) -> None: + async def create_telegram_chat(self, source: 'u.User', invites: List[InputUser], + supergroup: bool = False) -> None: if not self.mxid: raise ValueError("Can't create Telegram chat for portal without Matrix room.") elif self.tgid: raise ValueError("Can't create Telegram chat for portal with existing Telegram chat.") - invites = await self._get_telegram_users_in_matrix_room() if len(invites) < 2: if self.bot is not None: info, mxid = await self.bot.get_me()