import markdown from loguru import logger from nio import AsyncClient, LoginResponse class MatrixBot: def __init__(self, config: dict): self.config = config self.client = AsyncClient( homeserver=self.config['homeserver'], user=self.config['username'] ) self.logged_in = False async def ensure_logged_in(self): if not self.logged_in: try: response = await self.client.login(password=self.config['password']) if isinstance(response, LoginResponse): self.logged_in = True logger.info(f"Logged in as {self.config['username']}") else: logger.error(f"Failed to login as {self.config['username']}: {response}") logger.error("Closing nio session") await self.client.close() except Exception as e: logger.error(f"Exception during login: {e}") await self.client.close() raise async def send_message(self, message: str): await self.ensure_logged_in() if not self.logged_in: logger.error("Unable to send message, login failed") return try: await self.client.room_send( room_id=self.config['room_id'], message_type="m.room.message", content={ "msgtype": "m.text", "body": message } ) logger.info("Message sent") except Exception as e: logger.error(f"Exception during sending message: {e}") raise async def send_markdown(self, message: str): await self.ensure_logged_in() if not self.logged_in: logger.error("Unable to send message, login failed") return try: # Convert message to markdown html = markdown.markdown(message) # Send markdown formatted message await self.client.room_send( room_id=self.config['room_id'], message_type="m.room.message", content={ "msgtype": "m.text", "body": message, "format": "org.matrix.custom.html", "formatted_body": html } ) logger.info("Markdown message sent") except Exception as e: logger.error(f"Exception during sending markdown message: {e}") raise async def close(self): if self.logged_in: try: await self.client.logout() self.logged_in = False logger.info(f"Logged out from {self.config['homeserver']}") except Exception as e: logger.error(f"Exception during logout: {e}") finally: await self.client.close() # Ensure the client is closed