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 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 main() -> None: # If there are no previously-saved credentials, we'll use the password if not os.path.exists(CONFIG_FILE): print("First time use. Did not find credential file. Asking for " "homeserver, user, and password to create credential file.") homeserver = "https://matrix.example.org" homeserver = input(f"Enter your homeserver URL: [{homeserver}] ") if not (homeserver.startswith("https://") or homeserver.startswith("http://")): homeserver = "https://" + homeserver user_id = "@user:example.org" user_id = input(f"Enter your full user ID: [{user_id}] ") device_name = "matrix-nio" device_name = input(f"Choose a name for this device: [{device_name}] ") client = AsyncClient(homeserver, user_id) pw = getpass.getpass() resp = await client.login(pw, device_name=device_name) # check that we logged in succesfully if (isinstance(resp, LoginResponse)): write_details_to_disk(resp, homeserver) else: print(f"homeserver = \"{homeserver}\"; user = \"{user_id}\"") print(f"Failed to log in: {resp}") sys.exit(1) print( "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: # open the file in read-only mode with open(CONFIG_FILE, "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'] # Now we can send messages as the user room_id = "!myfavouriteroomid:example.org" 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) 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 main() -> None: # If there are no previously-saved credentials, we'll use the password if not os.path.exists(CONFIG_FILE): print("First time use. Did not find credential file. Asking for " "homeserver, user, and password to create credential file.") homeserver = "https://matrix.example.org" homeserver = input(f"Enter your homeserver URL: [{homeserver}] ") if not (homeserver.startswith("https://") or homeserver.startswith("http://")): homeserver = "https://" + homeserver user_id = "@user:example.org" user_id = input(f"Enter your full user ID: [{user_id}] ") client = AsyncClient(homeserver, user_id) pw = getpass.getpass() resp = await client.login(pw) # check that we logged in succesfully if (isinstance(resp, LoginResponse)): write_details_to_disk(resp, homeserver) else: print(f"homeserver = \"{homeserver}\"; user = \"{user_id}\"") print(f"Failed to log in: {resp}") sys.exit(1) print("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: # open the file in read-only mode with open(CONFIG_FILE, "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'] # Now we can send messages as the user room_id = "!myfavouriteroomid:example.org" room_id = input(f"Enter room id for test message: [{room_id}] ") await client.room_send(room_id, message_type="m.room.message", content={ "msgtype": "m.text", "body": "Hello world!" }) print("Logged in using stored credentials. Sent a test message.") # Either way we're logged in here, too await client.close()
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()
async def main(): # Read config file config = Config("config.yaml") # Configure the database store = Storage(config.database_filepath) # Configuration options for the AsyncClient client_config = AsyncClientConfig( max_limit_exceeded=0, max_timeouts=0, ) # Initialize the matrix client client = AsyncClient( config.homeserver_url, config.user_id, device_id=config.device_id, config=client_config, ) logger.debug("Connected to Matrix!") # Assign an access token to the bot instead of logging in and creating a new device client.access_token = config.access_token # Set up event callbacks callbacks = Callbacks(client, store, config) client.add_event_callback(callbacks.message, (RoomMessageText, )) client.add_event_callback(callbacks.invite, (InviteEvent, )) # Retrieve the last sync token if it exists token = store.get_sync_token() # Sync loop while True: # Sync with the server sync_response = await client.sync(timeout=30000, full_state=True, since=token) # Check if the sync had an error if type(sync_response) == SyncError: logger.warning("Error in client sync: %s", sync_response.message) continue # Save the latest sync token token = sync_response.next_batch if token: store.save_sync_token(token)
async def main() -> None: bot_info = load_bot_info() mongo_client = MongoClient( "mongodb+srv://{}:{}@{}/weekling?retryWrites=true&w=majority".format( bot_info["db_username"], bot_info["db_password"], bot_info["db_hostname"])) db = mongo_client.weekling # NOTE Hemppa-hack jointime = datetime.datetime.now() # HACKHACKHACK to avoid running old # commands after join join_hack_time = 5 # Seconds """ Create the client-object with correct info, set callbacks for reacting to events and login. If an access token is not found in config-file, ask for password. """ client = AsyncClient(bot_info["homeserver"]) client.add_event_callback(pass_to_invite_callback(client), InviteMemberEvent) client.add_event_callback( pass_to_message_callback(client, db, jointime, join_hack_time), RoomMessageText) # Ask password from command line, press enter to use stored access token access_token = bot_info["access_token"] user_id = bot_info["user_id"] if len(access_token) != 0 and len(user_id) != 0: client.access_token = access_token # Manually set user id because not calling client.login() client.user_id = user_id else: password = getpass.getpass() response = await client.login(password) # Save info to file for future use bot_info["access_token"] = response.access_token try: with io.open(LOGIN_FILE, "w", encoding="utf-8") as fp: fp.write(json.dumps(bot_info)) except OSError as e: print(f"Writing login-info failed: {e}") print(f"Logged in as {client}") await client.sync_forever(timeout=30000, full_state=False) # milliseconds
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 login() -> None: try: with open(CREDS_FILE) as f: creds = json.load(f) client = AsyncClient(creds["homeserver"]) client.access_token = creds["access_token"] client.user_id = creds["user_id"] client.device_id = creds["device_id"] except (FileNotFoundError, json.JSONDecodeError, KeyError): print(f"Did not find credentials in {CREDS_FILE}. " "Asking for login info.") matrix_server_str = "matrix.org" matrix_server_str = (input("Enter your matrix server URL " f"(default = {matrix_server_str!r}): ") or matrix_server_str) url = urlsplit(matrix_server_str) url = (url._replace(scheme=url.scheme or "https")._replace( netloc=url.netloc or url.path)._replace(path="")) matrix_server = urlunsplit(url) user_id = input("Enter your user ID: ") user, *server_maybe = user_id.lstrip("@").split(":", 1) user_id = f"@{user}:" + (server_maybe[0] if server_maybe else url.netloc) device_name = "diplomatrix_client" device_name = (input("Choose a name for this device " f"(default = {device_name!r}): ") or device_name) client = AsyncClient(matrix_server, user_id) pw = getpass.getpass() resp = await client.login(pw, device_name=device_name) if isinstance(resp, LoginResponse): save_login(resp, matrix_server) print(f"Logged in. Credentials saved to {CREDS_FILE!r}") else: print(f'server = "{matrix_server}"; user = "******"') print(f"Failed to log in: {resp}") sys.exit(1) await client.close()
async def main() -> None: client = AsyncClient("https://the-apothecary.club", "@bot-sync:the-apothecary.club") # imports login data with open(CONFIG_FILE, "r") as f: config = json.load(f) client.access_token = config["access_token"] client.user_id = config["user_id"] client.device_id = config["device_id"] # import room data with open(ROOMS_FILE, "r") as f: config = json.load(f) bot_control_room = config["control_room"] bot_template_room = config["template_room"] bot_rooms = config["rooms"] ## await bot_send_msg(client, "Online", bot_control_room) # get room state room_state = await client.room_get_state(bot_template_room) ## print(room_state) # execute in each room for room in bot_rooms: # logs room cycle print("Syncing state in:", room["id"]) # join rooms if not already joined await client.join(room["id"]) # sends a test message ##resp = await bot_send_msg(client, "Syncing...", room["id"]) ##print(resp) # sends a test state event resp = await bot_set_emote(client, room["id"]) print(resp) # ends the connection await client.close()
async def main(sugaroid: Sugaroid) -> None: config = Config.from_environment() client = AsyncClient(config['homeserver']) client.access_token = config['access_token'] client.user_id = config['user_id'] client.device_id = config['device_id'] print("Status: sleeping for 30000") await client.sync(30000) print("Resuming:") cb = Callbacks(client, sugaroid=sugaroid) client.add_event_callback(cb.message, RoomMessageText) while True: try: await client.sync_forever(timeout=30000, full_state=True) except KeyboardInterrupt: break except (ClientConnectionError, ServerDisconnectedError): print("Unable to connect to homeserver, retrying in 15s") time.sleep(15) finally: await client.close()
async def main(): global client access_token = os.getenv('MATRIX_ACCESS_TOKEN') join_on_invite = os.getenv('JOIN_ON_INVITE') client = AsyncClient(os.environ['MATRIX_SERVER'], os.environ['MATRIX_USER']) if access_token: client.access_token = access_token else: await client.login(os.environ['MATRIX_PASSWORD']) print("Access token:", client.access_token) await client.sync() if client.logged_in: client.add_event_callback(message_cb, RoomMessageText) client.add_event_callback(unknown_cb, RoomMessageUnknown) if join_on_invite: print('Note: Bot will join rooms if invited') client.add_event_callback(invite_cb, (InviteEvent, )) print('Bot running') await client.sync_forever(timeout=30000) else: print('Client was not able to log in, check env variables!')
async def main() -> None: client = AsyncClient("https://matrix.example.org", "@alice:example.org") # If there are no previously-saved credentials, we'll use the password if not os.path.exists(CONFIG_FILE): resp = await client.login("hunter2") # check that we logged in succesfully if (isinstance(resp, LoginResponse)): write_details_to_disk(resp) else: print(f"Failed to log in: {resp}") sys.exit(1) print("Logged in using a password.", "Try running the script again to login with an access token") # Otherwise the config file exists, so we'll use the stored credentials else: # open the file in read-only mode with open(CONFIG_FILE, "r") as f: config = json.load(f) client.access_token = config['access_token'] client.user_id = config['user_id'] client.device_id = config['device_id'] # Now we can send messages as the user await client.room_send(room_id="!myfavouriteroomid:example.org", message_type="m.room.message", content={ "msgtype": "m.text", "body": "Hello world!" }) print("Logged in using stored credentials") # Either way we're logged in here, too await client.close()
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()
async def main(): """Entry point.""" # Read config file config = Config("config.yaml") # Configure the database store = Storage(config.database_filepath) # Configuration options for the AsyncClient client_config = AsyncClientConfig( max_limit_exceeded=0, max_timeouts=0, # store_sync_tokens=True, encryption_enabled=config.enable_encryption, ) # Initialize the matrix client client = AsyncClient( config.homeserver_url, config.user_id, device_id=config.device_id, store_path=config.store_filepath, config=client_config, ) # Assign an access token to the bot instead of logging in and creating a new device client.access_token = config.access_token # 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.joined, (RoomMemberEvent,)) # Create a new sync token, attempting to load one from the database if it has one already sync_token = SyncToken(store) # Keep trying to reconnect on failure (with some time in-between) while True: # try: # 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(f"Failed to login: %s", login_response.message) # return False # except LocalProtocolError as e: # # There's an edge case here where the user enables encryption # # but hasn't installed the correct C dependencies. In that case, # # a LocalProtocolError is raised on login. # # Warn the user if these conditions are met. # if config.enable_encryption: # logger.fatal( # "Failed to login and encryption is enabled. " # "Have you installed the correct dependencies? " # "https://github.com/poljar/matrix-nio#installation" # ) # return False # else: # # We don't know why this was raised. Throw it at the user # logger.fatal("Error logging in: %s", e) # return False # Login succeeded! # =============================== # Sync encryption keys with the server # Required for participating in encrypted rooms # if client.should_upload_keys: # await client.keys_upload() # logger.info(f"Logged in as {config.user_id}") # await client.sync_forever(timeout=30000, full_state=True) # =============================== # =============================== logger.debug("Syncing: %s", sync_token.token) sync_response = await client.sync(timeout=30000, since=sync_token.token) # Check if the sync had an errors if type(sync_response) == SyncError: logger.warning("Error in client sync: %s", sync_response.message) continue # Save the latest sync token to the database token = sync_response.next_batch if token: sync_token.update(token)