"""Command handlers: /start, /help; /start registers user.""" import asyncio import config from telegram import Update from telegram.ext import CommandHandler, ContextTypes from db.session import session_scope from db.repository import get_or_create_user, set_user_phone from utils.user import build_full_name async def start(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None: if not update.message: return user = update.effective_user if not user: return full_name = build_full_name(user.first_name, user.last_name) telegram_user_id = user.id username = user.username first_name = user.first_name last_name = user.last_name def do_get_or_create() -> None: with session_scope(config.DATABASE_URL) as session: get_or_create_user( session, telegram_user_id=telegram_user_id, full_name=full_name, username=username, first_name=first_name, last_name=last_name, ) await asyncio.get_running_loop().run_in_executor(None, do_get_or_create) text = "Привет! Я бот календаря дежурств. Используй /help для списка команд." await update.message.reply_text(text) async def set_phone(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None: """Set or clear phone for the current user (private chat only).""" if not update.message or not update.effective_user: return if update.effective_chat and update.effective_chat.type != "private": await update.message.reply_text("Команда /set_phone доступна только в личке.") return # Optional: restrict to allowed usernames; plan says "or without restrictions" args = context.args or [] phone = " ".join(args).strip() if args else None telegram_user_id = update.effective_user.id def do_set_phone() -> str: with session_scope(config.DATABASE_URL) as session: full_name = build_full_name( update.effective_user.first_name, update.effective_user.last_name ) get_or_create_user( session, telegram_user_id=telegram_user_id, full_name=full_name, username=update.effective_user.username, first_name=update.effective_user.first_name, last_name=update.effective_user.last_name, ) user = set_user_phone(session, telegram_user_id, phone or None) if user is None: return "Ошибка сохранения." if phone: return f"Телефон сохранён: {phone}" return "Телефон очищен." result = await asyncio.get_running_loop().run_in_executor(None, do_set_phone) await update.message.reply_text(result) async def help_cmd(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None: if not update.message or not update.effective_user: return lines = [ "Доступные команды:", "/start — Начать", "/help — Показать эту справку", "/set_phone — Указать или очистить телефон для отображения в дежурстве", "/pin_duty — В группе: закрепить сообщение о дежурстве (нужны права админа у бота)", ] if config.is_admin(update.effective_user.username or ""): lines.append("/import_duty_schedule — Импорт расписания дежурств (JSON)") await update.message.reply_text("\n".join(lines)) start_handler = CommandHandler("start", start) help_handler = CommandHandler("help", help_cmd) set_phone_handler = CommandHandler("set_phone", set_phone)