Files
matrix/callbacks.py

63 lines
2.0 KiB
Python
Raw Normal View History

import logging
from functools import wraps
from nio import AsyncClient, RoomMessageText
from config import BOT_PREFIX, MATRIX_USER_ID
from commands import COMMANDS, metrics
logger = logging.getLogger("matrixbot")
def handle_command_errors(func):
@wraps(func)
async def wrapper(client, room_id, sender, args):
try:
return await func(client, room_id, sender, args)
except Exception as e:
logger.error(f"Error in command {func.__name__}: {e}", exc_info=True)
metrics.record_error(func.__name__)
try:
from utils import send_text
await send_text(client, room_id, "An unexpected error occurred. Please try again later.")
except Exception as e2:
logger.error(f"Failed to send error message: {e2}", exc_info=True)
return wrapper
class Callbacks:
def __init__(self, client: AsyncClient):
self.client = client
# Track the sync token so we ignore old messages on startup
self.startup_sync_token = None
async def message(self, room, event):
# Ignore messages from before the bot started
if self.startup_sync_token is None:
return
# Ignore our own messages
if event.sender == MATRIX_USER_ID:
return
body = event.body.strip() if event.body else ""
if not body.startswith(BOT_PREFIX):
return
# Parse command and args
without_prefix = body[len(BOT_PREFIX):]
parts = without_prefix.split(None, 1)
cmd_name = parts[0].lower() if parts else ""
args = parts[1] if len(parts) > 1 else ""
logger.info(f"Command '{cmd_name}' from {event.sender} in {room.room_id}")
handler_entry = COMMANDS.get(cmd_name)
if handler_entry is None:
return
handler, _ = handler_entry
metrics.record_command(cmd_name)
wrapped = handle_command_errors(handler)
await wrapped(self.client, room.room_id, event.sender, args)