diff --git a/handlers/commands.py b/handlers/commands.py index 5e8779a..fa27184 100644 --- a/handlers/commands.py +++ b/handlers/commands.py @@ -1039,17 +1039,18 @@ class BotInterface: interface._menu_msg[uid] = callback.message.message_id await callback.answer() - @dp.callback_query(F.data == "skip_percent") - async def cb_skip_percent(callback: CallbackQuery): + @dp.callback_query(F.data == "skip_twitch_ctr") + async def cb_skip_twitch_ctr(callback: CallbackQuery): uid = callback.from_user.id state = interface._user_task_state.pop(uid, None) - if not state or state.get("step") != "percent": + if not state or state.get("step") != "twitch_ctr": await callback.answer() return interface._menu_msg.pop(uid, None) await callback.message.delete() await interface._create_twitch_task( - callback.message, uid, state["channel"], state["domains"], 0.0 + callback.message, uid, state["channel"], state["domains"], + min_ctr=0.8, max_ctr=1.0 ) await callback.answer() @@ -2815,38 +2816,41 @@ class BotInterface: await self._show_user_tasks(message, user_id) return - # Новая задача — идём к шагу ввода процента зрителей + # Новая задача — идём к шагу ввода CTR if user_id in self._menu_msg: await self._safe_delete(message.bot, message.chat.id, self._menu_msg.pop(user_id)) self._user_task_state[user_id] = { - "step": "percent", + "step": "twitch_ctr", "channel": state["channel"], "domains": domains, } builder = InlineKeyboardBuilder() - builder.row(InlineKeyboardButton(text="⏭️ Без процента", callback_data="skip_percent")) + builder.row(InlineKeyboardButton(text="⏭️ По умолчанию", callback_data="skip_twitch_ctr")) builder.row(InlineKeyboardButton(text="❌ Отмена", callback_data="cancel_new_task")) sent = await message.answer( f"📺 Канал: {state['channel']}\n" f"🌐 Домены: {', '.join(domains)}\n\n" - "Шаг 3/3 — введите % от зрителей для расчёта переходов на ссылку:\n" - "(например: 5 = 5% от текущих зрителей)\n" - "Или нажмите «Без процента» для фиксированного значения", + "Шаг 3/3 — CTR\n\n" + "Введите минимальный и максимальный % от зрителей для расчёта переходов на ссылку\n" + "(например: `0.5-1.5` % от текущих зрителей)", reply_markup=builder.as_markup() ) self._menu_msg[user_id] = sent.message_id - elif state["step"] == "percent": + elif state["step"] == "twitch_ctr": try: - percent = float(text.replace(",", ".")) - if percent <= 0 or percent > 100: + min_ctr, max_ctr = parse_range(text, default_min=1) + if min_ctr <= 0 or max_ctr > 100: raise ValueError - except ValueError: - await self._send_temp(message, "Введите число от 0.1 до 100") + except (ValueError, Exception): + await self._send_temp(message, "❌ Введите диапазон `0.8-1.2` или одно число `1`") return await self._clean_prev(message) del self._user_task_state[user_id] - await self._create_twitch_task(message, user_id, state["channel"], state["domains"], percent) + await self._create_twitch_task( + message, user_id, state["channel"], state["domains"], + min_ctr=min_ctr, max_ctr=max_ctr + ) return # ========================================================================= @@ -2984,7 +2988,8 @@ class BotInterface: async def _create_twitch_task( self, message: Message, user_id: int, - channel: str, domains: list, visits_percent: float + channel: str, domains: list, + min_ctr: float = 0.8, max_ctr: float = 1.0, ): """Создаёт twitch_irc задачу и запускает её.""" balance = await self.balance_storage.get_balance(user_id) @@ -2992,9 +2997,8 @@ class BotInterface: await self._send_temp(message, "Недостаточно переходов") return - # Проверяем статус стрима до создания задачи (None = ошибка запроса → считаем онлайн) viewers = await get_viewer_count(channel) - is_offline = (viewers == 0) # None → не 0 → False → онлайн + is_offline = (viewers == 0) task_id = f"u{user_id}_{channel}_{datetime.now().strftime('%H%M%S')}" params = TaskParams( @@ -3004,9 +3008,8 @@ class BotInterface: allowed_domains=domains, user_id=user_id, visits_per_link=settings.DEFAULT_VISITS_PER_LINK, - visits_percent=visits_percent, - min_ctr=visits_percent if visits_percent > 0 else 0.8, - max_ctr=visits_percent if visits_percent > 0 else 1.0, + min_ctr=min_ctr, + max_ctr=max_ctr, monitor_minutes=0, min_delay=settings.DEFAULT_MIN_DELAY, max_delay=settings.DEFAULT_MAX_DELAY, @@ -3028,13 +3031,14 @@ class BotInterface: if success: if self.storage: await self.storage.save_task(task_id, params) - percent_info = f"\n📊 {visits_percent}% от зрителей" if visits_percent > 0 else "" + ctr_str = f"{min_ctr}%" if min_ctr == max_ctr else f"{min_ctr}–{max_ctr}%" status = f"⏸ Стрим оффлайн — задача на паузе" if is_offline else f"▶️ Онлайн: {viewers} зрителей" await self._send_temp( message, f"✅ Задача создана\n" f"📺 {channel} | 🌐 {', '.join(domains)}\n" - f"{status}{percent_info}", + f"📊 CTR: {ctr_str} от зрителей\n" + f"{status}", delay=6 ) await self._show_user_menu(message, user_id=user_id)