diff --git a/plugins/platforms/mattermost/adapter.py b/plugins/platforms/mattermost/adapter.py index bb6dc9b81f24..8fb06823d8cd 100644 --- a/plugins/platforms/mattermost/adapter.py +++ b/plugins/platforms/mattermost/adapter.py @@ -792,6 +792,8 @@ async def _handle_ws_event(self, event: Dict[str, Any]) -> None: # Determine message type. file_ids = post.get("file_ids") or [] msg_type = MessageType.TEXT + if message_text[:1].isspace() and message_text.lstrip().startswith("/"): + message_text = message_text.lstrip() if message_text.startswith("/"): msg_type = MessageType.COMMAND diff --git a/tests/gateway/test_mattermost.py b/tests/gateway/test_mattermost.py index cafe5ad68a49..4faa3074035e 100644 --- a/tests/gateway/test_mattermost.py +++ b/tests/gateway/test_mattermost.py @@ -6,6 +6,7 @@ from unittest.mock import MagicMock, patch, AsyncMock from gateway.config import Platform, PlatformConfig +from gateway.platforms.base import MessageType # --------------------------------------------------------------------------- @@ -366,6 +367,55 @@ async def test_channel_type_mapping(self): msg_event = self.adapter.handle_message.call_args[0][0] assert msg_event.source.chat_type == "dm" + @pytest.mark.asyncio + async def test_leading_space_slash_command_is_command(self): + """Mattermost mobile suggests leading-space slash commands.""" + post_data = { + "id": "post_cmd", + "user_id": "user_123", + "channel_id": "chan_dm", + "message": " /new", + } + event = { + "event": "posted", + "data": { + "post": json.dumps(post_data), + "channel_type": "D", + "sender_name": "@bob", + }, + } + + await self.adapter._handle_ws_event(event) + assert self.adapter.handle_message.called + msg_event = self.adapter.handle_message.call_args[0][0] + assert msg_event.text == "/new" + assert msg_event.message_type is MessageType.COMMAND + assert msg_event.get_command() == "new" + + @pytest.mark.asyncio + async def test_leading_space_normal_text_is_preserved(self): + """Only command-shaped mobile messages should be normalized.""" + post_data = { + "id": "post_text", + "user_id": "user_123", + "channel_id": "chan_dm", + "message": " hello", + } + event = { + "event": "posted", + "data": { + "post": json.dumps(post_data), + "channel_type": "D", + "sender_name": "@bob", + }, + } + + await self.adapter._handle_ws_event(event) + assert self.adapter.handle_message.called + msg_event = self.adapter.handle_message.call_args[0][0] + assert msg_event.text == " hello" + assert msg_event.message_type is MessageType.TEXT + @pytest.mark.asyncio async def test_thread_id_from_root_id(self): """Post with root_id should have thread_id set."""