Files
tg_bot_language/bot/handlers/start.py

161 lines
7.4 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
from aiogram import Router, F
from aiogram.filters import CommandStart, Command
from aiogram.types import (
Message,
InlineKeyboardMarkup,
InlineKeyboardButton,
CallbackQuery,
ReplyKeyboardMarkup,
KeyboardButton,
)
from aiogram.fsm.context import FSMContext
from database.db import async_session_maker
from services.user_service import UserService
router = Router()
@router.message(CommandStart())
async def cmd_start(message: Message, state: FSMContext):
"""Обработчик команды /start"""
async with async_session_maker() as session:
# Проверяем, существует ли пользователь
existing_user = await UserService.get_user_by_telegram_id(session, message.from_user.id)
is_new_user = existing_user is None
# Создаём или получаем пользователя
user = await UserService.get_or_create_user(
session,
telegram_id=message.from_user.id,
username=message.from_user.username
)
if is_new_user:
# Новый пользователь
await message.answer(
f"👋 Привет, {message.from_user.first_name}!\n\n"
f"Я бот для изучения английского языка. Помогу тебе:\n"
f"📚 Пополнять словарный запас (ручное/тематическое/из текста)\n"
f"✍️ Выполнять интерактивные задания\n"
f"💬 Практиковать язык в диалоге с AI\n"
f"📊 Отслеживать свой прогресс\n\n"
f"<b>Команды:</b>\n"
f"• /add [слово] - добавить слово\n"
f"• /words [тема] - тематическая подборка\n"
f"• /import - импорт из текста\n"
f"• /vocabulary - мой словарь\n"
f"• /task - задания\n"
f"• /practice - диалог с AI\n"
f"• /stats - статистика\n"
f"• /settings - настройки\n"
f"• /reminder - напоминания\n"
f"• /help - полная справка",
reply_markup=main_menu_keyboard(),
)
# Предлагаем пройти тест уровня
keyboard = InlineKeyboardMarkup(inline_keyboard=[
[InlineKeyboardButton(text="📊 Пройти тест уровня", callback_data="offer_level_test")],
[InlineKeyboardButton(text="➡️ Пропустить", callback_data="skip_level_test")]
])
await message.answer(
"🎯 <b>Определим твой уровень?</b>\n\n"
"Короткий тест (7 вопросов) поможет подобрать задания под твой уровень.\n"
"Это займёт 2-3 минуты.\n\n"
"Или можешь пропустить и установить уровень вручную позже в /settings",
reply_markup=keyboard
)
else:
# Существующий пользователь
await message.answer(
f"С возвращением, {message.from_user.first_name}! 👋\n\n"
f"Готов продолжить обучение?\n\n"
f"<b>Быстрый доступ:</b>\n"
f"• /vocabulary - посмотреть словарь\n"
f"• /task - получить задание\n"
f"• /practice - практика диалога\n"
f"• /words [тема] - тематическая подборка\n"
f"• /stats - статистика\n"
f"• /help - все команды",
reply_markup=main_menu_keyboard(),
)
@router.message(Command("menu"))
async def cmd_menu(message: Message):
"""Показать клавиатуру с основными командами."""
await message.answer("Главное меню доступно ниже ⤵️", reply_markup=main_menu_keyboard())
@router.message(Command("help"))
async def cmd_help(message: Message):
"""Обработчик команды /help"""
await message.answer(
"<b>📖 Справка по командам:</b>\n\n"
"<b>Управление словарём:</b>\n"
"• /add [слово] - добавить слово в словарь\n"
"• /vocabulary - просмотр словаря\n"
"• /words [тема] - тематическая подборка слов\n"
"• /import - импортировать слова из текста\n\n"
"<b>Обучение:</b>\n"
"• /task - задание (перевод, заполнение пропусков)\n"
"• /practice - диалог с ИИ (6 сценариев)\n"
"• /level_test - тест определения уровня\n\n"
"<b>Статистика:</b>\n"
"• /stats - твой прогресс\n\n"
"<b>Настройки:</b>\n"
"• /settings - уровень и язык\n"
"• /reminder - ежедневные напоминания\n\n"
"💡 Ты также можешь просто отправить мне слово, и я предложу добавить его в словарь!"
)
@router.callback_query(F.data == "offer_level_test")
async def offer_level_test_callback(callback: CallbackQuery, state: FSMContext):
"""Начать тест уровня из приветствия"""
from bot.handlers.level_test import start_level_test
await callback.message.delete()
await start_level_test(callback.message, state)
await callback.answer()
@router.callback_query(F.data == "skip_level_test")
async def skip_level_test_callback(callback: CallbackQuery):
"""Пропустить тест уровня"""
await callback.message.edit_text(
"✅ Хорошо!\n\n"
def main_menu_keyboard() -> ReplyKeyboardMarkup:
"""Клавиатура с основными командами (кнопки отправляют команды)."""
return ReplyKeyboardMarkup(
resize_keyboard=True,
keyboard=[
[
KeyboardButton(text="/add"),
KeyboardButton(text="/vocabulary"),
],
[
KeyboardButton(text="/task"),
KeyboardButton(text="/practice"),
],
[
KeyboardButton(text="/words travel"),
KeyboardButton(text="/import"),
],
[
KeyboardButton(text="/stats"),
KeyboardButton(text="/settings"),
],
],
)
"Ты можешь пройти тест позже командой /level_test\n"
"или установить уровень вручную в /settings\n\n"
"Давай начнём! Попробуй:\n"
"• /words travel - тематическая подборка\n"
"• /practice - диалог с AI\n"
"• /add hello - добавить слово"
)
await callback.answer()