Telegram-бот (aiogram 3.x)
Стек
- aiogram 3.x
- Redis — FSM storage
- HTTP client — httpx к backend API
- NATS consumer — game events
Команды
| Команда |
Описание |
FR |
/start |
Приветствие, меню |
FR-044 |
/join <code> |
Вход в сессию |
FR-002, FR-044 |
/leave |
Выход из сессии |
FR-044 |
/help |
Краткая справка |
Could |
/admin |
Справка по админ-командам (только ADMIN_TELEGRAM_ID) |
FR-058 |
/admin login |
Запрос OTP для входа в админ-панель |
FR-058 |
FSM States
stateDiagram-v2
[*] --> MainMenu
MainMenu --> InLobby: join success
InLobby --> InGame: game started
InGame --> InLobby: game ended
InLobby --> MainMenu: leave
InGame --> MainMenu: leave
| State |
Handlers |
MainMenu |
/start, /join |
InLobby |
participant list, wait for host |
InGame |
dice_board callbacks |
Watching |
spectator (Phase 2+) |
dice_board callbacks
| callback_data |
Action |
db:roll |
roll_dice |
db:cell:{r}:{c} |
choose_cell |
Сообщения с медиа
- При
game.state_changed → GET /media/render/{game_id}
edit_message_media если message exists, иначе send_photo
reply_markup — InlineKeyboard с кандидатами
Fallback
Если media-service недоступен:
· · 1 · · ·
· · · 2 · ·
...
🎲 4, 2 | Ход: Игрок1
Middleware stack
AuthMiddleware — map telegram_id → participant
ThrottlingMiddleware — 1 action / 500ms
ErrorHandler — user-friendly Russian messages
Webhook vs Polling
| Mode |
Когда |
| Polling |
Dev local |
| Webhook |
Prod https://api.tabletime.example/bot/webhook |
Ограничения Telegram
| Лимит |
Workaround |
| Caption 1024 chars |
Короткий caption + details в reply |
| edit rate |
Debounce 300ms, batch updates |
| Photo size |
Compress PNG < 1MB |
Пример handler (conceptual)
@router.callback_query(F.data.startswith("db:cell:"))
async def on_choose_cell(callback: CallbackQuery, state: FSMContext):
_, _, r, c = callback.data.split(":")
await api.submit_action(game_id, "choose_cell", {"row": int(r), "col": int(c)})
await callback.answer()
FR
FR-044–FR-046, FR-026, FR-006