import asyncio import logging import sys from os import getenv from aiogram import Bot, Dispatcher, html, F from aiogram.client.default import DefaultBotProperties from aiogram.enums import ParseMode from aiogram.filters import CommandStart, Command from aiogram.types import Message, InlineKeyboardButton, CallbackQuery from aiogram.fsm.context import FSMContext from aiogram.fsm.state import State, StatesGroup from aiogram.utils.keyboard import InlineKeyboardBuilder from dotenv import load_dotenv from database import Database load_dotenv() TOKEN = getenv("BOT_TOKEN") dp = Dispatcher() db = Database("users.db") # Добавили состояние для ручного ввода сферы class Registration(StatesGroup): waiting_for_sphere = State() waiting_for_custom_sphere = State() # <-- Новое состояние waiting_for_language = State() waiting_for_preferences = State() @dp.message(CommandStart()) async def command_start_handler(message: Message) -> None: builder = InlineKeyboardBuilder() builder.row(InlineKeyboardButton(text="✅ Подписаться", callback_data="subscribe")) builder.row(InlineKeyboardButton(text="📄 Читать оферту", url="https://telegra.ph/Polzovatelskoe-soglashenie-i-Oferta-qwork-parse-bot-03-28")) text = ( "👋 Привет! Я твой персональный агент по Kwork.\n\n" "💻 ⚠️ ВАЖНО: Этот бот предназначен исключительно для IT-специалистов.\n\n" "🔍 Я мониторю биржу 24/7 и мгновенно присылаю тебе свежие заказы.\n\n" "Нажимая кнопку «Подписаться», вы принимаете условия " "публичной оферты." ) await message.answer(text, reply_markup=builder.as_markup(), disable_web_page_preview=True) @dp.message(Command("profile")) async def show_profile(message: Message): user_data = await db.get_user(message.from_user.id) if not user_data or user_data[0] is None: await message.answer("⚠️ Твой профиль еще не настроен. Нажми /start, чтобы начать.") return sphere, lang, prefs = user_data builder = InlineKeyboardBuilder() builder.row(InlineKeyboardButton(text="📝 Редактировать профиль", callback_data="subscribe")) # Используем тот же callback text = ( "👤 Твой профиль IT-специалиста:\n\n" f"🌐 Сфера: {sphere}\n" f"🛠 Стек: {lang}\n" f"⚙️ Предпочтения: {prefs}\n\n" "Хочешь что-то изменить? Нажми кнопку ниже." ) await message.answer(text, reply_markup=builder.as_markup()) @dp.callback_query(F.data == "subscribe") async def subscribe_handler(callback: CallbackQuery, state: FSMContext): await db.add_user(callback.from_user.id) builder = InlineKeyboardBuilder() spheres = ["Backend", "Frontend", "Mobile", "DevOps", "Design", "QA"] for sphere in spheres: builder.add(InlineKeyboardButton(text=sphere, callback_data=f"sphere_{sphere}")) # Добавляем кнопку своего варианта builder.row(InlineKeyboardButton(text="⌨️ Свой вариант", callback_data="sphere_other")) builder.adjust(2) await callback.message.edit_text( "Отлично! Давай настроим профиль.\nВ какой сфере IT ты работаешь?", reply_markup=builder.as_markup() ) await state.set_state(Registration.waiting_for_sphere) await callback.answer() @dp.callback_query(Registration.waiting_for_sphere) async def sphere_chosen(callback: CallbackQuery, state: FSMContext): sphere = callback.data.split("_")[1] if sphere == "other": await callback.message.edit_text("Напиши свою сферу деятельности (например: Data Science или GameDev):") await state.set_state(Registration.waiting_for_custom_sphere) else: await state.update_data(sphere=sphere) await callback.message.edit_text( f"Выбрано: {sphere}\n\nКакой основной язык программирования или стек технологий используешь?" ) await state.set_state(Registration.waiting_for_language) await callback.answer() # Обработчик для текстового ввода своей сферы @dp.message(Registration.waiting_for_custom_sphere) async def custom_sphere_input(message: Message, state: FSMContext): sphere = message.text await state.update_data(sphere=sphere) await message.answer( f"Принято: {sphere}\n\nКакой основной язык программирования или стек технологий используешь?" ) await state.set_state(Registration.waiting_for_language) @dp.message(Registration.waiting_for_language) async def language_chosen(message: Message, state: FSMContext): await state.update_data(language=message.text) # Создаем кнопку для пропуска builder = InlineKeyboardBuilder() builder.row(InlineKeyboardButton(text="⏩ Пропустить", callback_data="skip_preferences")) await message.answer( "Принято! И последнее: напиши свои предпочтения по заказам (фильтры).\n" "Например: 'чек от 5000р' или 'без правок'.\n\n" "Если не хочешь заполнять сейчас, нажми кнопку ниже.", reply_markup=builder.as_markup() ) await state.set_state(Registration.waiting_for_preferences) @dp.callback_query(Registration.waiting_for_preferences, F.data == "skip_preferences") async def skip_preferences(callback: CallbackQuery, state: FSMContext): await state.update_data(preferences="Не указано") # Устанавливаем значение по умолчанию user_data = await state.get_data() await db.update_user_data(callback.from_user.id, user_data) await callback.message.edit_text( "✅ Профиль успешно настроен! (Фильтры пропущены)\n\n" f"Сфера: {user_data['sphere']}\n" f"Стек: {user_data['language']}\n" f"Фильтры: {user_data['preferences']}" ) await state.clear() await callback.answer() async def on_startup(): await db.create_tables() print("Database ready") async def main() -> None: bot = Bot(token=TOKEN, default=DefaultBotProperties(parse_mode=ParseMode.HTML)) dp.startup.register(on_startup) await dp.start_polling(bot) if __name__ == "__main__": logging.basicConfig(level=logging.INFO, stream=sys.stdout) asyncio.run(main())