diff --git a/backend/app/bot/__init__.py b/backend/app/bot/__init__.py index 5cd99ce..9bffcf6 100644 --- a/backend/app/bot/__init__.py +++ b/backend/app/bot/__init__.py @@ -1,19 +1,18 @@ -""" -Bot initialization module. -Creates bot and dispatcher instances. -""" +"""Bot initialization module""" from aiogram import Bot, Dispatcher -from .config import BOT_TOKEN +from .config import settings # Initialize bot and dispatcher -bot = Bot(token=BOT_TOKEN) +bot = Bot(token=settings.bot_token) dp = Dispatcher() async def start_bot(): - """ - Start the bot and include all routers. - This function is called when the application starts. - """ - from .handlers import router # Import here to avoid circular imports - dp.include_router(router) + """Start the bot and include all routers""" + from .handlers import callbacks_router, start_router + + # Include routers + dp.include_router(callbacks_router) + dp.include_router(start_router) + + # Start polling await dp.start_polling(bot, skip_updates=True) \ No newline at end of file diff --git a/backend/app/bot/config.py b/backend/app/bot/config.py index 264bd98..070b17a 100644 --- a/backend/app/bot/config.py +++ b/backend/app/bot/config.py @@ -2,15 +2,24 @@ Configuration module for the Telegram bot. Contains all necessary settings and constants. """ +from pydantic_settings import BaseSettings +from pydantic import Field -# Bot token from environment variables -BOT_TOKEN = "7677506032:AAHduD5EePz3bE23DKlo35KoOp2_9lZuS34" +class Settings(BaseSettings): + """Bot configuration settings""" + bot_token: str = Field("7677506032:AAHduD5EePz3bE23DKlo35KoOp2_9lZuS34", env="TELEGRAM_BOT_TOKEN") + chat_id: str = Field("-1002037023574", env="TELEGRAM_CHAT_ID") -# Chat ID for notifications -NOTIFICATION_CHAT_ID = "-1002037023574" + class Config: + env_file = ".env" + env_file_encoding = "utf-8" + +# Create settings instance +settings = Settings() # Request status constants class RequestStatus: + """Constants for request statuses""" NEW = "new" IN_PROGRESS = "in_progress" COMPLETED = "completed" diff --git a/backend/app/bot/handlers/__init__.py b/backend/app/bot/handlers/__init__.py index c9c2cfd..3e057f0 100644 --- a/backend/app/bot/handlers/__init__.py +++ b/backend/app/bot/handlers/__init__.py @@ -1,2 +1,6 @@ -from .start import dp -from .status import dp +"""Handlers initialization""" +from .callbacks import router as callbacks_router +from .start import router as start_router +from .callbacks import get_updated_keyboard + +__all__ = ['callbacks_router', 'start_router', 'get_updated_keyboard'] \ No newline at end of file diff --git a/backend/app/bot/handlers/callbacks.py b/backend/app/bot/handlers/callbacks.py new file mode 100644 index 0000000..1cd8bfe --- /dev/null +++ b/backend/app/bot/handlers/callbacks.py @@ -0,0 +1,70 @@ +"""Handlers for callback queries""" +from aiogram import Router, types +from aiogram.types import InlineKeyboardMarkup, InlineKeyboardButton +from sqlalchemy.orm import Session +from ...database import get_db +from ... import models +from ..config import RequestStatus + +router = Router() + +@router.callback_query(lambda c: c.data and c.data.startswith('status_')) +async def process_status_button(callback_query: types.CallbackQuery): + """ + Handle status update button clicks. + Updates request status in database and updates message in Telegram. + """ + try: + # Parse callback data + _, request_id, new_status = callback_query.data.split('_') + request_id = int(request_id) + + # Get database session + db = next(get_db()) + + # Update request status + request = db.query(models.Request).filter(models.Request.id == request_id).first() + if request: + request.status = new_status + db.commit() + + # Update message in Telegram + await callback_query.message.edit_text( + f"Заявка №{request_id}\n" + f"Статус: {new_status}\n" + f"Описание: {request.description}", + reply_markup=get_updated_keyboard(request_id, new_status) + ) + + await callback_query.answer("Статус успешно обновлен!") + else: + await callback_query.answer("Заявка не найдена!", show_alert=True) + + except Exception as e: + print(f"Error in process_status_button: {e}") + await callback_query.answer( + "Произошла ошибка при обновлении статуса", + show_alert=True + ) + +def get_updated_keyboard(request_id: int, current_status: str) -> InlineKeyboardMarkup: + """Create keyboard with status update buttons""" + keyboard = InlineKeyboardMarkup(inline_keyboard=[]) + + if current_status != RequestStatus.IN_PROGRESS: + keyboard.inline_keyboard.append([ + InlineKeyboardButton( + text="В работе", + callback_data=f"status_{request_id}_{RequestStatus.IN_PROGRESS}" + ) + ]) + + if current_status != RequestStatus.COMPLETED: + keyboard.inline_keyboard.append([ + InlineKeyboardButton( + text="Завершено", + callback_data=f"status_{request_id}_{RequestStatus.COMPLETED}" + ) + ]) + + return keyboard \ No newline at end of file diff --git a/backend/app/bot/handlers/start.py b/backend/app/bot/handlers/start.py index b07df0f..8cb37ba 100644 --- a/backend/app/bot/handlers/start.py +++ b/backend/app/bot/handlers/start.py @@ -1,12 +1,11 @@ -from aiogram import types -from aiogram.filters import CommandStart -from ..bot import dp +"""Handler for start command and other basic commands""" +from aiogram import Router, types +from aiogram.filters import Command +from ..config import settings +router = Router() -@dp.message(CommandStart()) -async def start_command(message: types.Message): +@router.message(Command("start")) +async def cmd_start(message: types.Message): """Handle /start command""" - await message.answer( - "👋 Привет! Я бот технической поддержки.\n" - "Я буду отправлять уведомления о новых заявках и позволю менять их статус." - ) + await message.answer("Бот для обработки заявок запущен!") \ No newline at end of file diff --git a/backend/app/bot/notifications.py b/backend/app/bot/notifications.py index 71f072d..397f5a4 100644 --- a/backend/app/bot/notifications.py +++ b/backend/app/bot/notifications.py @@ -1,19 +1,10 @@ -""" -Notifications module for the Telegram bot. -Handles sending notifications about new requests and status updates. -""" -from aiogram import types -from .config import NOTIFICATION_CHAT_ID +"""Notifications module for the Telegram bot""" +from .config import settings from . import bot from .handlers import get_updated_keyboard async def send_notification(request_data: dict): - """ - Send notification about new request to Telegram chat. - - Args: - request_data (dict): Request data including id, description, etc. - """ + """Send notification about new request to Telegram chat""" message_text = ( f"Новая заявка №{request_data['id']}\n" f"Отдел: {request_data['department']}\n" @@ -24,7 +15,7 @@ async def send_notification(request_data: dict): try: await bot.send_message( - chat_id=NOTIFICATION_CHAT_ID, + chat_id=settings.chat_id, text=message_text, reply_markup=get_updated_keyboard(request_data['id'], "new") )