def __init__(self, bot_mxid: UserID, login_shared_secret: str, homeserver_address: str, user_id_prefix: str, user_id_suffix: str, device_name: str, loop: Optional[asyncio.AbstractEventLoop] = None) -> None: self.loop = loop or asyncio.get_event_loop() self.bot_mxid = bot_mxid self.device_name = device_name self._id_prefix = user_id_prefix self._id_suffix = user_id_suffix self.login_shared_secret = login_shared_secret.encode("utf-8") config = AsyncClientConfig(store=NioStore, encryption_enabled=True, pickle_key="mautrix-python", store_sync_tokens=True) device_id = DBAccount.first_device_id(self.bot_mxid) if device_id: self.log.debug(f"Found device ID in database: {device_id}") self.client = AsyncClient(homeserver=homeserver_address, user=bot_mxid, device_id=device_id, config=config, store_path="3:<")
def __init__(self, loglevel=None): config = ClientConfig(encryption_enabled=True, pickle_key=cfg.pickle_key, store_name=cfg.store_name, store_sync_tokens=True) if not os.path.exists(cfg.store_path): os.makedirs(cfg.store_path) self.http_session = aiohttp.ClientSession( headers={'User-Agent': self.user_agent}) self.client = AsyncClient( cfg.server, cfg.user, cfg.device_id, config=config, store_path=cfg.store_path ) logger_group.level = getattr( logbook, loglevel) if loglevel else logbook.CRITICAL logbook.StreamHandler(sys.stdout).push_application() self.logger = logbook.Logger('bot') logger_group.add_logger(self.logger) self.mli = MessageLinksInfo(self.http_session) self._register_commands() self.client.add_response_callback(self._sync_cb, SyncResponse) self.client.add_response_callback( self._key_query_cb, KeysQueryResponse) self.client.add_event_callback(self._invite_cb, InviteMemberEvent)
async def _login_first_time(self) -> None: homeserver = os.environ['MATRIX_SERVER'] user_id = os.environ['MATRIX_USERID'] pw = os.environ['MATRIX_PASSWORD'] device_name = os.environ['MATRIX_DEVICE'] if not os.path.exists(self.STORE_PATH): os.makedirs(self.STORE_PATH) self.client = AsyncClient( homeserver, user_id, store_path=self.STORE_PATH, config=self.client_config, ssl=(os.environ['MATRIX_SSLVERIFY'] == 'True'), ) resp = await self.client.login(password=pw, device_name=device_name) if (isinstance(resp, LoginResponse)): self._write_details_to_disk(resp, homeserver) else: logging.info( f"homeserver = \"{homeserver}\"; user = \"{user_id}\"") logging.critical(f"Failed to log in: {resp}") sys.exit(1)
def init(self): self.matrix_user = os.getenv('MATRIX_USER') matrix_server = os.getenv('MATRIX_SERVER') bot_owners = os.getenv('BOT_OWNERS') access_token = os.getenv('MATRIX_ACCESS_TOKEN') join_on_invite = os.getenv('JOIN_ON_INVITE') owners_only = os.getenv('OWNERS_ONLY') is not None leave_empty_rooms = os.getenv('LEAVE_EMPTY_ROOMS') if matrix_server and self.matrix_user and bot_owners and access_token: self.client = AsyncClient(matrix_server, self.matrix_user, ssl=matrix_server.startswith("https://")) self.client.access_token = access_token self.join_on_invite = (join_on_invite or '').lower() == 'true' self.leave_empty_rooms = (leave_empty_rooms or 'true').lower() == 'true' self.owners = bot_owners.split(',') self.owners_only = owners_only self.get_modules() else: self.logger.error( "The environment variables MATRIX_SERVER, MATRIX_USER, MATRIX_ACCESS_TOKEN and BOT_OWNERS are mandatory" ) sys.exit(1)
async def create_client() -> AsyncClient: homeserver = ARGS.server user_id = ARGS.user password = ARGS.userpass if not ARGS.batch: homeserver = input( f"Enter URL of your homeserver: [{homeserver}] ") or homeserver user_id = input(f"Enter your full user ID: [{user_id}] ") or user_id password = getpass.getpass() client = AsyncClient( homeserver=homeserver, user=user_id, config=AsyncClientConfig(store=store.SqliteMemoryStore), ) await client.login(password, DEVICE_NAME) client.load_store() room_keys_path = ARGS.keys room_keys_password = ARGS.keyspass if not ARGS.batch: room_keys_path = input( f"Enter full path to room E2E keys: [{room_keys_path}] " ) or room_keys_path room_keys_password = getpass.getpass("Room keys password: "******"Importing keys. This may take a while...") await client.import_keys(room_keys_path, room_keys_password) return client
async def main() -> None: # Otherwise the config file exists, so we'll use the stored credentials # open the file in read-only mode client = AsyncClient("***HOMESERVER***", "***MATRIX_USER***") #NOTE client.access_token = "***ACCESS_TOKEN***" #NOTE #client.user_id = config['user_id'] #client.device_id = config['device_id'] # Now we can send messages as the user room_id = "***ROOM_ID***" #NOTE #room_id = input(f"Enter room id for image message: [{room_id}] ") #image = "exampledir/samplephoto.jpg" #image = input(f"Enter file name of image to send: [{image}] ") #await send_image(client, room_id, image) await client.room_send(room_id=room_id, message_type="m.room.message", content={ "msgtype": "m.text", "body": "Moi" }) client.login() print("Logged in using stored credentials. Sent a test message.") # Close the client connection after we are done with it. await client.close()
async def async_client_pair(tempdir, loop): ALICE_ID = "@alice:example.org" ALICE_DEVICE = "JLAFKJWSCS" BOB_ID = "@bob:example.org" BOB_DEVICE = "ASDFOEAK" config = AsyncClientConfig(max_timeouts=3) alice = AsyncClient( "https://example.org", ALICE_ID, ALICE_DEVICE, tempdir, config=config, ) bob = AsyncClient( "https://example.org", BOB_ID, BOB_DEVICE, tempdir, config=config, ) await alice.receive_response( LoginResponse(ALICE_ID, ALICE_DEVICE, "alice_1234")) await bob.receive_response(LoginResponse(BOB_ID, BOB_DEVICE, "bob_1234")) yield (alice, bob) await alice.close() await bob.close()
class MatrixClient: def __init__(self, bot_funcs): self.bot_funcs = bot_funcs self.client = AsyncClient(URI, USERNAME) self.last_sent = 0 print("init finished") async def message_callback(self, room: MatrixRoom, event: RoomMessageText): for f in self.bot_funcs: if event.body.startswith(f["trigger"]): ts = time.time() if ts - self.last_sent < 2: continue self.last_sent = time.time() res = f["ret_func"](event.body, event.sender) if res is None: continue await self.client.room_send(room_id=ROOM, message_type="m.room.message", content={ "msgtype": "m.text", "body": res }) async def exec_client(self): self.client.add_event_callback(self.message_callback, RoomMessageText) print(await self.client.login(PW)) await self.client.sync_forever(timeout=30000) # milliseconds
def init(self): self.matrix_user = os.getenv('MATRIX_USER') self.matrix_pass = os.getenv('MATRIX_PASSWORD') matrix_server = os.getenv('MATRIX_SERVER') bot_owners = os.getenv('BOT_OWNERS') access_token = os.getenv('MATRIX_ACCESS_TOKEN') join_on_invite = os.getenv('JOIN_ON_INVITE') if matrix_server and self.matrix_user and bot_owners: self.client = AsyncClient(matrix_server, self.matrix_user) self.client.access_token = access_token if self.client.access_token is None: if self.matrix_pass is None: self.logger.error("Either MATRIX_ACCESS_TOKEN or MATRIX_PASSWORD need to be set") sys.exit(1) self.join_on_invite = join_on_invite is not None self.owners = bot_owners.split(',') self.get_modules() else: self.logger.error("The environment variables MATRIX_SERVER, MATRIX_USER and BOT_OWNERS are mandatory") sys.exit(1)
async def run(self) -> None: client_config = AsyncClientConfig(store_sync_tokens=True, encryption_enabled=True) self.client = AsyncClient(config.matrix_homeserver, store_path="./store", config=client_config) self.client.restore_login( user_id=config.matrix_user_id, device_id=config.matrix_device_id, access_token=config.matrix_access_token, ) if self.client.should_upload_keys: await self.client.keys_upload() if self.client.should_query_keys: await self.client.keys_query() if self.client.should_claim_keys: await self.client.keys_claim() await self.client.sync(full_state=True) self.client.add_event_callback(self.on_message, RoomMessageText) self.client.add_event_callback(self.on_invite, InviteMemberEvent) await self.client.sync_forever(timeout=30000) await self.client.close()
def init(self): self.client = AsyncClient(os.environ['MATRIX_SERVER'], os.environ['MATRIX_USER']) self.client.access_token = os.getenv('MATRIX_ACCESS_TOKEN') self.join_on_invite = os.getenv('JOIN_ON_INVITE') self.get_modules()
class Bot: def __init__(self): self.client = AsyncClient(settings.MATRIX_SERVER, settings.MATRIX_USERNAME) self.command_handlers = { "cbstart": self.start, "cbstats": self.cbstats, } self.client.add_event_callback(self.message_handler, RoomMessageText) self.client.add_event_callback(self.invite_handler, InviteEvent) async def run(self): await self.client.login(settings.MATRIX_PASSWORD) await self.client.sync_forever(timeout=30000) async def invite_handler(self, room: MatrixRoom, event: InviteEvent): await self.client.join(room.room_id) async def message_handler(self, room, event: RoomMessageText): # Set up command handlers args = event.body.split(" ") if len(args) > 0 and args[0].startswith("!"): command = args[0][1:] if command in self.command_handlers: await self.command_handlers[command](room, event) async def send_message(self, room, message): await self.client.room_send( room_id=room.room_id, message_type="m.room.message", content={ "msgtype": "m.text", "format": "org.matrix.custom.html", "body": message, "formatted_body": message, }, ) async def start(self, room, _): await self.send_message(room, "Running") async def cbstats(self, room, event): args = event.body.split(" ")[1:] message = "" country_info = None try: if len(args) == 0: stats, updated = data.get_global_cases() else: country = " ".join(args) stats, country_info, updated = data.get_country_cases(country) last_updated = datetime.fromtimestamp(int(updated) / 1000) message = formatting.format_stats(stats, country_info, last_updated) except JSONDecodeError: if country is not None: message = f"{country} doesn't exist lmao" else: message = "Error: Could not look up stats" await self.send_message(room, message)
async def init(homeserver: str, username: str, password: str, keyfile: Optional[str], keyphrase: Optional[str]) -> AsyncClient: config = AsyncClientConfig(store=SqliteMemoryStore, store_sync_tokens=True) client = AsyncClient(homeserver, username, config=config) response = await client.login(password) client.add_event_callback(event_cb, RoomMessage) await client.import_keys(keyfile, keyphrase) return client
def __init__(self): self.client = AsyncClient(settings.MATRIX_SERVER, settings.MATRIX_USERNAME) self.command_handlers = { "cbstart": self.start, "cbstats": self.cbstats, } self.client.add_event_callback(self.message_handler, RoomMessageText) self.client.add_event_callback(self.invite_handler, InviteEvent)
async def main() -> None: client = AsyncClient("https://matrix.ether.ai", os.environ['BOT_USER']) client.add_event_callback(message_callback, RoomMessageText) print(await client.login(os.environ['BOT_PASSWORD'])) # "Logged in as @alice:example.org device id: RANDOMDID" # If you made a new room and haven't joined as that user, you can use # await client.join("your-room-id") file_path = 'logs/myLinks.log' # Referenced from stack overflow https://stackoverflow.com/a/24818607 last_line = None with open(file_path, 'r') as f: while True: line = f.readline() if not line: break last_line = line while True: with open(file_path, 'r') as f: lines = f.readlines() if lines[-1] != last_line: last_line = lines[-1] await client.room_send( # Watch out! If you join an old room you'll see lots of old messages room_id="!nXDYFQhwioFnAwUHiB:ether.ai", message_type="m.room.message", content={ "msgtype": "m.text", "body": lines[-1] } ) time.sleep(0.00000000000001) # while True: # line = file1.readline() # # if not line: # await client.sync_forever(timeout=1000) # milliseconds # # else: # await client.room_send( # # Watch out! If you join an old room you'll see lots of old messages # room_id="!nXDYFQhwioFnAwUHiB:ether.ai", # message_type="m.room.message", # content={ # "msgtype": "m.text", # "body": line # } # ) await client.sync_forever(timeout=30000) # milliseconds
async def main(client: nio.AsyncClient): # Set up event callbacks callbacks = Callbacks(client) client.add_to_device_callback(callbacks.to_device_callback, (nio.KeyVerificationEvent, )) # Sync encryption keys with the server # Required for participating in encrypted rooms if client.should_upload_keys: await client.keys_upload() print("This program is ready and waiting for the other party to initiate " 'an emoji verification with us by selecting "Verify by Emoji" ' "in their Matrix client.") await client.sync_forever(timeout=30000, full_state=True)
async def post_picture_to_room(matrix_config: MatrixConfig, image: Image) -> None: client = AsyncClient(matrix_config.homeserver_url) client.access_token = matrix_config.access_token client.user_id = matrix_config.mxid client.device_id = matrix_config.device_id room_id = matrix_config.target_room f = io.BytesIO() image.save(f, format="JPEG", optimize=True, progressive=True) # Get the (post-resize) file size f.seek(0, io.SEEK_END) image_file_size = f.tell() print(f"Image resized down to {image_file_size} bytes") f.seek(0) # rewind to the start # First upload the image and get an MXC URI in response resp, _maybe_keys = await client.upload( lambda _got_429, _got_timeouts: f, # No need to really use aiofiles when we have a BytesIO content_type="image/jpeg", filesize=image_file_size) if not isinstance(resp, UploadResponse): raise RuntimeError(f"Failed to send image: {resp}") # Then send a (image) message to the room pointing to the uploaded image's MXC URI. today_str = str(datetime.date.today()) content = { "body": f"Image of the day {today_str}", "info": { "size": image_file_size, "mimetype": "image/jpeg", "w": image.width, "h": image.height, "thumbnail_info": None, "thumbnail_url": None, }, "msgtype": "m.image", "url": resp.content_uri, } await client.room_send(room_id, message_type="m.room.message", content=content) f.close() await client.close()
def __init__(self, bot: Bot, home_server: str, username: str, access_token: str, device_id: str, store_filepath: str, web_dir: str, public_url: str, display_name: str, avatar_path: str, debug: bool = False): if not os.path.exists(store_filepath): os.makedirs(store_filepath) self.debug = debug self.public_url = public_url self.web_dir = web_dir self.display_name = display_name self.avatar_path = avatar_path self.username = username self.identifier = f"@{username}:{home_server[home_server.find('//') + 2:]}" self.matrix = AsyncClient(home_server, self.identifier, device_id, store_path=store_filepath, config=AsyncClientConfig( encryption_enabled=True, store=SqliteStore, store_name="matrix.db", store_sync_tokens=True)) self.matrix.access_token = access_token self.matrix.user_id = self.identifier self.matrix.add_event_callback(self.handle_message, RoomMessageText) self.matrix.add_event_callback(self.crypto_event, MegolmEvent) self.matrix.add_event_callback(self.invite_event, InviteMemberEvent) self.matrix.add_event_callback(self.room_event, RoomMemberEvent) self.matrix.restore_login(self.identifier, device_id, access_token) self.bot = bot self.log.level = logging.DEBUG self.log.debug(f"Initialized Matrix Bot: {self.identifier}")
async def bot_init(): global client m_config = config["matrix"] client = AsyncClient(m_config["homeserver"], m_config["mx_id"], m_config["device_id"]) await client.login(m_config["password"]) await client.sync()
async def main() -> None: client = AsyncClient(hs_url, mxid) await client.login(password) history = [] while (True): sync_response = await client.sync(30000) if len(sync_response.rooms.join) > 0: joins = sync_response.rooms.join for room_id in joins: for event in joins[room_id].timeline.events: if isinstance(event, RoomMessageText): if event.body.startswith("@Bernd"): history.append(tokenizer.encode(event.body)) with torch.no_grad(): out_ids = sample_sequence(personality, history, tokenizer, model, args) history.append(out_ids) history = history[-(2*args.max_history+1):] out_text = tokenizer.decode(out_ids, skip_special_tokens=True) await client.room_send(room_id,message_type="m.room.message", content = { "msgtype": "m.text", "body": out_text } )
def make_client(): client_config = AsyncClientConfig(encryption_enabled=True) return AsyncClient(settings.homeserver, settings.mxid, device_id=settings.device_id, config=client_config, store_path=settings.store_dir)
async def main_nio(homeserver, user, password, room_id, ext, mimetype, data_provider, content, log_fn): client = AsyncClient(homeserver, user) await client.login(password) upload_response, decrypt_info = None, None if data_provider: upload_response, decrypt_info = await client.upload( data_provider, mimetype ) content['url'] = upload_response.content_uri log_fn("uploading message to room %s: %s" % (room_id, str(content))) response = await client.room_send( room_id=room_id, message_type="m.room.message", content=content ) await client.close() return { "event_id" : response.event_id, "room_id" : response.room_id }
async def main() -> None: client = AsyncClient(HOMESERVER_URL, BOT_USER) logging.info(await client.login(BOT_PASSWORD)) # Build local cache create_cache() # Fetch recent posts from all sources posts = fetch_posts() cache_results(posts) counter = 0 for post in posts: if not post["skip"]: await client.room_send( room_id=ROOM_ID, message_type="m.room.message", content=format_message_content(post) ) counter += 1 logging.info("Sent %s into the Matrix room", pluralize("post", counter)) # End this session await client.logout() await client.close()
async def main(): async_client = AsyncClient( "https://matrix.org", "@reflexioneseir:matrix.org") response = await async_client.login("bezdma2rfl") print(response) await async_client.room_send( # Watch out! If you join an old room you'll see lots of old messages room_id="!gtvHHqMIfzLLUCoIAd:matrix.org", message_type="m.room.message", content = { "msgtype": "m.text", "body": "¡Prueba!" } ) return sync_response = await async_client.sync(30000) time.sleep(10) joins = sync_response.rooms.join for room_id in joins: print(f"Room id: {room_id}") print(joins[room_id]) print(joins)
async def do_init( homeserver, userid, device_name, password, path, roomid, endpoint, force ) -> None: full_path = os.path.join(path, CONFIG_FILE) if os.path.exists(full_path): if not force: print("Config file already exists, requires --force") return os.remove(full_path) if not (homeserver.startswith("https://") or homeserver.startswith("http://")): homeserver = "https://" + homeserver client = AsyncClient(homeserver, userid) resp = await client.login(password, device_name=device_name) # check that we logged in succesfully if isinstance(resp, LoginResponse): write_details_to_disk(resp, homeserver, full_path, roomid, endpoint) else: print(f'homeserver = "{homeserver}"; user = "******"') print(f"Failed to log in: {resp}") sys.exit(1) print( "Logged in using a password. Credentials were stored.", ) await client.close()
async def exec_rename(strategy, homeserver, mxid, passwd, script_device_id): client = AsyncClient(homeserver, mxid, script_device_id) await client.login(passwd) print("Fetching rooms...") # Sync fetches rooms await client.sync() planned_renames = [] for room in client.rooms.values(): room_id = room.room_id myroomnick = room.user_name(mxid) myavatarurl = room.avatar_url(mxid) nick_change_allowed = strategy.nick_change_allowed(myroomnick, myavatarurl) avatar_change_allowed = strategy.avatar_change_allowed(myroomnick, myavatarurl) print("ROOM {} {} {}".format(room.display_name, room_id, myroomnick if nick_change_allowed else (Fore.MAGENTA + myroomnick + Style.RESET_ALL))) if not nick_change_allowed and not avatar_change_allowed: print(" => skip") continue member_response = await client.joined_members(room_id = room_id) members = member_response.members new_name, new_avatar = strategy.get_new_name_and_avatar(myroomnick, myavatarurl, room, members) if not nick_change_allowed: new_name = myroomnick if not avatar_change_allowed: new_avatar = myavatarurl if myroomnick == new_name and myavatarurl == new_avatar: print(" => keep {}".format(myroomnick)) else: print(f" => {Fore.YELLOW}{myroomnick}|{myavatarurl}{Style.RESET_ALL} -> {Fore.CYAN}{new_name}|{new_avatar}{Style.RESET_ALL}") planned_renames.append(PlannedRename(room_id=room_id, room_name=room.display_name, old_name=myroomnick, new_name=new_name, old_avatar=myavatarurl, new_avatar=new_avatar)) # get max room name length only for planned renames for formatting max_room_name_len = 0 for pr in planned_renames: max_room_name_len = max(max_room_name_len, len(pr.room_name)) print("-"*42) print("Planned renames:") room_format = "{{:<{}}}".format(max_room_name_len) for pr in planned_renames: room_name = room_format.format(pr.room_name) print(f"{room_name} |{pr.old_name}|{pr.old_avatar} -> {pr.new_name}|{pr.new_avatar}") print("-"*42) input("Enter to rename") for pr in planned_renames: room_id = pr.room_id # Compare https://github.com/matrix-org/matrix-react-sdk/blob/7c4a84aae0b764842fadd38237c1a857437c4f51/src/SlashCommands.tsx#L274 # https://github.com/matrix-org/matrix-doc/blob/8eb1c531442093d239ab35027d784c4d9cfc8ac9/specification/client_server_api.rst#L1975 # https://github.com/matrix-org/matrix-doc/blob/9281d0ca13c39b83b8bbba184c8887d3d4faf045/event-schemas/schema/m.room.member # https://github.com/matrix-org/matrix-doc/blob/370ae8b9fe873b3ce061e4a8dbd7cf836388d640/event-schemas/examples/m.room.member # https://github.com/poljar/matrix-nio/blob/41636f04c14ffede01cf31abc309615b16ac949b/nio/client/async_client.py#L1570 content = { "membership": "join", "displayname": pr.new_name, "avatar_url": pr.new_avatar } print(f"{pr.room_name}: {content}") result = await client.room_put_state(room_id = room_id, event_type = "m.room.member", content = content, state_key = mxid) if VERBOSE: print(result) await client.logout() await client.close()
def __init__(self, controller, creds): self.name = controller.MATRIXBZ_BOT_NAME self.CHANNEL_GREETING = controller.CHANNEL_GREETING self.user = creds['user'] self.password = creds['password'] self.client = AsyncClient(creds['homeserver'], creds['user']) self.client.add_event_callback(self.invite_cb, InviteMemberEvent) self.client.add_event_callback(self.message_cb, RoomMessageText) self._setup_handlers(controller) if hasattr(controller, 'AUTH'): self.AUTH = controller.AUTH(controller) else: self.AUTH = BlockAll(controller) if hasattr(controller, 'CACHE'): self.CACHE = controller.CACHE else: self.CACHE = NoCache()
async def login(self) -> AsyncClient: # If there are no previously-saved credentials, we'll use the password if not os.path.exists(self.config.state_file): self.logger.info( "First time use. Did not find credential file. Using environment variables" ) client = AsyncClient(self.config.homeserver, self.config.account_name) resp = await client.login(self.config.account_password, device_name=self.config.device_name) # check that we logged in succesfully if (isinstance(resp, LoginResponse)): write_details_to_disk(resp, self.config) else: self.logger.warning( f'homeserver = "{self.config.homeserver}"; user = "******"' ) self.logger.warning(f'Failed to log in: {resp}') exit(1) self.logger.info( 'Logged in using a password. Credentials were stored.', 'Try running the script again to login with credentials') # Otherwise the config file exists, so we'll use the stored credentials else: client = AsyncClient(self.config.homeserver) client.access_token = self.access_token client.user_id = self.user_id client.device_id = self.device_id return client
async def do_sendmsg(roomid, message, path, endpoint) -> None: full_path = os.path.join(path, CONFIG_FILE) if not os.path.exists(full_path): print(f"Didn't find {full_path}, perhaps you should run init first") return # open the file in read-only mode with open(full_path, "r") as f: config = json.load(f) client = AsyncClient(config["homeserver"]) client.access_token = config["access_token"] client.user_id = config["user_id"] client.device_id = config["device_id"] if not roomid: try: roomid = config["room_id"] except KeyError: print("Must either specify roomid or put it config file") raise if endpoint: do_check_health(endpoint, 10) else: try: endpoint = config["endpoint"] except KeyError: pass else: do_check_health(endpoint, 10) resp = await client.room_send( roomid, message_type="m.room.message", content={ "msgtype": "m.text", "body": message, }, ) if isinstance(resp, RoomSendResponse): print("Logged in using stored credentials. Sent message.") else: print(f"Bad response: {resp}") await client.close()
async def create_client() -> AsyncClient: homeserver = "https://matrix-client.matrix.org" homeserver = input( f"Enter URL of your homeserver: [{homeserver}] ") or homeserver user_id = input(f"Enter your full user ID (e.g. @user:matrix.org): ") password = getpass.getpass() client = AsyncClient( homeserver=homeserver, user=user_id, config=AsyncClientConfig(store=store.SqliteMemoryStore), ) await client.login(password, DEVICE_NAME) client.load_store() room_keys_path = input("Enter full path to room E2E keys: ") room_keys_password = getpass.getpass("Room keys password: "******"Importing keys. This may take a while...") await client.import_keys(room_keys_path, room_keys_password) return client