diff --git a/src/adapters/jabber/command_handler.py b/src/adapters/jabber/command_handler.py index bb7905e..7cb636d 100644 --- a/src/adapters/jabber/command_handler.py +++ b/src/adapters/jabber/command_handler.py @@ -116,6 +116,10 @@ class CommandHandler: # ------------------------------------------------------------------ async def _handle_room(self, msg) -> None: + # Пропускаем исторические сообщения (XEP-0203), воспроизводимые при входе в комнату + if msg["delay"]["stamp"]: + return + room_jid = msg["from"].bare sender_nick = msg["from"].resource body = msg["body"].strip() if msg["body"] else "" @@ -208,7 +212,9 @@ class CommandHandler: room = await self._room_repo.get(room_jid) if not room: return False - return room.admin_jid == caller_jid + # Сравниваем bare JID — реальный JID из MUC может содержать ресурс + caller_bare = caller_jid.split("/")[0] + return room.admin_jid == caller_bare def _get_real_jid(self, room_jid: str, nick: str) -> str | None: """Получает реальный JID участника MUC через resolver.""" diff --git a/src/adapters/jabber/connection.py b/src/adapters/jabber/connection.py index 3c6194a..638d053 100644 --- a/src/adapters/jabber/connection.py +++ b/src/adapters/jabber/connection.py @@ -28,8 +28,7 @@ class JabberConnection(ClientXMPP, JabberRoomJoiner, JabberRoomLeaver, MucJidRes self.register_plugin("xep_0199") # XMPP Ping self.add_event_handler("session_start", self._on_session_start) - self.add_event_handler("message", self._on_chat_message) - self.add_event_handler("groupchat_message", self._on_groupchat_message) + self.add_event_handler("message", self._on_message) self.add_event_handler("failed_auth", self._on_failed_auth) def set_message_callback(self, callback: MessageCallback) -> None: @@ -52,28 +51,26 @@ class JabberConnection(ClientXMPP, JabberRoomJoiner, JabberRoomLeaver, MucJidRes except Exception: logger.exception("Не удалось зайти в комнату %s при старте", room_jid) - async def _on_chat_message(self, msg) -> None: - """Обрабатывает только личные сообщения (type=chat).""" - if msg["type"] != "chat": + async def _on_message(self, msg) -> None: + mtype = msg["type"] + if mtype == "chat": + # Игнорируем собственные личные сообщения + if msg["from"].bare == self.boundjid.bare: + return + elif mtype == "groupchat": + # Игнорируем собственные сообщения, отражённые сервером из комнаты + if msg["from"].resource == self._nick: + return + else: return - if msg["from"].bare == self.boundjid.bare: - return - if self._message_callback is not None: - try: - await self._message_callback(msg) - except Exception: - logger.exception("Ошибка в обработчике личных сообщений") - async def _on_groupchat_message(self, msg) -> None: - """Обрабатывает сообщения в конференции (type=groupchat).""" - # Игнорируем собственные сообщения, отражённые сервером - if msg["from"].resource == self._nick: - return + logger.debug("Входящее сообщение type=%s from=%s", mtype, msg["from"]) + if self._message_callback is not None: try: await self._message_callback(msg) except Exception: - logger.exception("Ошибка в обработчике сообщений конференции") + logger.exception("Ошибка в обработчике сообщений") async def _on_failed_auth(self, event) -> None: logger.error("Ошибка аутентификации XMPP") @@ -88,7 +85,7 @@ class JabberConnection(ClientXMPP, JabberRoomJoiner, JabberRoomLeaver, MucJidRes async def leave_room(self, room_jid: str) -> None: muc = self.plugin["xep_0045"] - await muc.leave_muc(room_jid, self._nick) + muc.leave_muc(room_jid, self._nick) logger.info("Вышел из комнаты %s", room_jid) # --- Вспомогательные методы для адаптеров ---