Add captcha functionality to start command handler

- Included captcha router in main handlers.
- Integrated captcha generation in the start command, conditional on CAPTCHA_ENABLE setting.
This commit is contained in:
Zakhar Izmaylov
2025-01-20 22:27:39 +03:00
parent b63c3fb115
commit a9e111bd4f
3 changed files with 86 additions and 0 deletions
+2
View File
@@ -13,11 +13,13 @@ from .payments import router as payments_router
from .profile import router as profile_router
from .start import router as start_router
from .user import router as user_router
from .captcha import router as captcha_router
router = Router(name="handlers_main_router")
router.include_routers(
start_router,
captcha_router,
profile_router,
pay_router,
donate_router,
+76
View File
@@ -0,0 +1,76 @@
import random
from typing import Any
from aiogram import F, Router
from aiogram.fsm.context import FSMContext
from aiogram.types import CallbackQuery
from aiogram.utils.keyboard import InlineKeyboardBuilder
from config import CAPTCHA_EMOJIS
from handlers.start import start_command
from logger import logger
router = Router()
async def generate_captcha(state: FSMContext):
"""Генерирует новую капчу и сохраняет правильный ответ в состоянии
Пример словаря CAPTCHA_EMOJIS:
{
"🐶": "собаку", # Собака
"🐱": "кошку", # Кошка
"🐭": "мышь", # Мышь
"🐹": "хомяка", # Хомяк
"🐰": "кролика", # Кролик
...
}
"""
# Выбираем случайный эмодзи и его описание из конфига
correct_emoji, correct_text = random.choice(list(CAPTCHA_EMOJIS.items()))
# Получаем 3 случайных неправильных эмодзи
wrong_emojis = random.sample(
[e for e in CAPTCHA_EMOJIS.keys() if e != correct_emoji], 3
)
# Создаем список всех эмодзи и перемешиваем их
all_emojis = [correct_emoji] + wrong_emojis
random.shuffle(all_emojis)
# Сохраняем правильный ответ в состоянии
await state.update_data(correct_emoji=correct_emoji)
# Создаем клавиатуру
builder = InlineKeyboardBuilder()
for emoji in all_emojis:
builder.button(text=emoji, callback_data=f"captcha_{emoji}")
builder.adjust(2, 2)
return {
"text": f"🔒 Для подтверждения что вы не робот,\nвыберите кнопку с {correct_text}",
"markup": builder.as_markup()
}
@router.callback_query(F.data.startswith("captcha_"))
async def check_captcha(
callback: CallbackQuery, state: FSMContext, session: Any, admin: bool
):
"""Проверяет ответ пользователя на капчу"""
selected_emoji = callback.data.split("captcha_")[1]
state_data = await state.get_data()
correct_emoji = state_data.get("correct_emoji")
if selected_emoji == correct_emoji:
logger.info(f"Пользователь {callback.message.chat.id} успешно прошел капчу")
await callback.message.delete()
await start_command(callback.message, state, session, admin)
else:
logger.warning(
f"Пользователь {callback.message.chat.id} неверно ответил на капчу"
)
captcha = await generate_captcha(state)
await callback.message.edit_text(
text=captcha["text"], reply_markup=captcha["markup"]
)
+8
View File
@@ -21,6 +21,7 @@ from config import (
DOWNLOAD_ANDROID,
DOWNLOAD_IOS,
SUPPORT_CHAT_URL,
CAPTCHA_ENABLE,
)
from database import (
add_connection,
@@ -41,6 +42,7 @@ from handlers.keys.key_management import create_key
from handlers.keys.trial_key import create_trial_key
from handlers.texts import INSTRUCTIONS_TRIAL, WELCOME_TEXT, get_about_vpn
from logger import logger
from handlers.captcha import generate_captcha
router = Router()
@@ -59,6 +61,12 @@ async def start_command(message: Message, state: FSMContext, session: Any, admin
await state.clear()
# Проверка капчи, если включена
if CAPTCHA_ENABLE:
captcha = await generate_captcha(state)
await message.answer(text=captcha["text"], reply_markup=captcha["markup"])
return
if message.text:
try:
connection_exists = await check_connection_exists(message.chat.id)