Add option to update m.direct with double puppeting

This commit is contained in:
Tulir Asokan
2020-08-21 21:20:49 +03:00
parent 292745866d
commit 66917b6db0
7 changed files with 33 additions and 6 deletions
+3
View File
@@ -130,5 +130,8 @@ class TelegramBridge(Bridge):
async def get_double_puppet(self, user_id: UserID) -> Puppet: async def get_double_puppet(self, user_id: UserID) -> Puppet:
return await Puppet.get_by_custom_mxid(user_id) return await Puppet.get_by_custom_mxid(user_id)
def is_bridge_ghost(self, user_id: UserID) -> bool:
return bool(Puppet.get_id_from_mxid(user_id))
TelegramBridge().run() TelegramBridge().run()
+3
View File
@@ -48,6 +48,8 @@ class Config(BaseBridgeConfig):
super().do_update(helper) super().do_update(helper)
copy, copy_dict, base = helper copy, copy_dict, base = helper
copy("homeserver.asmux")
if "appservice.protocol" in self and "appservice.address" not in self: if "appservice.protocol" in self and "appservice.address" not in self:
protocol, hostname, port = (self["appservice.protocol"], self["appservice.hostname"], protocol, hostname, port = (self["appservice.protocol"], self["appservice.hostname"],
self["appservice.port"]) self["appservice.port"])
@@ -102,6 +104,7 @@ class Config(BaseBridgeConfig):
copy("bridge.plaintext_highlights") copy("bridge.plaintext_highlights")
copy("bridge.public_portals") copy("bridge.public_portals")
copy("bridge.sync_with_custom_puppets") copy("bridge.sync_with_custom_puppets")
copy("bridge.sync_direct_chat_list")
copy("bridge.login_shared_secret") copy("bridge.login_shared_secret")
copy("bridge.telegram_link_preview") copy("bridge.telegram_link_preview")
copy("bridge.inline_images") copy("bridge.inline_images")
+4
View File
@@ -49,6 +49,10 @@ class Portal(Base):
def get_by_tgid(cls, tgid: TelegramID, tg_receiver: TelegramID) -> Optional['Portal']: def get_by_tgid(cls, tgid: TelegramID, tg_receiver: TelegramID) -> Optional['Portal']:
return cls._select_one_or_none(cls.c.tgid == tgid, cls.c.tg_receiver == tg_receiver) return cls._select_one_or_none(cls.c.tgid == tgid, cls.c.tg_receiver == tg_receiver)
@classmethod
def find_private_chats(cls, tg_receiver: TelegramID) -> Iterable['Portal']:
yield from cls._select_all(cls.c.tg_receiver == tg_receiver, cls.c.peer_type == "user")
@classmethod @classmethod
def get_by_mxid(cls, mxid: RoomID) -> Optional['Portal']: def get_by_mxid(cls, mxid: RoomID) -> Optional['Portal']:
return cls._select_one_or_none(cls.c.mxid == mxid) return cls._select_one_or_none(cls.c.mxid == mxid)
+7 -2
View File
@@ -7,6 +7,7 @@ homeserver:
# Whether or not to verify the SSL certificate of the homeserver. # Whether or not to verify the SSL certificate of the homeserver.
# Only applies if address starts with https:// # Only applies if address starts with https://
verify_ssl: true verify_ssl: true
asmux: false
# Application service host/registration related details # Application service host/registration related details
# Changing these values requires regeneration of the registration. # Changing these values requires regeneration of the registration.
@@ -163,9 +164,13 @@ bridge:
plaintext_highlights: false plaintext_highlights: false
# Whether or not to make portals of publicly joinable channels/supergroups publicly joinable on Matrix. # Whether or not to make portals of publicly joinable channels/supergroups publicly joinable on Matrix.
public_portals: true public_portals: true
# Whether or not to use /sync to get presence, read receipts and typing notifications when using # Whether or not to use /sync to get presence, read receipts and typing notifications
# your own Matrix account as the Matrix puppet for your Telegram account. # when double puppeting is enabled
sync_with_custom_puppets: true sync_with_custom_puppets: true
# Whether or not to update the m.direct account data event when double puppeting is enabled.
# Note that updating the m.direct event is not atomic (except with mautrix-asmux)
# and is therefore prone to race conditions.
sync_direct_chat_list: false
# Shared secret for https://github.com/devture/matrix-synapse-shared-secret-auth # Shared secret for https://github.com/devture/matrix-synapse-shared-secret-auth
# #
# If set, custom puppets will be enabled automatically for local users # If set, custom puppets will be enabled automatically for local users
+3 -1
View File
@@ -220,7 +220,9 @@ class PortalMetadata(BasePortal, ABC):
puppet = await p.Puppet.get_by_custom_mxid(user.mxid) puppet = await p.Puppet.get_by_custom_mxid(user.mxid)
if puppet: if puppet:
try: try:
await puppet.intent.ensure_joined(self.mxid) did_join = await puppet.intent.ensure_joined(self.mxid)
if isinstance(user, u.User) and did_join and self.peer_type == "user":
await user.update_direct_chats({self.main_intent.mxid: [self.mxid]})
except Exception: except Exception:
self.log.exception("Failed to ensure %s is joined to portal", user.mxid) self.log.exception("Failed to ensure %s is joined to portal", user.mxid)
+12 -2
View File
@@ -28,12 +28,12 @@ from telethon.tl.functions.account import UpdateStatusRequest
from mautrix.client import Client from mautrix.client import Client
from mautrix.errors import MatrixRequestError from mautrix.errors import MatrixRequestError
from mautrix.types import UserID from mautrix.types import UserID, RoomID
from mautrix.bridge import BaseUser from mautrix.bridge import BaseUser
from mautrix.util.logging import TraceLogger from mautrix.util.logging import TraceLogger
from .types import TelegramID from .types import TelegramID
from .db import User as DBUser from .db import User as DBUser, Portal as DBPortal
from .abstract_user import AbstractUser from .abstract_user import AbstractUser
from . import portal as po, puppet as pu from . import portal as po, puppet as pu
@@ -79,6 +79,7 @@ class User(AbstractUser, BaseUser):
self.db_portals = db_portals or [] self.db_portals = db_portals or []
self._db_instance = db_instance self._db_instance = db_instance
self._ensure_started_lock = asyncio.Lock() self._ensure_started_lock = asyncio.Lock()
self.dm_update_lock = asyncio.Lock()
self.command_status = None self.command_status = None
@@ -340,6 +341,13 @@ class User(AbstractUser, BaseUser):
except Exception: except Exception:
self.log.exception(f"Error while {action}") self.log.exception(f"Error while {action}")
async def get_direct_chats(self) -> Dict[UserID, List[RoomID]]:
return {
pu.Puppet.get_mxid_from_id(portal.tgid): [portal.mxid]
for portal in DBPortal.find_private_chats(self.tgid)
if portal.mxid
}
async def sync_dialogs(self) -> None: async def sync_dialogs(self) -> None:
if self.is_bot: if self.is_bot:
return return
@@ -378,6 +386,7 @@ class User(AbstractUser, BaseUser):
index += 1 index += 1
await self.save(portals=True) await self.save(portals=True)
await asyncio.gather(*creators) await asyncio.gather(*creators)
await self.update_direct_chats()
self.log.debug("Dialog syncing complete") self.log.debug("Dialog syncing complete")
async def register_portal(self, portal: po.Portal) -> None: async def register_portal(self, portal: po.Portal) -> None:
@@ -482,6 +491,7 @@ class User(AbstractUser, BaseUser):
def init(context: 'Context') -> Iterable[Awaitable['User']]: def init(context: 'Context') -> Iterable[Awaitable['User']]:
global config global config
config = context.config config = context.config
User.bridge = context.bridge
return (User.from_db(db_user).try_ensure_started() return (User.from_db(db_user).try_ensure_started()
for db_user in DBUser.all_with_tgid()) for db_user in DBUser.all_with_tgid())
+1 -1
View File
@@ -4,6 +4,6 @@ ruamel.yaml>=0.15.35,<0.17
python-magic>=0.4,<0.5 python-magic>=0.4,<0.5
commonmark>=0.8,<0.10 commonmark>=0.8,<0.10
aiohttp>=3,<4 aiohttp>=3,<4
mautrix==0.7.0rc1 mautrix==0.7.0rc2
telethon>=1.16,<1.17 telethon>=1.16,<1.17
telethon-session-sqlalchemy>=0.2.14,<0.3 telethon-session-sqlalchemy>=0.2.14,<0.3