diff --git a/mautrix_telegram/abstract_user.py b/mautrix_telegram/abstract_user.py index 67af83f8..a36384e5 100644 --- a/mautrix_telegram/abstract_user.py +++ b/mautrix_telegram/abstract_user.py @@ -63,8 +63,8 @@ from telethon.tl.types import ( UpdateShort, UpdateShortChatMessage, UpdateShortMessage, + UpdateUser, UpdateUserName, - UpdateUserPhoto, UpdateUserStatus, UpdateUserTyping, User, @@ -351,7 +351,7 @@ class AbstractUser(ABC): await self.update_default_banned_rights(update) elif isinstance(update, (UpdatePinnedMessages, UpdatePinnedChannelMessages)): await self.update_pinned_messages(update) - elif isinstance(update, (UpdateUserName, UpdateUserPhoto)): + elif isinstance(update, (UpdateUserName, UpdateUser)): await self.update_others_info(update) elif isinstance(update, UpdateReadHistoryOutbox): await self.update_read_receipt(update) @@ -500,7 +500,7 @@ class AbstractUser(ABC): except Exception: self.log.exception("Failed to handle entity updates") - async def update_others_info(self, update: UpdateUserName | UpdateUserPhoto) -> None: + async def update_others_info(self, update: UpdateUserName | UpdateUser) -> None: # TODO duplication not checked puppet = await pu.Puppet.get_by_tgid(TelegramID(update.user_id)) if isinstance(update, UpdateUserName): @@ -514,10 +514,9 @@ class AbstractUser(ABC): if await puppet.update_displayname(self, update): await puppet.save() await puppet.update_portals_meta() - elif isinstance(update, UpdateUserPhoto): - if await puppet.update_avatar(self, update.photo): - await puppet.save() - await puppet.update_portals_meta() + elif isinstance(update, UpdateUser): + info = await self.client.get_entity(puppet.peer) + await puppet.update_info(self, info) else: self.log.warning(f"Unexpected other user info update: {type(update)}") diff --git a/mautrix_telegram/config.py b/mautrix_telegram/config.py index bb71dc2c..9e397a3a 100644 --- a/mautrix_telegram/config.py +++ b/mautrix_telegram/config.py @@ -101,6 +101,7 @@ class Config(BaseBridgeConfig): copy("bridge.displayname_preference") copy("bridge.displayname_max_length") copy("bridge.allow_avatar_remove") + copy("bridge.allow_contact_info") copy("bridge.max_initial_member_sync") copy("bridge.max_member_count") diff --git a/mautrix_telegram/example-config.yaml b/mautrix_telegram/example-config.yaml index 637cec72..0f01d0c0 100644 --- a/mautrix_telegram/example-config.yaml +++ b/mautrix_telegram/example-config.yaml @@ -145,6 +145,9 @@ bridge: # as there's no way to determine whether an avatar is removed or just hidden from some users. If # you're on a single-user instance, this should be safe to enable. allow_avatar_remove: false + # Should contact names and profile pictures be allowed? + # This is only safe to enable on single-user instances. + allow_contact_info: false # Maximum number of members to sync per portal when starting up. Other members will be # synced when they send messages. The maximum is 10000, after which the Telegram server diff --git a/mautrix_telegram/portal_util/message_convert.py b/mautrix_telegram/portal_util/message_convert.py index b73dc42d..f97a96c9 100644 --- a/mautrix_telegram/portal_util/message_convert.py +++ b/mautrix_telegram/portal_util/message_convert.py @@ -409,6 +409,8 @@ class TelegramMessageConverter: mimetype=file.mime_type, size=self._photo_size_key(largest_size), ) + if media.spoiler: + info["fi.mau.telegram.spoiler"] = True ext = sane_mimetypes.guess_extension(file.mime_type) name = f"disappearing_image{ext}" if media.ttl_seconds else f"image{ext}" content = MediaMessageEventContent( @@ -498,6 +500,8 @@ class TelegramMessageConverter: info["fi.mau.autoplay"] = True info["fi.mau.hide_controls"] = True info["fi.mau.no_audio"] = True + if evt.media.spoiler: + info["fi.mau.telegram.spoiler"] = True if not name: ext = sane_mimetypes.guess_extension(file.mime_type) or "" name = "unnamed_file" + ext diff --git a/mautrix_telegram/puppet.py b/mautrix_telegram/puppet.py index 5730ecff..69688707 100644 --- a/mautrix_telegram/puppet.py +++ b/mautrix_telegram/puppet.py @@ -378,6 +378,16 @@ class Puppet(DBPuppet, BasePuppet): ) -> bool: if self.disable_updates: return False + if ( + isinstance(photo, UserProfilePhoto) + and photo.personal + and not self.config["bridge.allow_contact_info"] + ): + self.log.trace( + "Dropping user avatar as it's personal " + "and contact info is disabled in bridge config" + ) + return False if photo is None or isinstance(photo, (UserProfilePhotoEmpty, ChatPhotoEmpty)): photo_id = "" diff --git a/requirements.txt b/requirements.txt index 8d43ecfa..ce158c62 100644 --- a/requirements.txt +++ b/requirements.txt @@ -5,7 +5,7 @@ aiohttp>=3,<4 yarl>=1,<2 mautrix>=0.18.8,<0.19 #telethon>=1.25.4,<1.27 -tulir-telethon==1.27.0a3 +tulir-telethon==1.27.0a4 asyncpg>=0.20,<0.28 mako>=1,<2 setuptools