Files

98 lines
3.8 KiB
Python

from __future__ import annotations
from aiogram import Bot, types
from aiogram.utils.keyboard import InlineKeyboardBuilder
from sqlalchemy import update
from sqlalchemy.ext.asyncio import AsyncSession, async_sessionmaker
from config import NOTIFY_EXTRA_DAYS, NOTIFY_INACTIVE
from core.bootstrap import NOTIFICATIONS_CONFIG
from database import add_notification, check_notifications_bulk
from database.models import User
from database.tariffs import get_tariffs
from handlers.buttons import MAIN_MENU, TRIAL_BONUS
from handlers.notifications.sender import send_messages_with_limit
from handlers.texts import TRIAL_INACTIVE_BONUS_MSG, TRIAL_INACTIVE_FIRST_MSG
from handlers.utils import format_days
from logger import logger
async def process_inactive_trial(
bot: Bot,
session: AsyncSession,
*,
sessionmaker: async_sessionmaker | None = None,
):
inactive_hours = int(NOTIFICATIONS_CONFIG.get("INACTIVE_USER_ENABLED", NOTIFY_INACTIVE))
extra_days = int(NOTIFICATIONS_CONFIG.get("EXTRA_DAYS_AFTER_EXPIRY", NOTIFY_EXTRA_DAYS))
if inactive_hours <= 0:
return
users = await check_notifications_bulk(session, "inactive_trial", inactive_hours)
if not users:
return
logger.info(f"[InactiveTrial] {len(users)} неактивных пользователей")
trial_tariffs = await get_tariffs(session, group_code="trial")
if not trial_tariffs:
logger.error("[InactiveTrial] Триальный тариф не найден")
return
trial_days = trial_tariffs[0]["duration_days"]
messages = []
users_to_extend = []
for user in users:
tg_id = user["tg_id"]
display_name = user["username"] or user["first_name"] or user["last_name"] or "Пользователь"
builder = InlineKeyboardBuilder()
builder.row(types.InlineKeyboardButton(text=TRIAL_BONUS, callback_data="create_key"))
builder.row(types.InlineKeyboardButton(text=MAIN_MENU, callback_data="profile"))
keyboard = builder.as_markup()
trial_extended = user["last_notification_time"] is not None
if trial_extended and extra_days > 0:
total_days = extra_days + trial_days
message = TRIAL_INACTIVE_BONUS_MSG.format(
display_name=display_name,
extra_days_formatted=format_days(extra_days),
total_days_formatted=format_days(total_days),
)
users_to_extend.append(tg_id)
else:
message = TRIAL_INACTIVE_FIRST_MSG.format(
display_name=display_name,
trial_time_formatted=format_days(trial_days),
)
messages.append({
"tg_id": tg_id,
"text": message,
"keyboard": keyboard,
"notification_id": "inactive_trial",
})
if users_to_extend:
await session.execute(update(User).where(User.tg_id.in_(users_to_extend)).values(trial=-1))
logger.info(f"[InactiveTrial] {len(users_to_extend)} пользователей с расширенным триалом")
if messages:
results = await send_messages_with_limit(bot, messages, messages_per_second=25)
sent_tg_ids = [msg["tg_id"] for msg, result in zip(messages, results, strict=False) if result]
if sent_tg_ids:
if sessionmaker is not None:
async with sessionmaker() as fresh_session:
for tg_id in sent_tg_ids:
await add_notification(fresh_session, tg_id, "inactive_trial")
await fresh_session.commit()
else:
for tg_id in sent_tg_ids:
await add_notification(session, tg_id, "inactive_trial")
logger.info(f"[InactiveTrial] Отправлено {len(sent_tg_ids)} уведомлений")