diff --git a/mautrix_telegram/__main__.py b/mautrix_telegram/__main__.py
index ffd7e0c7..5d57e338 100644
--- a/mautrix_telegram/__main__.py
+++ b/mautrix_telegram/__main__.py
@@ -14,7 +14,7 @@
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see .
-from typing import Coroutine, List
+from typing import Awaitable, List, Any
import argparse
import asyncio
import logging.config
@@ -88,7 +88,7 @@ if config["appservice.sqlalchemy_core_mode"]:
loop = asyncio.get_event_loop() # type: asyncio.AbstractEventLoop
-state_store = SQLStateStore(db_session)
+state_store = SQLStateStore()
mebibyte = 1024 ** 2
appserv = AppService(config["homeserver.address"], config["homeserver.domain"],
config["appservice.as_token"], config["appservice.hs_token"],
@@ -121,8 +121,7 @@ with appserv.run(config["appservice.hostname"], config["appservice.port"]) as st
init_portal(context)
startup_actions = (init_puppet(context) +
init_user(context) +
- [start,
- context.mx.init_as_bot()]) # type: List[Coroutine]
+ [start, context.mx.init_as_bot()]) # type: List[Awaitable[Any]]
if context.bot:
startup_actions.append(context.bot.start())
diff --git a/mautrix_telegram/abstract_user.py b/mautrix_telegram/abstract_user.py
index c76e166c..11273f86 100644
--- a/mautrix_telegram/abstract_user.py
+++ b/mautrix_telegram/abstract_user.py
@@ -21,14 +21,14 @@ import logging
import platform
from sqlalchemy import orm
-from telethon.tl.types import Channel, ChannelForbidden, Chat, ChatForbidden, Message, \
- MessageActionChannelMigrateFrom, MessageService, PeerUser, TypeUpdate, \
- UpdateChannelPinnedMessage, UpdateChatAdmins, UpdateChatParticipantAdmin, \
- UpdateChatParticipants, UpdateChatUserTyping, UpdateDeleteChannelMessages, \
- UpdateDeleteMessages, UpdateEditChannelMessage, UpdateEditMessage, UpdateNewChannelMessage, \
- UpdateNewMessage, UpdateReadHistoryOutbox, UpdateShortChatMessage, UpdateShortMessage, \
- UpdateUserName, UpdateUserPhoto, UpdateUserStatus, UpdateUserTyping, User, UserStatusOffline, \
- UserStatusOnline
+from telethon.tl.patched import MessageService, Message
+from telethon.tl.types import (
+ Channel, ChannelForbidden, Chat, ChatForbidden, MessageActionChannelMigrateFrom, PeerUser,
+ TypeUpdate, UpdateChannelPinnedMessage, UpdateChatAdmins, UpdateChatParticipantAdmin,
+ UpdateChatParticipants, UpdateChatUserTyping, UpdateDeleteChannelMessages, UpdateDeleteMessages,
+ UpdateEditChannelMessage, UpdateEditMessage, UpdateNewChannelMessage, UpdateNewMessage,
+ UpdateReadHistoryOutbox, UpdateShortChatMessage, UpdateShortMessage, UpdateUserName,
+ UpdateUserPhoto, UpdateUserStatus, UpdateUserTyping, User, UserStatusOffline, UserStatusOnline)
from mautrix_appservice import MatrixRequestError, AppService
from alchemysession import AlchemySessionContainer
@@ -231,7 +231,7 @@ class AbstractUser(ABC):
return
# We check that these are user read receipts, so tg_space is always the user ID.
- message = DBMessage.get_by_tgid(update.max_id, self.tgid)
+ message = DBMessage.get_by_tgid(TelegramID(update.max_id), self.tgid)
if not message:
return
diff --git a/mautrix_telegram/bot.py b/mautrix_telegram/bot.py
index f7d4d263..c0399797 100644
--- a/mautrix_telegram/bot.py
+++ b/mautrix_telegram/bot.py
@@ -18,11 +18,12 @@ from typing import Awaitable, Callable, Dict, List, Optional, Pattern, TYPE_CHEC
import logging
import re
+from telethon.tl.patched import Message, MessageService
from telethon.tl.types import (
ChannelParticipantAdmin, ChannelParticipantCreator, ChatForbidden, ChatParticipantAdmin,
- ChatParticipantCreator, InputChannel, InputUser, Message, MessageActionChatAddUser,
- MessageActionChatDeleteUser, MessageEntityBotCommand, MessageService, PeerChannel, PeerChat,
- TypePeer, UpdateNewChannelMessage, UpdateNewMessage)
+ ChatParticipantCreator, InputChannel, InputUser, MessageActionChatAddUser,
+ MessageActionChatDeleteUser, MessageEntityBotCommand, PeerChannel, PeerChat, TypePeer,
+ UpdateNewChannelMessage, UpdateNewMessage)
from telethon.tl.functions.messages import GetChatsRequest, GetFullChatRequest
from telethon.tl.functions.channels import GetChannelsRequest, GetParticipantRequest
from telethon.errors import ChannelInvalidError, ChannelPrivateError
@@ -30,6 +31,7 @@ from telethon.errors import ChannelInvalidError, ChannelPrivateError
from .types import MatrixUserID
from .abstract_user import AbstractUser
from .db import BotChat
+from .types import TelegramID
from . import puppet as pu, portal as po, user as u
if TYPE_CHECKING:
@@ -115,7 +117,7 @@ class Bot(AbstractUser):
def add_chat(self, chat_id: int, chat_type: str) -> None:
if chat_id not in self.chats:
self.chats[chat_id] = chat_type
- self.db.add(BotChat(id=chat_id, type=chat_type))
+ self.db.add(BotChat(id=TelegramID(chat_id), type=chat_type))
self.db.commit()
def remove_chat(self, chat_id: int) -> None:
@@ -155,7 +157,7 @@ class Bot(AbstractUser):
return False
return True
- async def handle_command_portal(self, portal: po.Portal, reply: ReplyFunc) -> None:
+ async def handle_command_portal(self, portal: po.Portal, reply: ReplyFunc) -> Message:
if not config["bridge.relaybot.authless_portals"]:
return await reply("This bridge doesn't allow portal creation from Telegram.")
@@ -221,7 +223,8 @@ class Bot(AbstractUser):
text = message.message
if self.match_command(text, "id"):
- return await self.handle_command_id(message, reply)
+ await self.handle_command_id(message, reply)
+ return
portal = po.Portal.get_by_entity(message.to_id)
diff --git a/mautrix_telegram/commands/auth.py b/mautrix_telegram/commands/auth.py
index 9f8fe756..d355c746 100644
--- a/mautrix_telegram/commands/auth.py
+++ b/mautrix_telegram/commands/auth.py
@@ -27,7 +27,7 @@ from telethon.tl.functions.account import UpdateUsernameRequest
from . import command_handler, CommandEvent, SECTION_AUTH
from .. import puppet as pu, user as u
-from ..util import format_duration
+from ..util import format_duration, ignore_coro
@command_handler(needs_auth=False,
@@ -153,7 +153,7 @@ async def enter_code_register(evt: CommandEvent) -> Dict:
await evt.sender.ensure_started(even_if_no_session=True)
first_name, last_name = evt.sender.command_status["full_name"]
user = await evt.sender.client.sign_up(evt.args[0], first_name, last_name)
- asyncio.ensure_future(evt.sender.post_login(user), loop=evt.loop)
+ ignore_coro(asyncio.ensure_future(evt.sender.post_login(user), loop=evt.loop))
evt.sender.command_status = None
return await evt.reply(f"Successfully registered to Telegram.")
except PhoneNumberOccupiedError:
@@ -334,7 +334,7 @@ async def _sign_in(evt: CommandEvent, **sign_in_info) -> Dict:
await evt.reply(f"[{existing_user.displayname}]"
f"(https://matrix.to/#/{existing_user.mxid})"
" was logged out from the account.")
- asyncio.ensure_future(evt.sender.post_login(user), loop=evt.loop)
+ ignore_coro(asyncio.ensure_future(evt.sender.post_login(user), loop=evt.loop))
evt.sender.command_status = None
name = f"@{user.username}" if user.username else f"+{user.phone}"
return await evt.reply(f"Successfully logged in as {name}")
diff --git a/mautrix_telegram/commands/handler.py b/mautrix_telegram/commands/handler.py
index fd013c63..3cad49b4 100644
--- a/mautrix_telegram/commands/handler.py
+++ b/mautrix_telegram/commands/handler.py
@@ -126,8 +126,7 @@ class CommandHandler:
(not self.needs_admin or is_admin) and
(not self.needs_auth or is_logged_in))
- async def __call__(self, evt: CommandEvent
- ) -> Dict:
+ async def __call__(self, evt: CommandEvent) -> Dict:
error = await self.get_permission_error(evt)
if error is not None:
return await evt.reply(error)
@@ -154,12 +153,11 @@ def command_handler(_func: Optional[Callable[[CommandEvent], Awaitable[Dict]]] =
help_section: HelpSection = None
) -> Callable[[Callable[[CommandEvent], Awaitable[Optional[Dict]]]],
CommandHandler]:
- input_name = name
def decorator(func: Callable[[CommandEvent], Awaitable[Optional[Dict]]]) -> CommandHandler:
- name = input_name or func.__name__.replace("_", "-")
+ actual_name = name or func.__name__.replace("_", "-")
handler = CommandHandler(func, needs_auth, needs_puppeting, needs_matrix_puppeting,
- needs_admin, management_only, name, help_text, help_args,
+ needs_admin, management_only, actual_name, help_text, help_args,
help_section)
command_handlers[handler.name] = handler
return handler
diff --git a/mautrix_telegram/commands/meta.py b/mautrix_telegram/commands/meta.py
index 5920dbee..cbd8e901 100644
--- a/mautrix_telegram/commands/meta.py
+++ b/mautrix_telegram/commands/meta.py
@@ -51,8 +51,8 @@ async def _get_help_text(evt: CommandEvent) -> str:
help_sections.setdefault(handler.help_section, [])
help_sections[handler.help_section].append(handler.help + " ")
help_sorted = sorted(help_sections.items(), key=lambda item: item[0].order)
- help = ["#### {}\n{}\n".format(key.name, "\n".join(value)) for key, value in help_sorted]
- help_cache[cache_key] = "\n".join(help)
+ helps = ["#### {}\n{}\n".format(key.name, "\n".join(value)) for key, value in help_sorted]
+ help_cache[cache_key] = "\n".join(helps)
return help_cache[cache_key]
diff --git a/mautrix_telegram/commands/portal.py b/mautrix_telegram/commands/portal.py
index 3c4a821a..edd16d18 100644
--- a/mautrix_telegram/commands/portal.py
+++ b/mautrix_telegram/commands/portal.py
@@ -25,6 +25,7 @@ from mautrix_appservice import MatrixRequestError, IntentAPI
from ..types import MatrixRoomID, TelegramID
from ..config import yaml
+from ..util import ignore_coro
from .. import portal as po, user as u, util
from . import (command_handler, CommandEvent,
SECTION_ADMIN, SECTION_CREATING_PORTALS, SECTION_PORTAL_MANAGEMENT)
@@ -271,7 +272,7 @@ async def confirm_bridge(evt: CommandEvent) -> Optional[Dict]:
if not ok:
return None
elif coro:
- asyncio.ensure_future(coro, loop=evt.loop)
+ ignore_coro(asyncio.ensure_future(coro, loop=evt.loop))
await evt.reply("Cleaning up previous portal room...")
elif portal.mxid:
evt.sender.command_status = None
@@ -308,8 +309,9 @@ async def confirm_bridge(evt: CommandEvent) -> Optional[Dict]:
portal.photo_id = ""
portal.save()
- asyncio.ensure_future(portal.update_matrix_room(user, entity, direct, levels=levels),
- loop=evt.loop)
+ ignore_coro(asyncio.ensure_future(portal.update_matrix_room(user, entity, direct,
+ levels=levels),
+ loop=evt.loop))
return await evt.reply("Bridging complete. Portal synchronization should begin momentarily.")
diff --git a/mautrix_telegram/commands/telegram.py b/mautrix_telegram/commands/telegram.py
index b5e9a6a6..00c5f3f0 100644
--- a/mautrix_telegram/commands/telegram.py
+++ b/mautrix_telegram/commands/telegram.py
@@ -21,7 +21,7 @@ import re
from telethon.errors import (InviteHashInvalidError, InviteHashExpiredError,
UserAlreadyParticipantError)
-from telethon.tl.types import User as TLUser, TypeUpdates, MessageMediaGame, PeerChat
+from telethon.tl.types import User as TLUser, TypeUpdates, MessageMediaGame
from telethon.tl.types.messages import BotCallbackAnswer
from telethon.tl.functions.messages import (ImportChatInviteRequest, CheckChatInviteRequest,
GetBotCallbackAnswerRequest)
diff --git a/mautrix_telegram/matrix.py b/mautrix_telegram/matrix.py
index 3c6b1997..e91726dd 100644
--- a/mautrix_telegram/matrix.py
+++ b/mautrix_telegram/matrix.py
@@ -296,7 +296,7 @@ class MatrixHandler:
events = new_events - old_events
if len(events) > 0:
# New event pinned, set that as pinned in Telegram.
- await portal.handle_matrix_pin(sender, events.pop())
+ await portal.handle_matrix_pin(sender, MatrixEventID(events.pop()))
elif len(new_events) == 0:
# All pinned events removed, remove pinned event in Telegram.
await portal.handle_matrix_pin(sender, None)
diff --git a/mautrix_telegram/portal.py b/mautrix_telegram/portal.py
index ea41f5c8..05bc41e8 100644
--- a/mautrix_telegram/portal.py
+++ b/mautrix_telegram/portal.py
@@ -32,8 +32,7 @@ import re
import magic
from sqlalchemy import orm
-from sqlalchemy.exc import IntegrityError, InvalidRequestError
-from sqlalchemy.orm.exc import FlushError
+from sqlalchemy.exc import IntegrityError
from telethon.tl.functions.messages import (
AddChatUserRequest, CreateChatRequest, DeleteChatUserRequest, EditChatAdminRequest,
@@ -46,28 +45,30 @@ from telethon.tl.functions.channels import (
from telethon.tl.functions.messages import ReadHistoryRequest as ReadMessageHistoryRequest
from telethon.tl.functions.channels import ReadHistoryRequest as ReadChannelHistoryRequest
from telethon.errors import ChatAdminRequiredError, ChatNotModifiedError
+from telethon.tl.patched import Message, MessageService
from telethon.tl.types import (
Channel, ChannelAdminRights, ChannelBannedRights, ChannelFull, ChannelParticipantAdmin,
ChannelParticipantCreator, ChannelParticipantsRecent, ChannelParticipantsSearch, Chat,
ChatFull, ChatInviteEmpty, ChatParticipantAdmin, ChatParticipantCreator, ChatPhoto,
DocumentAttributeFilename, DocumentAttributeImageSize, DocumentAttributeSticker,
DocumentAttributeVideo, FileLocation, GeoPoint, InputChannel, InputChatUploadedPhoto,
- InputPeerChannel, InputPeerChat, InputPeerUser, InputUser, InputUserSelf, Message,
+ InputPeerChannel, InputPeerChat, InputPeerUser, InputUser, InputUserSelf,
MessageActionChannelCreate, MessageActionChatAddUser, MessageActionChatCreate,
MessageActionChatDeletePhoto, MessageActionChatDeleteUser, MessageActionChatEditPhoto,
MessageActionChatEditTitle, MessageActionChatJoinedByLink, MessageActionChatMigrateTo,
- MessageActionPinMessage, MessageMediaContact, MessageMediaDocument, MessageMediaGeo,
- MessageMediaPhoto, MessageMediaUnsupported, MessageMediaGame, MessageService, PeerChannel,
+ MessageActionPinMessage, MessageActionGameScore, MessageMediaContact, MessageMediaDocument,
+ MessageMediaGeo, MessageMediaPhoto, MessageMediaUnsupported, MessageMediaGame, PeerChannel,
PeerChat, PeerUser, Photo, PhotoCachedSize, SendMessageCancelAction, SendMessageTypingAction,
TypeChannelParticipant, TypeChat, TypeChatParticipant, TypeDocumentAttribute, TypeInputPeer,
TypeMessageAction, TypeMessageEntity, TypePeer, TypePhotoSize, TypeUpdates, TypeUser,
TypeUserFull, UpdateChatUserTyping, UpdateNewChannelMessage, UpdateNewMessage, UpdateUserTyping,
- User, UserFull, MessageEntityCode)
+ User, UserFull, MessageEntityPre)
from mautrix_appservice import MatrixRequestError, IntentError, AppService, IntentAPI
from .types import MatrixEventID, MatrixRoomID, MatrixUserID, TelegramID
from .context import Context
from .db import Portal as DBPortal, Message as DBMessage, TelegramFile as DBTelegramFile
+from .util import ignore_coro
from . import puppet as p, user as u, formatter, util
if TYPE_CHECKING:
@@ -76,6 +77,7 @@ if TYPE_CHECKING:
from .config import Config
from .tgclient import MautrixTelegramClient
+
mimetypes.init()
config = None # type: Config
@@ -338,7 +340,7 @@ class Portal:
if synchronous:
await update
else:
- asyncio.ensure_future(update, loop=self.loop)
+ ignore_coro(asyncio.ensure_future(update, loop=self.loop))
await self.invite_to_matrix(invites or [])
return self.mxid
async with self._room_create_lock:
@@ -405,10 +407,10 @@ class Portal:
self.save()
self.az.state_store.set_power_levels(self.mxid, power_levels)
user.register_portal(self)
- asyncio.ensure_future(self.update_matrix_room(user, entity, direct, puppet,
- levels=power_levels, users=users,
- participants=participants),
- loop=self.loop)
+ ignore_coro(asyncio.ensure_future(self.update_matrix_room(user, entity, direct, puppet,
+ levels=power_levels, users=users,
+ participants=participants),
+ loop=self.loop))
return self.mxid
@@ -631,7 +633,8 @@ class Portal:
entity, ChannelParticipantsRecent(), offset=0, limit=limit, hash=0))
return response.users, response.participants
elif limit > 200 or limit == -1:
- users, participants = [], [] # type: Tuple[List[TypeUser], List[TypeParticipant]]
+ users = [] # type: List[TypeUser]
+ participants = [] # type: List[TypeParticipant]
offset = 0
remaining_quota = limit if limit > 0 else 1000000
query = (ChannelParticipantsSearch("") if limit == -1
@@ -886,8 +889,8 @@ class Portal:
await self._apply_msg_format(sender, msgtype, message)
@staticmethod
- def _matrix_event_to_entities(event: Dict[str, Any]) -> Tuple[
- str, Optional[List[TypeMessageEntity]]]:
+ def _matrix_event_to_entities(event: Dict[str, Any]
+ ) -> Tuple[str, Optional[List[TypeMessageEntity]]]:
try:
if event.get("format", None) == "org.matrix.custom.html":
message, entities = formatter.matrix_to_telegram(event.get("formatted_body", ""))
@@ -983,7 +986,7 @@ class Portal:
self.log.debug("Handled Matrix message: %s", response)
self.is_duplicate(response, (event_id, space))
DBMessage(
- tgid=response.id,
+ tgid=TelegramID(response.id),
tg_space=space,
mx_room=self.mxid,
mxid=event_id).insert()
@@ -1415,7 +1418,7 @@ class Portal:
external_url=self.get_external_url(evt))
async def handle_telegram_unsupported(self, source: 'AbstractUser', intent: IntentAPI,
- evt: Message, relates_to: dict = None) -> dict:
+ evt: Message, _: dict = None) -> dict:
override_text = ("This message is not supported on your version of Mautrix-Telegram. "
"Please check https://github.com/tulir/mautrix-telegram or ask your "
"bridge administrator about possible updates.")
@@ -1433,11 +1436,11 @@ class Portal:
@staticmethod
def _int_to_bytes(i: int) -> bytes:
- hex = "{0:010x}".format(i)
- return codecs.decode(hex, "hex_codec")
+ hex_value = "{0:010x}".format(i)
+ return codecs.decode(hex_value, "hex_codec")
async def handle_telegram_game(self, source: 'AbstractUser', intent: IntentAPI,
- evt: Message, relates_to: dict = None):
+ evt: Message, _: dict = None):
game = evt.media.game
if self.peer_type == "channel":
play_id = base64.b64encode(b"c"
@@ -1457,7 +1460,7 @@ class Portal:
play_id = play_id.decode("utf-8").rstrip("=")
command = f"!tg play {play_id}"
override_text = f"Run {command} in your bridge management room to play {game.title}"
- override_entities = [MessageEntityCode(offset=len("Run "), length=len(command))]
+ override_entities = [MessageEntityPre(offset=len("Run "), length=len(command), language="")]
text, html, relates_to = await formatter.telegram_to_matrix(
evt, source, self.main_intent,
override_text=override_text, override_entities=override_entities)
@@ -1478,6 +1481,9 @@ class Portal:
elif not self.get_config("edits_as_replies"):
self.log.debug("Edits as replies disabled, ignoring edit event...")
return
+ elif hasattr(evt, "media") and isinstance(evt.media, (MessageMediaGame,)):
+ self.log.debug("Ignoring game message edit event")
+ return
lock = self.optional_send_lock(sender.tgid if sender else None)
if lock:
@@ -1492,7 +1498,7 @@ class Portal:
if duplicate_found:
mxid, other_tg_space = duplicate_found
if tg_space != other_tg_space:
- DBMessage.update_by_tgid(evt.id, tg_space,
+ DBMessage.update_by_tgid(TelegramID(evt.id), tg_space,
mxid=mxid,
mx_room=self.mxid)
return
@@ -1507,7 +1513,7 @@ class Portal:
mxid = response["event_id"]
- msg = DBMessage.get_by_tgid(evt.id, tg_space)
+ msg = DBMessage.get_by_tgid(TelegramID(evt.id), tg_space)
if not msg:
self.log.info(f"Didn't find edited message {evt.id}@{tg_space} (src {source.tgid}) "
"in database.")
@@ -1536,11 +1542,12 @@ class Portal:
self.log.debug(f"Ignoring message {evt.id}@{tg_space} (src {source.tgid}) "
f"as it was already handled (in space {other_tg_space})")
if tg_space != other_tg_space:
- DBMessage(tgid=evt.id, mx_room=self.mxid, mxid=mxid, tg_space=tg_space).insert()
+ DBMessage(tgid=TelegramID(evt.id), mx_room=self.mxid, mxid=mxid,
+ tg_space=tg_space).insert()
return
if self.dedup_pre_db_check and self.peer_type == "channel":
- msg = DBMessage.get_by_tgid(evt.id, tg_space)
+ msg = DBMessage.get_by_tgid(TelegramID(evt.id), tg_space)
if msg:
self.log.debug(f"Ignoring message {evt.id} (src {source.tgid}) as it was already"
f"handled into {msg.mxid}. This duplicate was catched in the db "
@@ -1593,21 +1600,15 @@ class Portal:
self.log.debug("Handled Telegram message: %s", evt)
try:
- DBMessage(tgid=evt.id, mx_room=self.mxid, mxid=mxid, tg_space=tg_space).insert()
+ DBMessage(tgid=TelegramID(evt.id), mx_room=self.mxid, mxid=mxid,
+ tg_space=tg_space).insert()
DBMessage.update_by_mxid(temporary_identifier, self.mxid, mxid=mxid)
- except FlushError as e:
+ except IntegrityError as e:
self.log.exception(f"{e.__class__.__name__} while saving message mapping. "
"This might mean that an update was handled after it left the "
"dedup cache queue. You can try enabling bridge.deduplication."
"pre_db_check in the config.")
await intent.redact(self.mxid, mxid)
- except (IntegrityError, InvalidRequestError) as e:
- self.log.exception(f"{e.__class__.__name__} while saving message mapping. "
- "This might mean that an update was handled after it left the "
- "dedup cache queue. You can try enabling bridge.deduplication."
- "pre_db_check in the config.")
- self.db.rollback()
- await intent.redact(self.mxid, mxid)
async def _create_room_on_action(self, source: 'AbstractUser',
action: TypeMessageAction) -> bool:
@@ -1650,6 +1651,9 @@ class Portal:
await sender.intent.send_emote(self.mxid, "upgraded this group to a supergroup.")
elif isinstance(action, MessageActionPinMessage):
await self.receive_telegram_pin_sender(sender)
+ elif isinstance(action, MessageActionGameScore):
+ # TODO handle game score
+ pass
else:
self.log.debug("Unhandled Telegram action in %s: %s", self.title, action)
diff --git a/mautrix_telegram/puppet.py b/mautrix_telegram/puppet.py
index 6708eaa9..4f9070ba 100644
--- a/mautrix_telegram/puppet.py
+++ b/mautrix_telegram/puppet.py
@@ -29,13 +29,13 @@ from mautrix_appservice import AppService, IntentAPI, IntentError, MatrixRequest
from .types import MatrixUserID, TelegramID
from .db import Puppet as DBPuppet
+from .util import ignore_coro
from . import util
if TYPE_CHECKING:
from .matrix import MatrixHandler
from .config import Config
from .context import Context
- from . import user as u
from .abstract_user import AbstractUser
PuppetError = Enum('PuppetError', 'Success OnlyLoginSelf InvalidAccessToken')
@@ -153,7 +153,7 @@ class Puppet:
return PuppetError.OnlyLoginSelf
return PuppetError.InvalidAccessToken
if config["bridge.sync_with_custom_puppets"]:
- asyncio.ensure_future(self.sync(), loop=self.loop)
+ ignore_coro(asyncio.ensure_future(self.sync(), loop=self.loop))
return PuppetError.Success
async def leave_rooms_with_default_user(self) -> None:
diff --git a/mautrix_telegram/sqlstatestore.py b/mautrix_telegram/sqlstatestore.py
index f5ced3bd..a4f67ee1 100644
--- a/mautrix_telegram/sqlstatestore.py
+++ b/mautrix_telegram/sqlstatestore.py
@@ -16,8 +16,6 @@
# along with this program. If not, see .
from typing import Dict, Tuple
-from sqlalchemy import orm
-
from mautrix_appservice import StateStore
from .types import MatrixUserID, MatrixRoomID
@@ -26,9 +24,8 @@ from .db import RoomState, UserProfile
class SQLStateStore(StateStore):
- def __init__(self, db: orm.Session) -> None:
+ def __init__(self) -> None:
super().__init__()
- self.db = db # type: orm.Session
self.profile_cache = {} # type: Dict[Tuple[str, str], UserProfile]
self.room_state_cache = {} # type: Dict[str, RoomState]
diff --git a/mautrix_telegram/tgclient.py b/mautrix_telegram/tgclient.py
index 769d431c..ba86b070 100644
--- a/mautrix_telegram/tgclient.py
+++ b/mautrix_telegram/tgclient.py
@@ -21,7 +21,7 @@ from telethon.tl.functions.messages import SendMediaRequest
from telethon.tl.types import (
InputMediaUploadedDocument, InputMediaUploadedPhoto, TypeDocumentAttribute, TypeInputMedia,
TypeInputPeer, TypeMessageEntity, TypeMessageMedia, TypePeer)
-from telethon.tl import custom
+from telethon.tl.patched import Message
class MautrixTelegramClient(TelegramClient):
@@ -45,7 +45,7 @@ class MautrixTelegramClient(TelegramClient):
async def send_media(self, entity: Union[TypeInputPeer, TypePeer],
media: Union[TypeInputMedia, TypeMessageMedia],
caption: str = None, entities: List[TypeMessageEntity] = None,
- reply_to: int = None) -> Optional[custom.Message]:
+ reply_to: int = None) -> Optional[Message]:
entity = await self.get_input_entity(entity)
reply_to = utils.get_message_id(reply_to)
request = SendMediaRequest(entity, media, message=caption or "", entities=entities or [],
diff --git a/mautrix_telegram/user.py b/mautrix_telegram/user.py
index 38e48cb2..55929475 100644
--- a/mautrix_telegram/user.py
+++ b/mautrix_telegram/user.py
@@ -21,8 +21,7 @@ import re
from telethon.tl.types import (
TypeUpdate, UpdateNewMessage, UpdateNewChannelMessage, PeerUser,
- UpdateShortChatMessage, UpdateShortMessage)
-from telethon.tl.types import User as TLUser
+ UpdateShortChatMessage, UpdateShortMessage, User as TLUser)
from telethon.tl.types.contacts import ContactsNotModified
from telethon.tl.functions.contacts import GetContactsRequest, SearchRequest
from telethon.tl.functions.account import UpdateStatusRequest
diff --git a/mautrix_telegram/util/__init__.py b/mautrix_telegram/util/__init__.py
index 7071b2d6..14e5b29d 100644
--- a/mautrix_telegram/util/__init__.py
+++ b/mautrix_telegram/util/__init__.py
@@ -2,3 +2,7 @@ from .file_transfer import transfer_file_to_matrix, convert_image
from .format_duration import format_duration
from .signed_token import sign_token, verify_token
from .recursive_dict import recursive_del, recursive_set, recursive_get
+
+
+def ignore_coro(coro):
+ pass
diff --git a/mautrix_telegram/util/file_transfer.py b/mautrix_telegram/util/file_transfer.py
index 415a3309..4a2263b5 100644
--- a/mautrix_telegram/util/file_transfer.py
+++ b/mautrix_telegram/util/file_transfer.py
@@ -21,7 +21,6 @@ import logging
import asyncio
import magic
-from sqlalchemy import orm
from sqlalchemy.exc import IntegrityError, InvalidRequestError
from telethon.tl.types import (Document, FileLocation, InputFileLocation,
diff --git a/mautrix_telegram/web/common/auth_api.py b/mautrix_telegram/web/common/auth_api.py
index a91ea682..803df2e7 100644
--- a/mautrix_telegram/web/common/auth_api.py
+++ b/mautrix_telegram/web/common/auth_api.py
@@ -25,7 +25,7 @@ import logging
from telethon.errors import *
from ...commands.auth import enter_password
-from ...util import format_duration
+from ...util import format_duration, ignore_coro
from ...puppet import Puppet, PuppetError
from ...user import User
@@ -112,7 +112,7 @@ class AuthAPI(abc.ABC):
existing_user = User.get_by_tgid(user_info.id)
if existing_user and existing_user != user:
await existing_user.log_out()
- asyncio.ensure_future(user.post_login(user_info), loop=self.loop)
+ ignore_coro(asyncio.ensure_future(user.post_login(user_info), loop=self.loop))
if user.command_status and user.command_status["action"] == "Login":
user.command_status = None
diff --git a/mautrix_telegram/web/provisioning/__init__.py b/mautrix_telegram/web/provisioning/__init__.py
index 34804c48..eec0b3c4 100644
--- a/mautrix_telegram/web/provisioning/__init__.py
+++ b/mautrix_telegram/web/provisioning/__init__.py
@@ -27,6 +27,7 @@ from mautrix_appservice import AppService, MatrixRequestError, IntentError
from ...types import MatrixUserID, TelegramID
from ...user import User
from ...portal import Portal
+from ...util import ignore_coro
from ...commands.portal import user_has_power_level, get_initial_state
from ..common import AuthAPI
@@ -190,8 +191,9 @@ class ProvisioningAPI(AuthAPI):
portal.photo_id = ""
portal.save()
- asyncio.ensure_future(portal.update_matrix_room(user, entity, direct, levels=levels),
- loop=self.loop)
+ ignore_coro(asyncio.ensure_future(portal.update_matrix_room(user, entity, direct,
+ levels=levels),
+ loop=self.loop))
return web.Response(status=202, body="{}")
@@ -285,7 +287,7 @@ class ProvisioningAPI(AuthAPI):
self.log.exception("Failed to disconnect chat")
return self.get_error_response(500, "exception", "Failed to disconnect chat")
else:
- asyncio.ensure_future(coro, loop=self.loop)
+ ignore_coro(asyncio.ensure_future(coro, loop=self.loop))
return web.json_response({}, status=200 if sync else 202)
async def get_user_info(self, request: web.Request) -> web.Response: