Явное принятие согласия
This commit is contained in:
@@ -71,8 +71,6 @@ docker compose up -d --build
|
|||||||
|
|
||||||
Везде используются inline-кнопки. При этом кнопки под старыми сообщениями автоматически удаляются.
|
Везде используются inline-кнопки. При этом кнопки под старыми сообщениями автоматически удаляются.
|
||||||
|
|
||||||
История сообщений остаётся в чате с ботом. UX не строится на редактировании сообщений.
|
|
||||||
|
|
||||||
В первую очередь пользователям предлагается озвучить дорожки, которые никто ещё не начал озвучивать. Затем те дорожки, которые кто-то начал озвучивать, но ещё не закончил. И топлько потом дорожки, для которых уже озвучка. Тем не менее, одна дорожка может быть озвучена несколькими дикторами.
|
В первую очередь пользователям предлагается озвучить дорожки, которые никто ещё не начал озвучивать. Затем те дорожки, которые кто-то начал озвучивать, но ещё не закончил. И топлько потом дорожки, для которых уже озвучка. Тем не менее, одна дорожка может быть озвучена несколькими дикторами.
|
||||||
|
|
||||||
## Администрирование
|
## Администрирование
|
||||||
|
|||||||
6
main.py
6
main.py
@@ -49,8 +49,12 @@ def main() -> None:
|
|||||||
app.add_handler(CommandHandler("start", start_command))
|
app.add_handler(CommandHandler("start", start_command))
|
||||||
app.add_handler(CommandHandler("admin", admin_command))
|
app.add_handler(CommandHandler("admin", admin_command))
|
||||||
|
|
||||||
|
# Message handlers для текстовых ответов (должны быть перед остальными)
|
||||||
|
app.add_handler(
|
||||||
|
MessageHandler(filters.TEXT & ~filters.COMMAND, handle_accept_intro)
|
||||||
|
)
|
||||||
|
|
||||||
# Callback query handlers
|
# Callback query handlers
|
||||||
app.add_handler(CallbackQueryHandler(handle_accept_intro, pattern="^accept_intro$"))
|
|
||||||
app.add_handler(
|
app.add_handler(
|
||||||
CallbackQueryHandler(handle_select_gender, pattern="^select_gender:")
|
CallbackQueryHandler(handle_select_gender, pattern="^select_gender:")
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,4 +1,11 @@
|
|||||||
from telegram import InlineKeyboardButton, InlineKeyboardMarkup, Update
|
from telegram import (
|
||||||
|
InlineKeyboardButton,
|
||||||
|
InlineKeyboardMarkup,
|
||||||
|
KeyboardButton,
|
||||||
|
ReplyKeyboardMarkup,
|
||||||
|
ReplyKeyboardRemove,
|
||||||
|
Update,
|
||||||
|
)
|
||||||
from telegram.ext import ContextTypes
|
from telegram.ext import ContextTypes
|
||||||
|
|
||||||
from src.config import ADMIN_LOGIN
|
from src.config import ADMIN_LOGIN
|
||||||
@@ -40,7 +47,18 @@ INTRO_TEXT = """👋 Добро пожаловать!
|
|||||||
📋 Отправляя голосовые сообщения, вы соглашаетесь с тем, что они будут
|
📋 Отправляя голосовые сообщения, вы соглашаетесь с тем, что они будут
|
||||||
использованы в исследовательских целях для обучения моделей машинного обучения.
|
использованы в исследовательских целях для обучения моделей машинного обучения.
|
||||||
|
|
||||||
Нажмите кнопку ниже, чтобы начать."""
|
|
||||||
|
Для продолжения отправьте сообщение:
|
||||||
|
|
||||||
|
```
|
||||||
|
Принимаю условия
|
||||||
|
```
|
||||||
|
"""
|
||||||
|
|
||||||
|
ACCEPT_TEXT = "Принимаю условия"
|
||||||
|
INVALID_INTRO_RESPONSE = (
|
||||||
|
f'❌ Для продолжения нажмите кнопку или отправьте: "{ACCEPT_TEXT}"'
|
||||||
|
)
|
||||||
|
|
||||||
SPECIFY_GENDER_TEXT = """👤 Укажите ваш пол.
|
SPECIFY_GENDER_TEXT = """👤 Укажите ваш пол.
|
||||||
|
|
||||||
@@ -76,15 +94,11 @@ REPEAT_REPLICA_TEXT = "🔄 Перезапись реплики {num}/{total}:"
|
|||||||
# === Клавиатуры ===
|
# === Клавиатуры ===
|
||||||
|
|
||||||
|
|
||||||
def get_intro_keyboard() -> InlineKeyboardMarkup:
|
def get_intro_keyboard() -> ReplyKeyboardMarkup:
|
||||||
return InlineKeyboardMarkup(
|
return ReplyKeyboardMarkup(
|
||||||
[
|
[[KeyboardButton(ACCEPT_TEXT)]],
|
||||||
[
|
resize_keyboard=True,
|
||||||
InlineKeyboardButton(
|
one_time_keyboard=True,
|
||||||
"✅ Принять и продолжить", callback_data="accept_intro"
|
|
||||||
)
|
|
||||||
]
|
|
||||||
]
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -315,10 +329,10 @@ async def start_command(update: Update, context: ContextTypes.DEFAULT_TYPE) -> N
|
|||||||
session = get_user_session(user.id) or create_new_session(user.id)
|
session = get_user_session(user.id) or create_new_session(user.id)
|
||||||
|
|
||||||
session.state = UserState.INTRO
|
session.state = UserState.INTRO
|
||||||
msg_id = await send_message_and_save(
|
session.last_bot_message_id = None
|
||||||
update, context, session, INTRO_TEXT, get_intro_keyboard()
|
await update.message.reply_text(
|
||||||
|
INTRO_TEXT, reply_markup=get_intro_keyboard(), parse_mode="Markdown"
|
||||||
)
|
)
|
||||||
session.last_bot_message_id = msg_id
|
|
||||||
upsert_user_session(session)
|
upsert_user_session(session)
|
||||||
logger.info(f"User {user.id} started bot")
|
logger.info(f"User {user.id} started bot")
|
||||||
|
|
||||||
@@ -350,20 +364,37 @@ async def admin_command(update: Update, context: ContextTypes.DEFAULT_TYPE) -> N
|
|||||||
# === Callback handlers ===
|
# === Callback handlers ===
|
||||||
|
|
||||||
|
|
||||||
@answer_callback
|
|
||||||
@with_user_and_session
|
@with_user_and_session
|
||||||
@require_state(UserState.INTRO)
|
|
||||||
async def handle_accept_intro(
|
async def handle_accept_intro(
|
||||||
update: Update, context: ContextTypes.DEFAULT_TYPE, user: User, session: UserSession
|
update: Update,
|
||||||
|
context: ContextTypes.DEFAULT_TYPE,
|
||||||
|
user: User,
|
||||||
|
session: UserSession | None,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Обработчик кнопки 'Принять и продолжить'."""
|
"""Обработчик согласия с условиями."""
|
||||||
query = update.callback_query
|
if not session or session.state != UserState.INTRO:
|
||||||
session.state = UserState.SPECIFY_GENDER
|
return # Пропускаем, следующий обработчик обработает
|
||||||
await query.edit_message_text(
|
|
||||||
SPECIFY_GENDER_TEXT, reply_markup=get_specify_gender_keyboard()
|
text = update.message.text.strip()
|
||||||
|
|
||||||
|
if text != ACCEPT_TEXT:
|
||||||
|
await update.message.reply_text(INVALID_INTRO_RESPONSE)
|
||||||
|
return
|
||||||
|
|
||||||
|
# Удаляем reply-клавиатуру
|
||||||
|
await update.message.reply_text(
|
||||||
|
"✅ Отлично!",
|
||||||
|
reply_markup=ReplyKeyboardRemove(),
|
||||||
)
|
)
|
||||||
session.last_bot_message_id = query.message.message_id
|
|
||||||
|
session.state = UserState.SPECIFY_GENDER
|
||||||
|
msg = await update.message.reply_text(
|
||||||
|
SPECIFY_GENDER_TEXT,
|
||||||
|
reply_markup=get_specify_gender_keyboard(),
|
||||||
|
)
|
||||||
|
session.last_bot_message_id = msg.message_id
|
||||||
upsert_user_session(session)
|
upsert_user_session(session)
|
||||||
|
logger.info(f"User {user.id} accepted intro")
|
||||||
|
|
||||||
|
|
||||||
@answer_callback
|
@answer_callback
|
||||||
@@ -597,7 +628,9 @@ async def handle_exit_admin(
|
|||||||
|
|
||||||
# Показываем соответствующее сообщение
|
# Показываем соответствующее сообщение
|
||||||
if session.state == UserState.INTRO:
|
if session.state == UserState.INTRO:
|
||||||
await query.edit_message_text(INTRO_TEXT, reply_markup=get_intro_keyboard())
|
await query.edit_message_text(
|
||||||
|
INTRO_TEXT, reply_markup=get_intro_keyboard(), parse_mode="Markdown"
|
||||||
|
)
|
||||||
elif session.state == UserState.SPECIFY_GENDER:
|
elif session.state == UserState.SPECIFY_GENDER:
|
||||||
await query.edit_message_text(
|
await query.edit_message_text(
|
||||||
SPECIFY_GENDER_TEXT, reply_markup=get_specify_gender_keyboard()
|
SPECIFY_GENDER_TEXT, reply_markup=get_specify_gender_keyboard()
|
||||||
|
|||||||
Reference in New Issue
Block a user