Refactored various modules, applied multiple improvements and fixed critical bugs

This commit is contained in:
Vladless
2025-05-08 00:49:50 +03:00
parent 3837f47bb6
commit 6cd1dd8bc2
12 changed files with 107 additions and 78 deletions
+23 -4
View File
@@ -24,11 +24,21 @@ async def generate_captcha(message: Message, state: FSMContext):
all_emojis = [correct_emoji] + wrong_emojis
random.shuffle(all_emojis)
from_user = message.from_user or message.chat
await state.update_data(
correct_emoji=correct_emoji,
message_id=message.message_id,
chat_id=message.chat.id,
original_text=message.text,
user_data={
"tg_id": from_user.id,
"username": getattr(from_user, "username", None),
"first_name": getattr(from_user, "first_name", None),
"last_name": getattr(from_user, "last_name", None),
"language_code": getattr(from_user, "language_code", None),
"is_bot": getattr(from_user, "is_bot", False),
}
)
builder = InlineKeyboardBuilder()
@@ -44,13 +54,15 @@ async def generate_captcha(message: Message, state: FSMContext):
@router.callback_query(F.data.startswith("captcha_"))
async def check_captcha(callback: CallbackQuery, state: FSMContext, session: Any, admin: bool):
from handlers.start import start_command
from handlers.start import process_start_logic
selected_emoji = callback.data.split("captcha_")[1]
state_data = await state.get_data()
correct_emoji = state_data.get("correct_emoji")
message_id = state_data.get("message_id")
chat_id = state_data.get("chat_id")
original_text = state_data.get("original_text")
user_data = state_data.get("user_data")
if not message_id or not chat_id:
target_message = callback.message
@@ -65,10 +77,17 @@ async def check_captcha(callback: CallbackQuery, state: FSMContext, session: Any
target_message = callback.message
if selected_emoji == correct_emoji:
logger.info(f"Пользователь {callback.message.chat.id} успешно прошел капчу")
await start_command(target_message, state, session, admin, captcha=False)
logger.info(f"Пользователь {callback.from_user.id} успешно прошел капчу")
await process_start_logic(
message=target_message,
state=state,
session=session,
admin=admin,
text_to_process=original_text,
user_data=user_data
)
else:
logger.warning(f"Пользователь {callback.message.chat.id} неверно ответил на капчу")
logger.warning(f"Пользователь {callback.from_user.id} неверно ответил на капчу")
captcha = await generate_captcha(target_message, state)
await edit_or_send_message(
target_message=target_message,
+22 -12
View File
@@ -69,7 +69,14 @@ async def process_coupon_code(message: Message, state: FSMContext, session: Any)
await activate_coupon(message, state, session, coupon_code=coupon_code)
async def activate_coupon(message: Message, state: FSMContext, session: Any, coupon_code: str, admin: bool = False):
async def activate_coupon(
message: Message,
state: FSMContext,
session: Any,
coupon_code: str,
admin: bool = False,
user_data: dict | None = None,
):
logger.info(f"Активация купона: {coupon_code}")
coupon_record = await get_coupon_by_code(coupon_code, session)
@@ -84,7 +91,8 @@ async def activate_coupon(message: Message, state: FSMContext, session: Any, cou
await state.clear()
return
user_id = message.chat.id
user = user_data or message.from_user or message.chat
user_id = user["tg_id"] if isinstance(user, dict) else user.id
usage = await check_coupon_usage(coupon_record["id"], user_id, session)
if usage:
@@ -94,16 +102,18 @@ async def activate_coupon(message: Message, state: FSMContext, session: Any, cou
user_exists = await check_user_exists(user_id)
if not user_exists:
from_user = message.from_user
await add_user(
tg_id=from_user.id,
username=from_user.username,
first_name=from_user.first_name,
last_name=from_user.last_name,
language_code=from_user.language_code,
is_bot=from_user.is_bot,
session=session,
)
if isinstance(user, dict):
await add_user(session=session, **user)
else:
await add_user(
tg_id=user.id,
username=getattr(user, "username", None),
first_name=getattr(user, "first_name", None),
last_name=getattr(user, "last_name", None),
language_code=getattr(user, "language_code", None),
is_bot=getattr(user, "is_bot", False),
session=session,
)
if coupon_record["amount"] > 0:
try:
+28 -22
View File
@@ -213,49 +213,55 @@ async def top_referrals_handler(callback_query: CallbackQuery):
await conn.close()
async def handle_referral_link(referral_code: str, message: Message, state: FSMContext, session: Any):
async def handle_referral_link(
referral_code: str,
message: Message,
state: FSMContext,
session: Any,
user_data: dict | None = None,
):
try:
referrer_tg_id = int(referral_code)
user_exists_now = await check_user_exists(message.chat.id)
if referrer_tg_id == message.chat.id:
user = user_data or message.from_user or message.chat
user_id = user["tg_id"] if isinstance(user, dict) else user.id
if referrer_tg_id == user_id:
await message.answer("❌ Вы не можете быть реферальной ссылкой самого себя.")
return
if user_exists_now:
await message.answer("❌ Вы уже зарегистрированы и не можете использовать реферальную ссылку.")
return
existing_referral = await get_referral_by_referred_id(message.chat.id, session)
existing_referral = await get_referral_by_referred_id(user_id, session)
if existing_referral:
await message.answer("❌ Вы уже использовали реферальную ссылку.")
return
await add_referral(message.chat.id, referrer_tg_id, session)
user_exists = await check_user_exists(user_id)
if not user_exists:
if isinstance(user, dict):
await add_user(session=session, **user)
else:
await add_user(
tg_id=user.id,
username=getattr(user, "username", None),
first_name=getattr(user, "first_name", None),
last_name=getattr(user, "last_name", None),
language_code=getattr(user, "language_code", None),
is_bot=getattr(user, "is_bot", False),
session=session,
)
from_user = message.from_user
await add_user(
tg_id=from_user.id,
username=from_user.username,
first_name=from_user.first_name,
last_name=from_user.last_name,
language_code=from_user.language_code,
is_bot=from_user.is_bot,
session=session,
)
await add_referral(user_id, referrer_tg_id, session)
try:
await bot.send_message(
referrer_tg_id,
NEW_REFERRAL_NOTIFICATION.format(referred_id=message.chat.id),
NEW_REFERRAL_NOTIFICATION.format(referred_id=user_id),
)
except Exception as e:
logger.error(f"Не удалось отправить уведомление пригласившему ({referrer_tg_id}): {e}")
await message.answer(REFERRAL_SUCCESS_MSG.format(referrer_tg_id=referrer_tg_id))
return
except Exception as e:
logger.error(f"Ошибка при обработке реферальной ссылки {referral_code}: {e}")
await message.answer("❌ Произошла ошибка при обработке реферальной ссылки.")
return
+33 -39
View File
@@ -137,12 +137,25 @@ async def check_subscription_callback(callback_query: CallbackQuery, state: FSMC
async def process_start_logic(
message: Message, state: FSMContext, session: Any, admin: bool, text_to_process: str = None
message: Message,
state: FSMContext,
session: Any,
admin: bool,
text_to_process: str = None,
user_data: dict | None = None
):
text = text_to_process or message.text or message.caption
user_data = user_data or {
"tg_id": (message.from_user or message.chat).id,
"username": getattr(message.from_user, "username", None),
"first_name": getattr(message.from_user, "first_name", None),
"last_name": getattr(message.from_user, "last_name", None),
"language_code": getattr(message.from_user, "language_code", None),
"is_bot": getattr(message.from_user, "is_bot", False),
}
if not text:
logger.info(f"[StartLogic] Текста нет — вызываю стартовое меню для {message.chat.id}")
logger.info(f"[StartLogic] Текста нет — вызываю стартовое меню для {user_data['tg_id']}")
await show_start_menu(message, admin, session)
return
@@ -159,7 +172,7 @@ async def process_start_logic(
if "coupons" in part:
logger.info(f"Обнаружена ссылка на купон: {part}")
coupon_code = part.split("coupons")[1].strip("_")
await activate_coupon(message, state, session, coupon_code=coupon_code, admin=admin)
await activate_coupon(message, state, session, coupon_code, admin=admin, user_data=user_data)
continue
if "gift" in part:
@@ -172,7 +185,7 @@ async def process_start_logic(
gift_id = parts[0]
sender_id = parts[1]
logger.info(f"[GIFT] Обнаружен подарок {gift_id} от {sender_id}")
await handle_gift_link(gift_id, message, state, session)
await handle_gift_link(gift_id, message, state, session, user_data=user_data)
gift_detected = True
break
@@ -180,34 +193,25 @@ async def process_start_logic(
referrer_tg_id = part.split("referral")[1].strip("_")
try:
referrer_tg_id = int(referrer_tg_id)
await handle_referral_link(referrer_tg_id, message, state, session)
await handle_referral_link(referrer_tg_id, message, state, session, user_data=user_data)
except (ValueError, IndexError):
pass
continue
if "utm" in part:
utm_code = part
logger.info(f"Обнаружена ссылка на UTM: {utm_code}")
await handle_utm_link(utm_code, message, state, session)
logger.info(f"[UTM] Обнаружена ссылка на UTM: {utm_code}")
await handle_utm_link(utm_code, message, state, session, user_data=user_data)
continue
if gift_detected:
return
user_exists = await check_user_exists(message.chat.id)
user_exists = await check_user_exists(user_data["tg_id"])
if not user_exists:
from_user = message.from_user
await add_user(
tg_id=from_user.id,
username=from_user.username,
first_name=from_user.first_name,
last_name=from_user.last_name,
language_code=from_user.language_code,
is_bot=from_user.is_bot,
session=session,
)
await add_user(session=session, **user_data)
trial_status = await get_trial(message.chat.id, session)
trial_status = await get_trial(user_data["tg_id"], session)
if SHOW_START_MENU_ONCE:
if trial_status > 0:
@@ -218,31 +222,22 @@ async def process_start_logic(
await show_start_menu(message, admin, session)
except Exception as e:
logger.error(f"Ошибка при обработке текста {message.text}{e}", exc_info=True)
logger.error(f"Ошибка при обработке текста {text}{e}", exc_info=True)
await message.answer("❌ Произошла ошибка. Попробуйте позже.")
async def handle_utm_link(utm_code, message, state, session):
async def handle_utm_link(utm_code, message, state, session, user_data: dict):
user_id = user_data["tg_id"]
exists = await session.fetchval("SELECT 1 FROM tracking_sources WHERE code = $1", utm_code)
if exists:
current_code = await session.fetchval("SELECT source_code FROM users WHERE tg_id = $1", message.chat.id)
current_code = await session.fetchval("SELECT source_code FROM users WHERE tg_id = $1", user_id)
if current_code is None:
user_exists = await check_user_exists(message.chat.id)
from_user = message.from_user
user_exists = await check_user_exists(user_id)
if not user_exists:
await add_user(
tg_id=from_user.id,
username=from_user.username,
first_name=from_user.first_name,
last_name=from_user.last_name,
language_code=from_user.language_code,
is_bot=from_user.is_bot,
session=session,
source_code=utm_code,
)
await add_user(session=session, source_code=utm_code, **user_data)
else:
await session.execute("UPDATE users SET source_code = $1 WHERE tg_id = $2", utm_code, message.chat.id)
logger.info(f"[UTM] Привязана {utm_code} к пользователю {message.chat.id}")
await session.execute("UPDATE users SET source_code = $1 WHERE tg_id = $2", utm_code, user_id)
logger.info(f"[UTM] Привязана {utm_code} к пользователю {user_id}")
else:
await message.answer("❌ UTM ссылка не найдена.")
@@ -255,17 +250,16 @@ async def show_start_menu(message: Message, admin: bool, session: Any):
image_path = os.path.join("img", "pic.jpg")
builder = InlineKeyboardBuilder()
trial_status = None
if session is not None:
trial_status = await get_trial(message.chat.id, session)
logger.info(f"Trial status для {message.chat.id}: {trial_status}")
if trial_status == 0:
builder.row(InlineKeyboardButton(text=TRIAL_SUB, callback_data="create_key"))
else:
builder.row(InlineKeyboardButton(text=MAIN_MENU, callback_data="profile"))
else:
logger.warning(f"Сессия базы данных отсутствует, пропускаем проверку триала для {message.chat.id}")
if not SHOW_START_MENU_ONCE:
if trial_status != 0 or not SHOW_START_MENU_ONCE:
builder.row(InlineKeyboardButton(text=MAIN_MENU, callback_data="profile"))
if CHANNEL_EXISTS:
+1 -1
View File
File diff suppressed because one or more lines are too long
Binary file not shown.