diff --git a/src/main.py b/src/main.py
index e372a5e..7257188 100644
--- a/src/main.py
+++ b/src/main.py
@@ -579,25 +579,10 @@ async def run(settings: Settings) -> None:
command_handler = TelegramCommandHandler(telegram)
# Register basic commands
- async def handle_start() -> None:
- """Handle /start command."""
- message = (
- "🤖 The Ouroboros Trading Bot\n\n"
- "AI-powered global stock trading agent with real-time notifications.\n\n"
- "Available commands:\n"
- "/help - Show this help message\n"
- "/status - Current trading status\n"
- "/positions - View holdings\n"
- "/stop - Pause trading\n"
- "/resume - Resume trading"
- )
- await telegram.send_message(message)
-
async def handle_help() -> None:
"""Handle /help command."""
message = (
"📖 Available Commands\n\n"
- "/start - Welcome message\n"
"/help - Show available commands\n"
"/status - Trading status (mode, markets, P&L)\n"
"/positions - Current holdings\n"
@@ -722,7 +707,6 @@ async def run(settings: Settings) -> None:
"⚠️ Error\n\nFailed to retrieve positions."
)
- command_handler.register_command("start", handle_start)
command_handler.register_command("help", handle_help)
command_handler.register_command("stop", handle_stop)
command_handler.register_command("resume", handle_resume)
diff --git a/src/notifications/telegram_client.py b/src/notifications/telegram_client.py
index 4765cb4..3482646 100644
--- a/src/notifications/telegram_client.py
+++ b/src/notifications/telegram_client.py
@@ -492,7 +492,8 @@ class TelegramCommandHandler:
if not command_parts:
return
- command_name = command_parts[0]
+ # Remove @botname suffix if present (for group chats)
+ command_name = command_parts[0].split("@")[0]
# Execute handler
handler = self._commands.get(command_name)
diff --git a/tests/test_telegram_commands.py b/tests/test_telegram_commands.py
index 3438005..1b78a6e 100644
--- a/tests/test_telegram_commands.py
+++ b/tests/test_telegram_commands.py
@@ -230,6 +230,31 @@ class TestUpdateHandling:
await handler._handle_update(update)
assert executed is False
+ @pytest.mark.asyncio
+ async def test_handle_command_with_botname(self) -> None:
+ """Commands with @botname suffix are handled correctly."""
+ client = TelegramClient(bot_token="123:abc", chat_id="456", enabled=True)
+ handler = TelegramCommandHandler(client)
+
+ executed = False
+
+ async def test_command() -> None:
+ nonlocal executed
+ executed = True
+
+ handler.register_command("start", test_command)
+
+ update = {
+ "update_id": 1,
+ "message": {
+ "chat": {"id": 456},
+ "text": "/start@mybot",
+ },
+ }
+
+ await handler._handle_update(update)
+ assert executed is True
+
@pytest.mark.asyncio
async def test_handle_update_error_isolation(self) -> None:
"""Errors in handlers don't crash the system."""
@@ -638,51 +663,6 @@ class TestStatusCommands:
class TestBasicCommands:
"""Test basic command implementations."""
- @pytest.mark.asyncio
- async def test_start_command_content(self) -> None:
- """Start command contains welcome message and command list."""
- client = TelegramClient(bot_token="123:abc", chat_id="456", enabled=True)
- handler = TelegramCommandHandler(client)
-
- mock_resp = AsyncMock()
- mock_resp.status = 200
- mock_resp.__aenter__ = AsyncMock(return_value=mock_resp)
- mock_resp.__aexit__ = AsyncMock(return_value=False)
-
- async def mock_start() -> None:
- """Mock /start handler."""
- message = (
- "🤖 The Ouroboros Trading Bot\n\n"
- "AI-powered global stock trading agent with real-time notifications.\n\n"
- "Available commands:\n"
- "/help - Show this help message\n"
- "/status - Current trading status\n"
- "/positions - View holdings\n"
- "/stop - Pause trading\n"
- "/resume - Resume trading"
- )
- await client.send_message(message)
-
- handler.register_command("start", mock_start)
-
- with patch("aiohttp.ClientSession.post", return_value=mock_resp) as mock_post:
- update = {
- "update_id": 1,
- "message": {
- "chat": {"id": 456},
- "text": "/start",
- },
- }
-
- await handler._handle_update(update)
-
- # Verify message was sent
- assert mock_post.call_count == 1
- payload = mock_post.call_args.kwargs["json"]
- assert "Ouroboros Trading Bot" in payload["text"]
- assert "/help" in payload["text"]
- assert "/status" in payload["text"]
-
@pytest.mark.asyncio
async def test_help_command_content(self) -> None:
"""Help command lists all available commands."""
@@ -698,7 +678,6 @@ class TestBasicCommands:
"""Mock /help handler."""
message = (
"📖 Available Commands\n\n"
- "/start - Welcome message\n"
"/help - Show available commands\n"
"/status - Trading status (mode, markets, P&L)\n"
"/positions - Current holdings\n"
@@ -724,7 +703,6 @@ class TestBasicCommands:
assert mock_post.call_count == 1
payload = mock_post.call_args.kwargs["json"]
assert "Available Commands" in payload["text"]
- assert "/start" in payload["text"]
assert "/help" in payload["text"]
assert "/status" in payload["text"]
assert "/positions" in payload["text"]