Merge branch 'telethon-1.17'
This commit is contained in:
@@ -31,7 +31,7 @@ from telethon.tl.types import (
|
||||
UpdateEditChannelMessage, UpdateEditMessage, UpdateNewChannelMessage, UpdateReadHistoryOutbox,
|
||||
UpdateShortChatMessage, UpdateShortMessage, UpdateUserName, UpdateUserPhoto, UpdateUserStatus,
|
||||
UpdateUserTyping, User, UserStatusOffline, UserStatusOnline, UpdateReadHistoryInbox,
|
||||
UpdateReadChannelInbox)
|
||||
UpdateReadChannelInbox, MessageEmpty)
|
||||
|
||||
from mautrix.types import UserID, PresenceState
|
||||
from mautrix.errors import MatrixError
|
||||
@@ -164,6 +164,7 @@ class AbstractUser(ABC):
|
||||
request_retries=config["telegram.connection.request_retries"],
|
||||
connection=connection,
|
||||
proxy=proxy,
|
||||
raise_last_call_error=True,
|
||||
|
||||
loop=self.loop,
|
||||
base_logger=base_logger
|
||||
@@ -387,12 +388,15 @@ class AbstractUser(ABC):
|
||||
elif isinstance(update, (UpdateNewMessage, UpdateNewChannelMessage,
|
||||
UpdateEditMessage, UpdateEditChannelMessage)):
|
||||
update = update.message
|
||||
if isinstance(update, MessageEmpty):
|
||||
return update, None, None
|
||||
if isinstance(update.to_id, PeerUser) and not update.out:
|
||||
portal = po.Portal.get_by_tgid(update.from_id, peer_type="user",
|
||||
tg_receiver=self.tgid)
|
||||
else:
|
||||
portal = po.Portal.get_by_entity(update.to_id, receiver_id=self.tgid)
|
||||
sender = pu.Puppet.get(update.from_id) if update.from_id else None
|
||||
sender = (pu.Puppet.get(TelegramID(update.from_id.user_id))
|
||||
if isinstance(update.from_id, PeerUser) else None)
|
||||
else:
|
||||
self.log.warning("Unexpected message type in User#get_message_details: "
|
||||
f"{type(update)}")
|
||||
|
||||
@@ -22,7 +22,7 @@ from telethon.tl.types import (MessageEntityMention, MessageEntityMentionName, M
|
||||
MessageEntityEmail, MessageEntityTextUrl, MessageEntityBold,
|
||||
MessageEntityItalic, MessageEntityCode, MessageEntityPre,
|
||||
MessageEntityBotCommand, MessageEntityHashtag, MessageEntityCashtag,
|
||||
MessageEntityPhone, TypeMessageEntity, PeerChannel,
|
||||
MessageEntityPhone, TypeMessageEntity, PeerChannel, PeerChat,
|
||||
MessageEntityBlockquote, MessageEntityStrike, MessageFwdHeader,
|
||||
MessageEntityUnderline, PeerUser)
|
||||
from telethon.tl.custom import Message
|
||||
@@ -45,11 +45,11 @@ log: logging.Logger = logging.getLogger("mau.fmt.tg")
|
||||
|
||||
|
||||
def telegram_reply_to_matrix(evt: Message, source: 'AbstractUser') -> Optional[RelatesTo]:
|
||||
if evt.reply_to_msg_id:
|
||||
space = (evt.to_id.channel_id
|
||||
if isinstance(evt, Message) and isinstance(evt.to_id, PeerChannel)
|
||||
if evt.reply_to:
|
||||
space = (evt.peer_id.channel_id
|
||||
if isinstance(evt, Message) and isinstance(evt.peer_id, PeerChannel)
|
||||
else source.tgid)
|
||||
msg = DBMessage.get_one_by_tgid(TelegramID(evt.reply_to_msg_id), space)
|
||||
msg = DBMessage.get_one_by_tgid(TelegramID(evt.reply_to.reply_to_msg_id), space)
|
||||
if msg:
|
||||
return RelatesTo(rel_type=RelationType.REFERENCE, event_id=msg.mxid)
|
||||
return None
|
||||
@@ -61,15 +61,15 @@ async def _add_forward_header(source: 'AbstractUser', content: TextMessageEventC
|
||||
content.format = Format.HTML
|
||||
content.formatted_body = escape(content.body)
|
||||
fwd_from_html, fwd_from_text = None, None
|
||||
if fwd_from.from_id:
|
||||
user = u.User.get_by_tgid(TelegramID(fwd_from.from_id))
|
||||
if isinstance(fwd_from.from_id, PeerUser):
|
||||
user = u.User.get_by_tgid(TelegramID(fwd_from.from_id.user_id))
|
||||
if user:
|
||||
fwd_from_text = user.displayname or user.mxid
|
||||
fwd_from_html = (f"<a href='https://matrix.to/#/{user.mxid}'>"
|
||||
f"{escape(fwd_from_text)}</a>")
|
||||
|
||||
if not fwd_from_text:
|
||||
puppet = pu.Puppet.get(TelegramID(fwd_from.from_id), create=False)
|
||||
puppet = pu.Puppet.get(TelegramID(fwd_from.from_id.user_id), create=False)
|
||||
if puppet and puppet.displayname:
|
||||
fwd_from_text = puppet.displayname or puppet.mxid
|
||||
fwd_from_html = (f"<a href='https://matrix.to/#/{puppet.mxid}'>"
|
||||
@@ -77,14 +77,16 @@ async def _add_forward_header(source: 'AbstractUser', content: TextMessageEventC
|
||||
|
||||
if not fwd_from_text:
|
||||
try:
|
||||
user = await source.client.get_entity(PeerUser(fwd_from.from_id))
|
||||
user = await source.client.get_entity(fwd_from.from_id)
|
||||
if user:
|
||||
fwd_from_text = pu.Puppet.get_displayname(user, False)
|
||||
fwd_from_html = f"<b>{escape(fwd_from_text)}</b>"
|
||||
except (ValueError, RPCError):
|
||||
fwd_from_text = fwd_from_html = "unknown user"
|
||||
elif fwd_from.channel_id:
|
||||
portal = po.Portal.get_by_tgid(TelegramID(fwd_from.channel_id))
|
||||
elif isinstance(fwd_from.from_id, (PeerChannel, PeerChat)):
|
||||
from_id = (fwd_from.from_id.chat_id if isinstance(fwd_from.from_id, PeerChat)
|
||||
else fwd_from.from_id.channel_id)
|
||||
portal = po.Portal.get_by_tgid(TelegramID(from_id))
|
||||
if portal:
|
||||
fwd_from_text = portal.title
|
||||
if portal.alias:
|
||||
@@ -94,7 +96,7 @@ async def _add_forward_header(source: 'AbstractUser', content: TextMessageEventC
|
||||
fwd_from_html = f"channel <b>{escape(fwd_from_text)}</b>"
|
||||
else:
|
||||
try:
|
||||
channel = await source.client.get_entity(PeerChannel(fwd_from.channel_id))
|
||||
channel = await source.client.get_entity(fwd_from.from_id)
|
||||
if channel:
|
||||
fwd_from_text = f"channel {channel.title}"
|
||||
fwd_from_html = f"channel <b>{escape(channel.title)}</b>"
|
||||
@@ -116,11 +118,11 @@ async def _add_forward_header(source: 'AbstractUser', content: TextMessageEventC
|
||||
|
||||
async def _add_reply_header(source: 'AbstractUser', content: TextMessageEventContent, evt: Message,
|
||||
main_intent: IntentAPI):
|
||||
space = (evt.to_id.channel_id
|
||||
if isinstance(evt, Message) and isinstance(evt.to_id, PeerChannel)
|
||||
space = (evt.peer_id.channel_id
|
||||
if isinstance(evt, Message) and isinstance(evt.peer_id, PeerChannel)
|
||||
else source.tgid)
|
||||
|
||||
msg = DBMessage.get_one_by_tgid(TelegramID(evt.reply_to_msg_id), space)
|
||||
msg = DBMessage.get_one_by_tgid(TelegramID(evt.reply_to.reply_to_msg_id), space)
|
||||
if not msg:
|
||||
return
|
||||
|
||||
@@ -162,7 +164,7 @@ async def telegram_to_matrix(evt: Message, source: "AbstractUser",
|
||||
if evt.fwd_from:
|
||||
await _add_forward_header(source, content, evt.fwd_from)
|
||||
|
||||
if evt.reply_to_msg_id and not no_reply_fallback:
|
||||
if evt.reply_to and not no_reply_fallback:
|
||||
await _add_reply_header(source, content, evt, main_intent)
|
||||
|
||||
if isinstance(evt, Message) and evt.post and evt.post_author:
|
||||
|
||||
@@ -87,9 +87,9 @@ class PortalMatrix(BasePortal, ABC):
|
||||
message = await self._get_state_change_message(event, user, **kwargs)
|
||||
if not message:
|
||||
return
|
||||
response = await self.bot.client.send_message(
|
||||
self.peer, message,
|
||||
parse_mode=self._matrix_event_to_entities)
|
||||
message, entities = formatter.matrix_to_telegram(message)
|
||||
response = await self.bot.client.send_message(self.peer, message,
|
||||
formatting_entities=entities)
|
||||
space = self.tgid if self.peer_type == "channel" else self.bot.tgid
|
||||
self.dedup.check(response, (event_id, space))
|
||||
|
||||
@@ -231,18 +231,22 @@ class PortalMatrix(BasePortal, ABC):
|
||||
async def _handle_matrix_text(self, sender_id: TelegramID, event_id: EventID,
|
||||
space: TelegramID, client: 'MautrixTelegramClient',
|
||||
content: TextMessageEventContent, reply_to: TelegramID) -> None:
|
||||
if content.formatted_body and content.format == Format.HTML:
|
||||
message, entities = formatter.matrix_to_telegram(content.formatted_body)
|
||||
else:
|
||||
message, entities = formatter.matrix_text_to_telegram(content.body)
|
||||
async with self.send_lock(sender_id):
|
||||
lp = self.get_config("telegram_link_preview")
|
||||
if content.get_edit():
|
||||
orig_msg = DBMessage.get_by_mxid(content.get_edit(), self.mxid, space)
|
||||
if orig_msg:
|
||||
response = await client.edit_message(self.peer, orig_msg.tgid, content,
|
||||
parse_mode=self._matrix_event_to_entities,
|
||||
response = await client.edit_message(self.peer, orig_msg.tgid, message,
|
||||
formatting_entities=entities,
|
||||
link_preview=lp)
|
||||
self._add_telegram_message_to_db(event_id, space, -1, response)
|
||||
return
|
||||
response = await client.send_message(self.peer, content, reply_to=reply_to,
|
||||
parse_mode=self._matrix_event_to_entities,
|
||||
response = await client.send_message(self.peer, message, reply_to=reply_to,
|
||||
formatting_entities=entities,
|
||||
link_preview=lp)
|
||||
self._add_telegram_message_to_db(event_id, space, 0, response)
|
||||
await self._send_delivery_receipt(event_id)
|
||||
@@ -297,7 +301,13 @@ class PortalMatrix(BasePortal, ABC):
|
||||
media = InputMediaUploadedDocument(file=file_handle, attributes=attributes,
|
||||
mime_type=mime or "application/octet-stream")
|
||||
|
||||
caption, entities = self._matrix_event_to_entities(caption) if caption else (None, None)
|
||||
if caption:
|
||||
if caption.formatted_body and caption.format == Format.HTML:
|
||||
caption, entities = formatter.matrix_to_telegram(caption.formatted_body)
|
||||
else:
|
||||
caption, entities = formatter.matrix_text_to_telegram(content.body)
|
||||
else:
|
||||
caption, entities = None, None
|
||||
|
||||
async with self.send_lock(sender_id):
|
||||
if await self._matrix_document_edit(client, content, space, caption, media, event_id):
|
||||
@@ -336,7 +346,7 @@ class PortalMatrix(BasePortal, ABC):
|
||||
except (KeyError, ValueError):
|
||||
self.log.exception("Failed to parse location")
|
||||
return None
|
||||
caption, entities = self._matrix_event_to_entities(content)
|
||||
caption, entities = formatter.matrix_text_to_telegram(content.body)
|
||||
media = MessageMediaGeo(geo=GeoPoint(lat, long, access_hash=0))
|
||||
|
||||
async with self.send_lock(sender_id):
|
||||
@@ -372,7 +382,8 @@ class PortalMatrix(BasePortal, ABC):
|
||||
await self._handle_matrix_message(sender, content, event_id)
|
||||
except RPCError as e:
|
||||
if config["bridge.delivery_error_reports"]:
|
||||
await self._send_bridge_error(f"\u26a0 Your message may not have been bridged: {e}")
|
||||
await self._send_bridge_error(
|
||||
f"\u26a0 Your message may not have been bridged: {e}")
|
||||
raise
|
||||
|
||||
async def _handle_matrix_message(self, sender: 'u.User', content: MessageEventContent,
|
||||
@@ -586,6 +597,7 @@ class PortalMatrix(BasePortal, ABC):
|
||||
self.log.warning(f"Failed to set room name", exc_info=True)
|
||||
return ok
|
||||
|
||||
|
||||
def init(context: Context) -> None:
|
||||
global config
|
||||
config = context.config
|
||||
|
||||
@@ -29,7 +29,7 @@ from telethon.tl.types import (
|
||||
ChatParticipantCreator, ChannelParticipantCreator, UserProfilePhoto, UserProfilePhotoEmpty)
|
||||
|
||||
from mautrix.errors import MForbidden
|
||||
from mautrix.types import (RoomID, UserID, RoomCreatePreset, EventType, Membership, Member,
|
||||
from mautrix.types import (RoomID, UserID, RoomCreatePreset, EventType, Membership,
|
||||
PowerLevelStateEventContent, RoomTopicStateEventContent,
|
||||
RoomNameStateEventContent, RoomAvatarStateEventContent,
|
||||
StateEventContent, EventID)
|
||||
|
||||
@@ -99,8 +99,7 @@ class PortalTelegram(BasePortal, ABC):
|
||||
encrypt=self.encrypted)
|
||||
if not file:
|
||||
return None
|
||||
if self.get_config("inline_images") and (evt.message
|
||||
or evt.fwd_from or evt.reply_to_msg_id):
|
||||
if self.get_config("inline_images") and (evt.message or evt.fwd_from or evt.reply_to):
|
||||
content = await formatter.telegram_to_matrix(
|
||||
evt, source, self.main_intent,
|
||||
prefix_html=f"<img src='{file.mxc}' alt='Inline Telegram photo'/><br/>",
|
||||
@@ -439,12 +438,12 @@ class PortalTelegram(BasePortal, ABC):
|
||||
"max_file_size": min(config["bridge.max_document_size"], 2000) * 1024 * 1024
|
||||
}
|
||||
|
||||
async def backfill(self, source: 'AbstractUser', is_initial: bool = False,
|
||||
async def backfill(self, source: 'u.User', is_initial: bool = False,
|
||||
limit: Optional[int] = None, last_id: Optional[int] = None) -> None:
|
||||
async with self.backfill_method_lock:
|
||||
await self._locked_backfill(source, is_initial, limit, last_id)
|
||||
|
||||
async def _locked_backfill(self, source: 'AbstractUser', is_initial: bool = False,
|
||||
async def _locked_backfill(self, source: 'u.User', is_initial: bool = False,
|
||||
limit: Optional[int] = None, last_id: Optional[int] = None) -> None:
|
||||
limit = limit or (config["bridge.backfill.initial_limit"] if is_initial
|
||||
else config["bridge.backfill.missed_limit"])
|
||||
@@ -481,7 +480,7 @@ class PortalTelegram(BasePortal, ABC):
|
||||
with self.backfill_lock:
|
||||
await self._backfill(source, min_id, limit)
|
||||
|
||||
async def _backfill(self, source: 'AbstractUser', min_id: Optional[int], limit: int) -> None:
|
||||
async def _backfill(self, source: 'u.User', min_id: Optional[int], limit: int) -> None:
|
||||
self.backfill_leave = set()
|
||||
if ((self.peer_type == "user" and self.tgid != source.tgid
|
||||
and config["bridge.backfill.invite_own_puppet"])):
|
||||
@@ -514,7 +513,8 @@ class PortalTelegram(BasePortal, ABC):
|
||||
self.log.debug(f"Iterating all messages starting with {min_id} (approx: {limit})")
|
||||
messages = client.iter_messages(entity, reverse=True, min_id=min_id)
|
||||
async for message in messages:
|
||||
sender = p.Puppet.get(message.from_id) if message.from_id else None
|
||||
sender = (p.Puppet.get(message.from_id.user_id)
|
||||
if isinstance(message.from_id, PeerUser) else None)
|
||||
# TODO handle service messages?
|
||||
await self.handle_telegram_message(source, sender, message)
|
||||
count += 1
|
||||
@@ -522,7 +522,8 @@ class PortalTelegram(BasePortal, ABC):
|
||||
self.log.debug(f"Fetching up to {limit} most recent messages")
|
||||
messages = await client.get_messages(entity, limit=limit)
|
||||
for message in reversed(messages):
|
||||
sender = p.Puppet.get(message.from_id) if message.from_id else None
|
||||
sender = (p.Puppet.get(TelegramID(message.from_id.user_id))
|
||||
if isinstance(message.from_id, PeerUser) else None)
|
||||
await self.handle_telegram_message(source, sender, message)
|
||||
count += 1
|
||||
return count
|
||||
@@ -533,7 +534,7 @@ class PortalTelegram(BasePortal, ABC):
|
||||
self.log.trace("Got telegram message %d, but no room exists, creating...", evt.id)
|
||||
await self.create_matrix_room(source, invites=[source.mxid], update_if_exists=False)
|
||||
|
||||
if (self.peer_type == "user" and sender.tgid == self.tg_receiver
|
||||
if (self.peer_type == "user" and sender and sender.tgid == self.tg_receiver
|
||||
and not sender.is_real_user and not await self.az.state_store.is_joined(self.mxid,
|
||||
sender.mxid)):
|
||||
self.log.debug(f"Ignoring private chat message {evt.id}@{source.tgid} as receiver does"
|
||||
|
||||
+2
-2
@@ -5,6 +5,6 @@ python-magic>=0.4,<0.5
|
||||
commonmark>=0.8,<0.10
|
||||
aiohttp>=3,<3.7
|
||||
yarl<1.6
|
||||
mautrix==0.8.0.beta7
|
||||
telethon>=1.16,<1.17
|
||||
mautrix==0.8.0.beta9
|
||||
telethon>=1.17,<1.18
|
||||
telethon-session-sqlalchemy>=0.2.14,<0.3
|
||||
|
||||
Reference in New Issue
Block a user