Files
duty-teller/handlers/commands.py
Nikolay Tatarinov 50347038e9 Implement group duty pinning and user phone management
- Added functionality to pin duty messages in group chats, including scheduling updates and handling bot add/remove events.
- Introduced a new `GroupDutyPin` model to store pinned message details and a `phone` field in the `User` model for user contact information.
- Implemented commands for users to set or clear their phone numbers in private chats.
- Enhanced the repository with functions to manage group duty pins and user phone data.
- Updated handlers to register new commands and manage duty pin updates effectively.
2026-02-18 01:00:31 +03:00

114 lines
4.2 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.

"""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 get_session
from db.repository import get_or_create_user, set_user_phone
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 = (
" ".join(filter(None, [user.first_name or "", user.last_name or ""])).strip()
or "User"
)
telegram_user_id = user.id
username = user.username
first_name = user.first_name
last_name = user.last_name
def do_get_or_create() -> None:
session = get_session(config.DATABASE_URL)
try:
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,
)
finally:
session.close()
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:
session = get_session(config.DATABASE_URL)
try:
full_name = (
" ".join(
filter(
None,
[
update.effective_user.first_name or "",
update.effective_user.last_name or "",
],
)
).strip()
or "User"
)
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 "Телефон очищен."
finally:
session.close()
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)