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 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
async def main(): """The first function that is run when starting the bot""" # Read user-configured options from a config file. # A different config file path can be specified as the first command line argument if len(sys.argv) > 1: config_path = sys.argv[1] else: config_path = "config.yaml" # Read the parsed config file and create a Config object config = Config(config_path) # Configure the database store = Storage(config.database) # Configuration options for the AsyncClient client_config = AsyncClientConfig( max_limit_exceeded=0, max_timeouts=0, store_sync_tokens=True, encryption_enabled=True, ) # Initialize the matrix client client = AsyncClient( config.homeserver_url, config.user_id, device_id=config.device_id, store_path=config.store_path, config=client_config, ) if config.user_token: client.access_token = config.user_token client.user_id = config.user_id # Set up event callbacks callbacks = Callbacks(client, store, config) client.add_event_callback(callbacks.message, (RoomMessageText, )) client.add_event_callback(callbacks.invite, (InviteMemberEvent, )) client.add_event_callback(callbacks.decryption_failure, (MegolmEvent, )) client.add_event_callback(callbacks.unknown, (UnknownEvent, )) workflows = Workflow.fetch_workflows(config) aiocron.crontab(config.crontab, func=report_last_nightlies, args=(config, client, workflows)) # Keep trying to reconnect on failure (with some time in-between) while True: try: if config.user_token: # Use token to log in client.load_store() # Sync encryption keys with the server if client.should_upload_keys: await client.keys_upload() else: # Try to login with the configured username/password try: login_response = await client.login( password=config.user_password, device_name=config.device_name, ) # Check if login failed if type(login_response) == LoginError: logger.error("Failed to login: %s", login_response.message) return False except LocalProtocolError as e: # There's an edge case here where the user hasn't installed the correct C # dependencies. In that case, a LocalProtocolError is raised on login. logger.fatal( "Failed to login. Have you installed the correct dependencies? " "https://github.com/poljar/matrix-nio#installation " "Error: %s", e, ) return False # Login succeeded! logger.info(f"Logged in as {config.user_id}") await client.sync_forever(timeout=30000, full_state=True) except (ClientConnectionError, ServerDisconnectedError): logger.warning( "Unable to connect to homeserver, retrying in 15s...") # Sleep so we don't bombard the server with login requests sleep(15) finally: # Make sure to close the client connection on disconnect await client.close()
async def main(args): cfgparser = configparser.ConfigParser() with open(args.config) as fh: cfgparser.read_file(fh) cfg = cfgparser['DEFAULT'] room = cfg['room'] payload = { 'service': args.service, 'host': args.host, 'type': args.type.upper(), 'state': args.state.upper(), 'output': args.output, 'msg': args.message, } device = {} device_state = os.path.join(cfg['state'], 'device.json') try: with open(device_state) as fh: device = json.load(fh) except FileNotFoundError: pass ensure_dir(cfg['state']) ensure_dir(os.path.join(cfg['state'], 'nio')) ensure_dir(os.path.join(cfg['state'], 'nio', cfg['user_id'])) client = AsyncClient(cfg['homeserver'], cfg['user_id'], device_id=device.get('device_id'), store_path=os.path.join(cfg['state'], 'nio', cfg['user_id']), config=ClientConfig(store_sync_tokens=True)) if device: client.access_token = device['access_token'] client.user_id = device['user_id'] client.load_store() else: resp = await client.login_raw({ 'type': 'org.matrix.login.jwt', 'token': cfg['token'], }) if (isinstance(resp, LoginResponse)): write_state(device_state, resp) else: print(f"Failed to log in: {resp}", file=sys.stderr) sys.exit(1) await client.sync(timeout=args.timeout * 1000, full_state=True) in_rooms = client.rooms.keys() room_id = (await client.room_resolve_alias(room)).room_id if not room_id in in_rooms: await client.join(room_id) for unwanted in [r for r in in_rooms if r != room_id]: await client.room_leave(room) if client.should_upload_keys: await client.keys_upload() if client.should_query_keys: await client.keys_query() if client.should_claim_keys: await client.keys_claim(client.get_users_for_key_claiming()) await client.sync(timeout=args.timeout * 1000, full_state=True) ps_l = [] if payload['msg']: ps_l.append(payload['msg']) if payload['output']: ps_l.append(payload['output']) ps = '\n'.join(ps_l) await client.room_send( room_id, 'm.room.message', { 'msgtype': 'm.text', 'body': '{type}: {service} on {host} is {state}\n{msg}'.format(**payload), 'format': 'org.matrix.custom.html', 'formatted_body': '<span style="background-color: #{color};"><span data-mx-bg-color="#{color}"><strong>{type}</strong>:</span></span> <span data-mx-bg-color="#ffffff">Service <strong>{service}</strong> on <strong>{host}</strong> is <strong>{state}</strong>:<br />{ps}</span>' .format(**payload, bgcolor=state_colors_back.get(payload['state'].lower(), '222288'), ps=ps, color=state_colors.get(payload['state'].lower(), '1111ff')), }, ignore_unverified_devices=True) await client.sync(timeout=args.timeout * 1000, full_state=True) await client.close()
async def main(): # Read config file # A different config file path can be specified as the first command line argument if len(sys.argv) > 1: config_path = sys.argv[1] else: config_path = "config.yaml" config = Config(config_path) # Configure the database store = Storage(config.database) # Configuration options for the AsyncClient client_config = AsyncClientConfig( max_limit_exceeded=0, max_timeouts=0, store_sync_tokens=True, encryption_enabled=True, ) # Initialize the matrix client client = AsyncClient( config.homeserver_url, config.user_id, device_id=config.device_id, store_path=config.store_path, config=client_config, ) if config.user_token: client.access_token = config.user_token client.user_id = config.user_id # Set up event callbacks callbacks = Callbacks(client, store, config) # noinspection PyTypeChecker client.add_event_callback(callbacks.message, (RoomMessageText, )) # noinspection PyTypeChecker client.add_event_callback(callbacks.invite, (InviteMemberEvent, )) # Keep trying to reconnect on failure (with some time in-between) while True: try: if config.user_token: # Use token to log in client.load_store() # Sync encryption keys with the server if client.should_upload_keys: await client.keys_upload() else: # Try to login with the configured username/password try: login_response = await client.login( password=config.user_password, device_name=config.device_name, ) # Check if login failed if type(login_response) == LoginError: logger.error("Failed to login: %s", login_response.message) break except LocalProtocolError as e: # There's an edge case here where the user hasn't installed the correct C # dependencies. In that case, a LocalProtocolError is raised on login. logger.fatal( "Failed to login. Have you installed the correct dependencies? " "https://github.com/poljar/matrix-nio#installation " "Error: %s", e, ) break # Login succeeded! # Join the management room or fail response = await with_ratelimit(client, "join", config.management_room) if type(response) == JoinError: logger.fatal("Could not join the management room, aborting.") break else: logger.info(f"Management room membership is good") # Resolve management room ID if not known if config.management_room.startswith('#'): # Resolve the room ID response = await with_ratelimit(client, "room_resolve_alias", config.management_room) if type(response) == RoomResolveAliasResponse: config.management_room_id = response.room_id else: logger.fatal( "Could not resolve the management room ID from alias, aborting" ) break logger.info(f"Logged in as {config.user_id}") await client.sync_forever(timeout=30000, full_state=True) except (ClientConnectionError, ServerDisconnectedError): logger.warning( "Unable to connect to homeserver, retrying in 15s...") # Sleep so we don't bombard the server with login requests sleep(15) finally: # Make sure to close the client connection on disconnect await client.close()