mirror of
https://git.juggalol.com/agatha/stockbot-buyvm.git
synced 2024-11-16 12:46:38 +00:00
181 lines
6.4 KiB
Python
181 lines
6.4 KiB
Python
"""
|
|
matrix.py
|
|
|
|
A module for interacting with the Matrix protocol.
|
|
|
|
Classes:
|
|
MatrixBot: A Matrix bot that can send messages and markdown messages to a room.
|
|
|
|
Dependencies:
|
|
markdown: A library for converting markdown to HTML.
|
|
loguru: A library for logging.
|
|
nio: A library for interacting with the Matrix protocol.
|
|
"""
|
|
import markdown
|
|
from loguru import logger
|
|
from nio import AsyncClient, LoginResponse
|
|
|
|
|
|
class MatrixBot:
|
|
"""
|
|
A Matrix bot that can send messages and markdown messages to a room.
|
|
|
|
Attributes:
|
|
config (dict): A dictionary containing the bot's configuration.
|
|
Expected keys are 'homeserver', 'username', 'password', 'room_id'.
|
|
client (AsyncClient): The Matrix client instance.
|
|
logged_in (bool): Whether the bot is currently logged in.
|
|
|
|
Methods:
|
|
__init__: Initializes the bot with a given configuration.
|
|
ensure_logged_in: Ensures that the bot is logged in to the Matrix homeserver.
|
|
send_message: Sends a message to the room specified in the bot's configuration.
|
|
send_markdown: Sends a markdown formatted message to the room specified in the bot's configuration.
|
|
close: Log out from the Matrix homeserver and close the client.
|
|
"""
|
|
def __init__(self, config: dict):
|
|
"""
|
|
A Matrix bot that can send messages and markdown messages to a room.
|
|
|
|
Args:
|
|
config (dict): A dictionary containing the bot's configuration.
|
|
Expected keys are 'homeserver', 'username', 'password', 'room_id'.
|
|
"""
|
|
self.config = config
|
|
|
|
self.client = AsyncClient(
|
|
homeserver=self.config['homeserver'],
|
|
user=self.config['username']
|
|
)
|
|
self.logged_in = False
|
|
|
|
async def ensure_logged_in(self):
|
|
"""
|
|
Ensures that the bot is logged in to the Matrix homeserver.
|
|
|
|
If the bot is not logged in, attempts to log in using the provided
|
|
password. If the login attempt fails, logs the error and closes the
|
|
nio session.
|
|
|
|
If an exception occurs during the login attempt, logs the error and
|
|
re-raises it.
|
|
"""
|
|
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):
|
|
"""
|
|
Sends a message to the room specified in the bot's configuration.
|
|
|
|
The message is sent as a simple text message, with the 'msgtype' set to
|
|
'm.text' and the 'body' set to the provided message.
|
|
|
|
If the bot is not logged in, attempts to log in using the provided
|
|
password. If the login attempt fails, logs the error and closes the
|
|
nio session.
|
|
|
|
If an exception occurs during the login attempt or the message sending,
|
|
logs the error and re-raises it.
|
|
|
|
Args:
|
|
message (str): The message to send to the room.
|
|
"""
|
|
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):
|
|
"""
|
|
Sends a markdown formatted message to the room specified in the bot's
|
|
configuration.
|
|
|
|
The message is sent as a text message with the 'msgtype' set to
|
|
'm.text', the 'body' set to the provided message, and the 'format'
|
|
set to 'org.matrix.custom.html'. The 'formatted_body' is set to the
|
|
markdown formatted message.
|
|
|
|
If the bot is not logged in, attempts to log in using the provided
|
|
password. If the login attempt fails, logs the error and closes the
|
|
nio session.
|
|
|
|
If an exception occurs during the login attempt or the message sending,
|
|
logs the error and re-raises it.
|
|
|
|
Args:
|
|
message (str): The message to send to the room.
|
|
"""
|
|
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):
|
|
"""
|
|
Log out from the Matrix homeserver and close the client.
|
|
|
|
If the bot is logged in, attempts to log out using the provided
|
|
password. If the login attempt fails, logs the error and closes the
|
|
nio session.
|
|
|
|
If an exception occurs during the login attempt or the message sending,
|
|
logs the error and re-raises it.
|
|
"""
|
|
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
|