forked from fair/matrix-puppeteer-line
Kick own puppets when turning on double puppeting
And invite them when turning it off
This commit is contained in:
parent
a2a21927cd
commit
baf7db73b7
|
@ -79,7 +79,8 @@ bridge:
|
||||||
# Set 0 to disable automatic syncing.
|
# Set 0 to disable automatic syncing.
|
||||||
initial_conversation_sync: 10
|
initial_conversation_sync: 10
|
||||||
# Whether or not the LINE users of logged in Matrix users should be
|
# Whether or not the LINE users of logged in Matrix users should be
|
||||||
# invited to private chats when the user sends a message from another client.
|
# invited to rooms when the user sends a message from another client.
|
||||||
|
# NOTE: This setting is forced to "false" when custom puppets are enabled.
|
||||||
invite_own_puppet_to_pm: false
|
invite_own_puppet_to_pm: 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
|
||||||
#
|
#
|
||||||
|
|
|
@ -29,7 +29,7 @@ from mautrix.types import (EventID, MessageEventContent, RoomID, EventType, Mess
|
||||||
TextMessageEventContent, MediaMessageEventContent, Membership, Format,
|
TextMessageEventContent, MediaMessageEventContent, Membership, Format,
|
||||||
ContentURI, EncryptedFile, ImageInfo,
|
ContentURI, EncryptedFile, ImageInfo,
|
||||||
RelatesTo, RelationType)
|
RelatesTo, RelationType)
|
||||||
from mautrix.errors import MatrixError
|
from mautrix.errors import IntentError, MatrixError
|
||||||
from mautrix.util.simple_lock import SimpleLock
|
from mautrix.util.simple_lock import SimpleLock
|
||||||
|
|
||||||
from .db import Portal as DBPortal, Message as DBMessage, ReceiptReaction as DBReceiptReaction, Media as DBMedia
|
from .db import Portal as DBPortal, Message as DBMessage, ReceiptReaction as DBReceiptReaction, Media as DBMedia
|
||||||
|
@ -91,6 +91,12 @@ class Portal(DBPortal, BasePortal):
|
||||||
def is_room(self) -> bool:
|
def is_room(self) -> bool:
|
||||||
return self.chat_id[0] == "r"
|
return self.chat_id[0] == "r"
|
||||||
|
|
||||||
|
@property
|
||||||
|
def needs_bridgebot(self) -> bool:
|
||||||
|
# TODO Ask Tulir why e2b needs the bridgebot to be in the room
|
||||||
|
# Reminder that the bridgebot's intent is used for non-DM rooms
|
||||||
|
return not self.is_direct or (self.encrypted and self.matrix.e2ee)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def main_intent(self) -> IntentAPI:
|
def main_intent(self) -> IntentAPI:
|
||||||
if not self._main_intent:
|
if not self._main_intent:
|
||||||
|
@ -110,6 +116,7 @@ class Portal(DBPortal, BasePortal):
|
||||||
NotificationDisabler.config_enabled = cls.config["bridge.backfill.disable_notifications"]
|
NotificationDisabler.config_enabled = cls.config["bridge.backfill.disable_notifications"]
|
||||||
|
|
||||||
async def _send_delivery_receipt(self, event_id: EventID) -> None:
|
async def _send_delivery_receipt(self, event_id: EventID) -> None:
|
||||||
|
# TODO Also send receipt from own puppet, if it's in the room
|
||||||
if event_id and self.config["bridge.delivery_receipts"]:
|
if event_id and self.config["bridge.delivery_receipts"]:
|
||||||
try:
|
try:
|
||||||
await self.az.intent.mark_read(self.mxid, event_id)
|
await self.az.intent.mark_read(self.mxid, event_id)
|
||||||
|
@ -187,7 +194,15 @@ class Portal(DBPortal, BasePortal):
|
||||||
intent = sender.intent if sender else self.az.intent
|
intent = sender.intent if sender else self.az.intent
|
||||||
if self.is_direct and (sender is None or sender.mid == source.mid and not sender.is_real_user):
|
if self.is_direct and (sender is None or sender.mid == source.mid and not sender.is_real_user):
|
||||||
if self.invite_own_puppet_to_pm and invite:
|
if self.invite_own_puppet_to_pm and invite:
|
||||||
|
try:
|
||||||
|
await intent.ensure_joined(self.mxid)
|
||||||
|
except IntentError as e:
|
||||||
|
if self.main_intent != self.az.intent:
|
||||||
await self.main_intent.invite_user(self.mxid, intent.mxid)
|
await self.main_intent.invite_user(self.mxid, intent.mxid)
|
||||||
|
await intent.ensure_joined(self.mxid)
|
||||||
|
else:
|
||||||
|
self.log.warning(f"Unable to invite own puppet to {self.mxid}: {e}")
|
||||||
|
intent = None
|
||||||
elif await self.az.state_store.get_membership(self.mxid,
|
elif await self.az.state_store.get_membership(self.mxid,
|
||||||
intent.mxid) != Membership.JOIN:
|
intent.mxid) != Membership.JOIN:
|
||||||
self.log.warning(f"Ignoring own {mid} in private chat because own puppet is not in"
|
self.log.warning(f"Ignoring own {mid} in private chat because own puppet is not in"
|
||||||
|
@ -427,9 +442,16 @@ class Portal(DBPortal, BasePortal):
|
||||||
return
|
return
|
||||||
self._last_participant_update = current_members
|
self._last_participant_update = current_members
|
||||||
|
|
||||||
|
# TODO When supporting multiple bridge users, do this per user
|
||||||
|
forbid_own_puppets = \
|
||||||
|
not self.invite_own_puppet_to_pm or \
|
||||||
|
(await u.User.get_by_mxid(self.config["bridge.user"], False)).intent is not None
|
||||||
|
|
||||||
# Make sure puppets who should be here are here
|
# Make sure puppets who should be here are here
|
||||||
for participant in participants:
|
for participant in participants:
|
||||||
puppet = await p.Puppet.get_by_mid(participant.id)
|
puppet = await p.Puppet.get_by_mid(participant.id)
|
||||||
|
if forbid_own_puppets and p.Puppet.is_mid_for_own_puppet(participant.id):
|
||||||
|
continue
|
||||||
await puppet.intent.ensure_joined(self.mxid)
|
await puppet.intent.ensure_joined(self.mxid)
|
||||||
|
|
||||||
print(current_members)
|
print(current_members)
|
||||||
|
@ -437,12 +459,18 @@ class Portal(DBPortal, BasePortal):
|
||||||
# Kick puppets who shouldn't be here
|
# Kick puppets who shouldn't be here
|
||||||
for user_id in await self.main_intent.get_room_members(self.mxid):
|
for user_id in await self.main_intent.get_room_members(self.mxid):
|
||||||
if user_id == self.az.bot_mxid:
|
if user_id == self.az.bot_mxid:
|
||||||
|
if forbid_own_puppets and not self.needs_bridgebot:
|
||||||
|
await self.az.intent.leave_room(self.mxid)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
mid = p.Puppet.get_id_from_mxid(user_id)
|
mid = p.Puppet.get_id_from_mxid(user_id)
|
||||||
if mid and mid not in current_members:
|
if mid and mid not in current_members:
|
||||||
print(mid)
|
print(mid)
|
||||||
await self.main_intent.kick_user(self.mxid, user_id,
|
await self.main_intent.kick_user(self.mxid, user_id,
|
||||||
reason="User had left this chat")
|
reason="User had left this chat")
|
||||||
|
elif forbid_own_puppets and p.Puppet.is_mid_for_own_puppet(mid):
|
||||||
|
await self.main_intent.kick_user(self.mxid, user_id,
|
||||||
|
reason="Kicking own puppet")
|
||||||
|
|
||||||
async def backfill(self, source: 'u.User') -> None:
|
async def backfill(self, source: 'u.User') -> None:
|
||||||
try:
|
try:
|
||||||
|
@ -594,7 +622,7 @@ class Portal(DBPortal, BasePortal):
|
||||||
if not self.mxid:
|
if not self.mxid:
|
||||||
raise Exception("Failed to create room: no mxid returned")
|
raise Exception("Failed to create room: no mxid returned")
|
||||||
|
|
||||||
if self.encrypted and self.matrix.e2ee and self.is_direct:
|
if self.needs_bridgebot:
|
||||||
try:
|
try:
|
||||||
await self.az.intent.ensure_joined(self.mxid)
|
await self.az.intent.ensure_joined(self.mxid)
|
||||||
except Exception:
|
except Exception:
|
||||||
|
|
|
@ -148,6 +148,11 @@ class Puppet(DBPuppet, BasePuppet):
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
# TODO When supporting multiple bridge users, this should return the user whose puppet this is
|
||||||
|
@classmethod
|
||||||
|
def is_mid_for_own_puppet(cls, mid) -> bool:
|
||||||
|
return mid.startswith("_OWN_") if mid else False
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
async def get_by_custom_mxid(cls, mxid: UserID) -> Optional['u.User']:
|
async def get_by_custom_mxid(cls, mxid: UserID) -> Optional['u.User']:
|
||||||
if mxid == cls.config["bridge.user"]:
|
if mxid == cls.config["bridge.user"]:
|
||||||
|
|
Loading…
Reference in New Issue