fix comand
This commit is contained in:
+234
-89
@@ -819,11 +819,14 @@ class BotInterface:
|
||||
f"Текущее: {cur}\n"
|
||||
f"Диапазон `2-5` или фиксированно `3`."
|
||||
)
|
||||
_d_mn = params.min_delay // 60
|
||||
_d_mx = params.max_delay // 60
|
||||
_d_cur = f"{_d_mn}–{_d_mx}" if _d_mn != _d_mx else str(_d_mn)
|
||||
delay_label = (
|
||||
f"⏱️ *Пауза между циклами*\n"
|
||||
f"Сколько секунд ждать после каждого цикла кликов.\n"
|
||||
f"Текущая: {params.min_delay}–{params.max_delay} сек\n"
|
||||
f"Диапазон `30-60` или фиксированно `45`."
|
||||
f"Сколько минут ждать после каждого цикла кликов.\n"
|
||||
f"Текущая: {_d_cur} мин\n"
|
||||
f"Диапазон `2-5` или фиксированно `3`."
|
||||
)
|
||||
else:
|
||||
perlink_label = (
|
||||
@@ -873,12 +876,12 @@ class BotInterface:
|
||||
interface._user_input_state[uid] = {
|
||||
"task_id": task_id,
|
||||
"param": param,
|
||||
"menu_msg_id": callback.message.message_id,
|
||||
}
|
||||
builder = InlineKeyboardBuilder()
|
||||
builder.row(InlineKeyboardButton(text="❌ Отмена", callback_data=f"utask_{task_id}"))
|
||||
sent = await callback.message.answer(prompt, reply_markup=builder.as_markup())
|
||||
interface._user_input_state[uid]["prompt_msg_id"] = sent.message_id
|
||||
await callback.answer(f"Введите значение")
|
||||
await callback.message.edit_text(prompt, reply_markup=builder.as_markup())
|
||||
await callback.answer()
|
||||
|
||||
@dp.callback_query(F.data == "confirm_buy")
|
||||
async def cb_confirm_buy(callback: CallbackQuery):
|
||||
@@ -1036,6 +1039,10 @@ class BotInterface:
|
||||
await interface._show_user_menu(callback.message, user_id=uid)
|
||||
await callback.answer("👤 Переключились в режим пользователя")
|
||||
|
||||
@dp.callback_query(F.data == "noop")
|
||||
async def _cb_noop(callback: CallbackQuery):
|
||||
await callback.answer()
|
||||
|
||||
@dp.callback_query(F.data == "cancel_new_task")
|
||||
async def cb_cancel_new_task(callback: CallbackQuery):
|
||||
uid = callback.from_user.id
|
||||
@@ -1048,6 +1055,16 @@ class BotInterface:
|
||||
await interface._show_user_tasks(callback.message, callback.from_user.id, edit=True)
|
||||
await callback.answer()
|
||||
|
||||
@dp.callback_query(F.data == "my_tasks_visits")
|
||||
async def cb_my_tasks_visits(callback: CallbackQuery):
|
||||
await interface._show_user_visits(callback.message, callback.from_user.id, edit=True)
|
||||
await callback.answer()
|
||||
|
||||
@dp.callback_query(F.data == "my_tasks_monitors")
|
||||
async def cb_my_tasks_monitors(callback: CallbackQuery):
|
||||
await interface._show_user_monitors(callback.message, callback.from_user.id, edit=True)
|
||||
await callback.answer()
|
||||
|
||||
async def _get_user_task(callback: CallbackQuery, tid: str):
|
||||
uid = callback.from_user.id
|
||||
if not interface.auth_manager.is_authenticated(uid):
|
||||
@@ -1690,41 +1707,44 @@ class BotInterface:
|
||||
user_id = message.from_user.id
|
||||
state = self._user_input_state.pop(user_id)
|
||||
|
||||
# Удаляем prompt и ответ пользователя
|
||||
prompt_id = state.get("prompt_msg_id")
|
||||
if prompt_id:
|
||||
await self._safe_delete(message.bot, message.chat.id, prompt_id)
|
||||
await self._safe_delete(message.bot, message.chat.id, message.message_id)
|
||||
|
||||
task_id = state["task_id"]
|
||||
param = state["param"]
|
||||
menu_msg_id = state.get("menu_msg_id")
|
||||
|
||||
value = message.text.strip() if message.text else ""
|
||||
value = value.replace("'", "").replace('"', "").replace("`", "").strip()
|
||||
|
||||
|
||||
logger.info(f"Process param: {param} = {value}")
|
||||
|
||||
|
||||
if not value:
|
||||
await message.answer("❌ Пустое значение. Попробуйте ещё раз.")
|
||||
await self._send_temp(message, "❌ Пустое значение. Попробуйте ещё раз.")
|
||||
return
|
||||
|
||||
|
||||
confirm = ""
|
||||
try:
|
||||
if param == "delay":
|
||||
if "-" in value:
|
||||
mn, mx = parse_range(value)
|
||||
else:
|
||||
mn = mx = int(value)
|
||||
await self.task_manager.update_task(task_id, min_delay=mn, max_delay=mx)
|
||||
await message.answer(f"✅ Задержка: {format_range(mn, mx)}с")
|
||||
|
||||
task_obj = await self.task_manager.get_task(task_id)
|
||||
if task_obj and task_obj.task_type == "user_visit":
|
||||
await self.task_manager.update_task(task_id, min_delay=mn * 60, max_delay=mx * 60)
|
||||
confirm = f"✅ Пауза: {format_range(mn, mx)} мин"
|
||||
else:
|
||||
await self.task_manager.update_task(task_id, min_delay=mn, max_delay=mx)
|
||||
confirm = f"✅ Задержка: {format_range(mn, mx)}с"
|
||||
|
||||
elif param == "reading":
|
||||
if "-" in value:
|
||||
mn, mx = parse_range(value, default_min=1)
|
||||
else:
|
||||
mn = mx = int(value)
|
||||
await self.task_manager.update_task(task_id, min_reading=mn, max_reading=mx)
|
||||
await message.answer(f"✅ Чтение: {format_range(mn, mx)}с")
|
||||
|
||||
confirm = f"✅ Чтение: {format_range(mn, mx)}с"
|
||||
|
||||
elif param == "perlink":
|
||||
params_obj = await self.task_manager.get_task(task_id)
|
||||
if params_obj and params_obj.task_type == "user_visit":
|
||||
@@ -1734,11 +1754,11 @@ class BotInterface:
|
||||
mn = mx = int(value)
|
||||
await self.task_manager.update_task(task_id, min_series=mn, max_series=mx)
|
||||
lbl = f"{mn}–{mx}" if mn != mx else str(mn)
|
||||
await message.answer(f"✅ Цикл: {lbl} кликов")
|
||||
confirm = f"✅ Цикл: {lbl} кликов"
|
||||
else:
|
||||
await self.task_manager.update_task(task_id, visits_per_link=int(value))
|
||||
await message.answer(f"✅ На ссылку: {value}")
|
||||
|
||||
confirm = f"✅ На ссылку: {value}"
|
||||
|
||||
elif param == "ctr":
|
||||
if "-" in value:
|
||||
parts_v = value.split("-", 1)
|
||||
@@ -1750,27 +1770,27 @@ class BotInterface:
|
||||
raise ValueError("CTR должен быть от 0 до 100, например 0.8-1")
|
||||
await self.task_manager.update_task(task_id, min_ctr=mn_c, max_ctr=mx_c)
|
||||
lbl = f"{mn_c}%–{mx_c}%" if mn_c != mx_c else f"{mn_c}%"
|
||||
await message.answer(f"✅ CTR: {lbl}")
|
||||
confirm = f"✅ CTR: {lbl}"
|
||||
|
||||
elif param == "minutes":
|
||||
await self.task_manager.update_task(task_id, monitor_minutes=int(value))
|
||||
await message.answer(f"✅ Мониторинг: {value} мин")
|
||||
|
||||
confirm = f"✅ Мониторинг: {value} мин"
|
||||
|
||||
elif param == "domains":
|
||||
if value.lower() in ["all", "все"]:
|
||||
await self.task_manager.update_task(task_id, allowed_domains=None)
|
||||
await message.answer("✅ Домены: все")
|
||||
confirm = "✅ Домены: все"
|
||||
else:
|
||||
domains = [d.strip().lower() for d in value.split(",") if d.strip()]
|
||||
await self.task_manager.update_task(task_id, allowed_domains=domains)
|
||||
await message.answer(f"✅ Домены: {', '.join(domains)}")
|
||||
confirm = f"✅ Домены: {', '.join(domains)}"
|
||||
|
||||
elif param == "percent":
|
||||
pct = float(value.replace(",", "."))
|
||||
if pct < 0 or pct > 100:
|
||||
raise ValueError("Значение от 0 до 100")
|
||||
await self.task_manager.update_task(task_id, visits_percent=pct)
|
||||
await message.answer(f"✅ % зрителей: {pct}%" if pct > 0 else "✅ % зрителей отключён")
|
||||
confirm = f"✅ % зрителей: {pct}%" if pct > 0 else "✅ % зрителей отключён"
|
||||
|
||||
elif param == "clickdelay":
|
||||
if "-" in value:
|
||||
@@ -1778,27 +1798,93 @@ class BotInterface:
|
||||
else:
|
||||
mn = mx = int(value)
|
||||
await self.task_manager.update_task(task_id, min_click_delay=mn, max_click_delay=mx)
|
||||
await message.answer(f"✅ Задержка между кликами: {format_range(mn, mx)}с")
|
||||
|
||||
elif param == "ctr":
|
||||
if "-" in value:
|
||||
parts_v = value.split("-", 1)
|
||||
mn_c = float(parts_v[0].replace(",", "."))
|
||||
mx_c = float(parts_v[1].replace(",", "."))
|
||||
else:
|
||||
mn_c = mx_c = float(value.replace(",", "."))
|
||||
if not (0 < mn_c <= mx_c <= 100):
|
||||
raise ValueError("CTR должен быть от 0 до 100, например 0.8-1")
|
||||
await self.task_manager.update_task(task_id, min_ctr=mn_c, max_ctr=mx_c)
|
||||
lbl = f"{mn_c}%–{mx_c}%" if mn_c != mx_c else f"{mn_c}%"
|
||||
await message.answer(f"✅ CTR: {lbl}")
|
||||
confirm = f"✅ Задержка между кликами: {format_range(mn, mx)}с"
|
||||
|
||||
else:
|
||||
await message.answer(f"❌ Неизвестный параметр: {param}")
|
||||
|
||||
await self._send_temp(message, f"❌ Неизвестный параметр: {param}")
|
||||
return
|
||||
|
||||
except ValueError as e:
|
||||
await message.answer(f"❌ Ошибка: {e}")
|
||||
await self._send_temp(message, f"❌ Ошибка: {e}")
|
||||
return
|
||||
|
||||
# Обновляем меню с параметрами (заменяем prompt обратно на настройки задачи)
|
||||
updated = await self.task_manager.get_task(task_id)
|
||||
if updated and menu_msg_id:
|
||||
try:
|
||||
await self._rebuild_user_task_menu(
|
||||
message.bot, message.chat.id, menu_msg_id, task_id, updated, confirm
|
||||
)
|
||||
return
|
||||
except Exception:
|
||||
pass
|
||||
await self._send_temp(message, confirm, delay=4)
|
||||
|
||||
async def _rebuild_user_task_menu(
|
||||
self, bot, chat_id: int, msg_id: int,
|
||||
task_id: str, params: TaskParams, confirm: str = ""
|
||||
):
|
||||
"""Редактирует сообщение обратно в настройки задачи после ввода параметра."""
|
||||
if params.task_type == "user_visit":
|
||||
series_range = (
|
||||
f"{params.min_series}–{params.max_series}"
|
||||
if params.min_series != params.max_series
|
||||
else str(params.min_series)
|
||||
)
|
||||
info = (
|
||||
f"🔗 {params.url[:50]}\n"
|
||||
f"📊 Выполнено: {params.successful_visits} из {params.max_visits} переходов\n\n"
|
||||
f"🔢 Кликов в цикле: {series_range}\n"
|
||||
f"⏳ Задержка между кликами: {params.min_click_delay}–{params.max_click_delay} сек\n"
|
||||
f"⏱ Пауза между циклами: {params.min_delay // 60}–{params.max_delay // 60} мин\n"
|
||||
f"📖 Время на странице: {params.min_reading}–{params.max_reading} сек"
|
||||
)
|
||||
else:
|
||||
domains = ", ".join(params.allowed_domains) if params.allowed_domains else "все"
|
||||
ctr_str = (
|
||||
f"{params.min_ctr}%–{params.max_ctr}%"
|
||||
if params.min_ctr != params.max_ctr
|
||||
else f"{params.min_ctr}%"
|
||||
)
|
||||
info = (
|
||||
f"📺 Стример: {params.channel}\n"
|
||||
f"🌐 Домены: {domains}\n\n"
|
||||
f"🔗 Ссылок найдено: {params.links_found}\n"
|
||||
f"✅ Успешных кликов: {params.successful_visits}\n\n"
|
||||
f"📊 CTR: {ctr_str}\n"
|
||||
f"⏱ Пауза между кликами: {params.min_delay}–{params.max_delay} сек\n"
|
||||
f"📖 Время на странице: {params.min_reading}–{params.max_reading} сек"
|
||||
)
|
||||
|
||||
builder = InlineKeyboardBuilder()
|
||||
if params.task_type == "user_visit":
|
||||
builder.row(
|
||||
InlineKeyboardButton(text="⏱️ Пауза (мин)", callback_data=f"uset_{task_id}_delay"),
|
||||
InlineKeyboardButton(text="📖 Время на стр.", callback_data=f"uset_{task_id}_reading"),
|
||||
)
|
||||
builder.row(
|
||||
InlineKeyboardButton(text="🔢 Размер цикла", callback_data=f"uset_{task_id}_perlink"),
|
||||
InlineKeyboardButton(text="⏳ Между кликами", callback_data=f"uset_{task_id}_clickdelay"),
|
||||
)
|
||||
else:
|
||||
builder.row(
|
||||
InlineKeyboardButton(text="⏱️ Пауза (сек)", callback_data=f"uset_{task_id}_delay"),
|
||||
InlineKeyboardButton(text="📖 Время на стр.", callback_data=f"uset_{task_id}_reading"),
|
||||
)
|
||||
builder.row(
|
||||
InlineKeyboardButton(text="📊 % CTR зрителей", callback_data=f"uset_{task_id}_ctr"),
|
||||
InlineKeyboardButton(text="🌐 Домены", callback_data=f"uedit_{task_id}"),
|
||||
)
|
||||
builder.row(InlineKeyboardButton(text="🔙 К задачам", callback_data="my_tasks"))
|
||||
|
||||
prefix = f"{confirm}\n\n" if confirm else ""
|
||||
await bot.edit_message_text(
|
||||
f"{prefix}⚙️ Параметры задачи\n\n{info}",
|
||||
chat_id=chat_id,
|
||||
message_id=msg_id,
|
||||
reply_markup=builder.as_markup()
|
||||
)
|
||||
|
||||
async def _show_user_task_detail(self, callback: CallbackQuery, task_id: str, params: TaskParams):
|
||||
if params.task_type == "user_visit":
|
||||
series_range = (
|
||||
@@ -1811,7 +1897,7 @@ class BotInterface:
|
||||
f"📊 Выполнено: {params.successful_visits} из {params.max_visits} переходов\n\n"
|
||||
f"🔢 Кликов в цикле: {series_range}\n"
|
||||
f"⏳ Задержка между кликами: {params.min_click_delay}–{params.max_click_delay} сек\n"
|
||||
f"⏱ Пауза между циклами: {params.min_delay}–{params.max_delay} сек\n"
|
||||
f"⏱ Пауза между циклами: {params.min_delay // 60}–{params.max_delay // 60} мин\n"
|
||||
f"📖 Время на странице: {params.min_reading}–{params.max_reading} сек"
|
||||
)
|
||||
else:
|
||||
@@ -1838,16 +1924,20 @@ class BotInterface:
|
||||
)
|
||||
|
||||
builder = InlineKeyboardBuilder()
|
||||
builder.row(
|
||||
InlineKeyboardButton(text="⏱️ Пауза (сек)", callback_data=f"uset_{task_id}_delay"),
|
||||
InlineKeyboardButton(text="📖 Время на стр.", callback_data=f"uset_{task_id}_reading"),
|
||||
)
|
||||
if params.task_type == "user_visit":
|
||||
builder.row(
|
||||
InlineKeyboardButton(text="⏱️ Пауза (мин)", callback_data=f"uset_{task_id}_delay"),
|
||||
InlineKeyboardButton(text="📖 Время на стр.", callback_data=f"uset_{task_id}_reading"),
|
||||
)
|
||||
builder.row(
|
||||
InlineKeyboardButton(text="🔢 Размер цикла", callback_data=f"uset_{task_id}_perlink"),
|
||||
InlineKeyboardButton(text="⏳ Между кликами", callback_data=f"uset_{task_id}_clickdelay"),
|
||||
)
|
||||
else:
|
||||
builder.row(
|
||||
InlineKeyboardButton(text="⏱️ Пауза (сек)", callback_data=f"uset_{task_id}_delay"),
|
||||
InlineKeyboardButton(text="📖 Время на стр.", callback_data=f"uset_{task_id}_reading"),
|
||||
)
|
||||
builder.row(
|
||||
InlineKeyboardButton(text="📊 % CTR зрителей", callback_data=f"uset_{task_id}_ctr"),
|
||||
InlineKeyboardButton(text="🌐 Домены", callback_data=f"uedit_{task_id}"),
|
||||
@@ -2146,55 +2236,106 @@ class BotInterface:
|
||||
all_tasks = await self.task_manager.get_all_tasks()
|
||||
user_tasks = {tid: p for tid, p in all_tasks.items() if p.user_id == user_id}
|
||||
|
||||
visits = {tid: p for tid, p in user_tasks.items() if p.task_type == "user_visit"}
|
||||
monitors = {tid: p for tid, p in user_tasks.items() if p.task_type != "user_visit"}
|
||||
|
||||
v_active = sum(1 for p in visits.values() if not p.completed and not p.stopped)
|
||||
m_active = sum(1 for p in monitors.values() if not p.completed and not p.stopped)
|
||||
|
||||
if not user_tasks:
|
||||
text = f"📋 Задачи {str(user_id) if for_admin else ''}\n\nЗадач нет."
|
||||
else:
|
||||
header = f"📋 Задачи пользователя {user_id}\n\n" if for_admin else "📋 Мои задачи\n\n"
|
||||
text = header
|
||||
for tid, p in list(user_tasks.items())[:10]:
|
||||
if p.task_type == "user_visit":
|
||||
text += (
|
||||
f"{p.get_status_emoji()} 🔗 {p.url[:40]}\n"
|
||||
f" ✅ {p.successful_visits}/{p.max_visits} | 📊 {p.total_visits}\n"
|
||||
)
|
||||
else:
|
||||
domains = ", ".join(p.allowed_domains) if p.allowed_domains else "все"
|
||||
text += (
|
||||
f"{p.get_status_emoji()} 📺 {p.channel} — 🌐 {domains}\n"
|
||||
f" 🔗 {p.links_found} | ✅ {p.successful_visits} | 📊 {p.total_visits}\n"
|
||||
)
|
||||
if visits:
|
||||
text += f"🔗 Посещения — {v_active} акт. / {len(visits)} всего\n"
|
||||
if monitors:
|
||||
text += f"📺 Мониторинг — {m_active} акт. / {len(monitors)} всего\n"
|
||||
|
||||
builder = InlineKeyboardBuilder()
|
||||
if for_admin:
|
||||
builder.row(InlineKeyboardButton(text="🔙 К пользователю", callback_data=f"udetail_{user_id}"))
|
||||
else:
|
||||
for tid, p in list(user_tasks.items())[:8]:
|
||||
if p.task_type == "user_visit":
|
||||
domain = extract_domain(p.url)[:18] if p.url else "?"
|
||||
label = f"🔗 {domain}"
|
||||
else:
|
||||
label = f"📺 {p.channel}"
|
||||
if not p.completed and not p.stopped:
|
||||
pause_btn = (
|
||||
InlineKeyboardButton(text="▶️", callback_data=f"uresume_{tid}")
|
||||
if p.paused else
|
||||
InlineKeyboardButton(text="⏸️", callback_data=f"upause_{tid}")
|
||||
)
|
||||
builder.row(
|
||||
InlineKeyboardButton(text=label, callback_data=f"utask_{tid}"),
|
||||
pause_btn,
|
||||
InlineKeyboardButton(text="⚙️", callback_data=f"utask_{tid}"),
|
||||
InlineKeyboardButton(text="🗑️", callback_data=f"ustop_{tid}"),
|
||||
)
|
||||
else:
|
||||
builder.row(InlineKeyboardButton(
|
||||
text=f"🗑️ {label} (завершена)",
|
||||
callback_data=f"ustop_{tid}"
|
||||
))
|
||||
builder.row(
|
||||
InlineKeyboardButton(
|
||||
text=f"🔗 Посещения ({len(visits)})",
|
||||
callback_data="my_tasks_visits"
|
||||
),
|
||||
InlineKeyboardButton(
|
||||
text=f"📺 Мониторинг ({len(monitors)})",
|
||||
callback_data="my_tasks_monitors"
|
||||
),
|
||||
)
|
||||
builder.row(InlineKeyboardButton(text="📝 Новая задача", callback_data="new_task"))
|
||||
builder.row(InlineKeyboardButton(text="🔙 Назад", callback_data="user_menu"))
|
||||
await self._edit_or_send(message, text, builder.as_markup(), edit)
|
||||
|
||||
def _build_task_buttons(self, builder: InlineKeyboardBuilder, tasks: dict):
|
||||
for tid, p in list(tasks.items())[:8]:
|
||||
if p.task_type == "user_visit":
|
||||
domain = extract_domain(p.url)[:16] if p.url else "?"
|
||||
label = f"🔗 {domain}"
|
||||
else:
|
||||
label = f"📺 {p.channel}"
|
||||
if not p.completed and not p.stopped:
|
||||
pause_btn = (
|
||||
InlineKeyboardButton(text="▶️", callback_data=f"uresume_{tid}")
|
||||
if p.paused else
|
||||
InlineKeyboardButton(text="⏸️", callback_data=f"upause_{tid}")
|
||||
)
|
||||
builder.row(
|
||||
InlineKeyboardButton(text=label, callback_data=f"utask_{tid}"),
|
||||
pause_btn,
|
||||
InlineKeyboardButton(text="⚙️", callback_data=f"utask_{tid}"),
|
||||
InlineKeyboardButton(text="🗑️", callback_data=f"ustop_{tid}"),
|
||||
)
|
||||
else:
|
||||
builder.row(InlineKeyboardButton(
|
||||
text=f"🗑️ {label} (завершена)",
|
||||
callback_data=f"ustop_{tid}"
|
||||
))
|
||||
builder.row(InlineKeyboardButton(text="📝 Новая задача", callback_data="new_task"))
|
||||
builder.row(InlineKeyboardButton(text="🔙 Мои задачи", callback_data="my_tasks"))
|
||||
|
||||
async def _show_user_visits(self, message: Message, user_id: int, edit: bool = False):
|
||||
all_tasks = await self.task_manager.get_all_tasks()
|
||||
visits = {
|
||||
tid: p for tid, p in all_tasks.items()
|
||||
if p.user_id == user_id and p.task_type == "user_visit"
|
||||
}
|
||||
if not visits:
|
||||
text = "🔗 Посещения\n\nЗадач нет."
|
||||
else:
|
||||
text = "🔗 Посещения\n\n"
|
||||
for _, p in list(visits.items())[:8]:
|
||||
text += (
|
||||
f"{p.get_status_emoji()} {p.url[:40]}\n"
|
||||
f" ✅ {p.successful_visits}/{p.max_visits} | 📊 {p.total_visits}\n"
|
||||
)
|
||||
builder = InlineKeyboardBuilder()
|
||||
self._build_task_buttons(builder, visits)
|
||||
await self._edit_or_send(message, text, builder.as_markup(), edit)
|
||||
|
||||
async def _show_user_monitors(self, message: Message, user_id: int, edit: bool = False):
|
||||
all_tasks = await self.task_manager.get_all_tasks()
|
||||
monitors = {
|
||||
tid: p for tid, p in all_tasks.items()
|
||||
if p.user_id == user_id and p.task_type != "user_visit"
|
||||
}
|
||||
if not monitors:
|
||||
text = "📺 Мониторинг\n\nЗадач нет."
|
||||
else:
|
||||
text = "📺 Мониторинг\n\n"
|
||||
for _, p in list(monitors.items())[:8]:
|
||||
domains = ", ".join(p.allowed_domains) if p.allowed_domains else "все"
|
||||
text += (
|
||||
f"{p.get_status_emoji()} {p.channel} — {domains}\n"
|
||||
f" 🔗 {p.links_found} | ✅ {p.successful_visits} | 📊 {p.total_visits}\n"
|
||||
)
|
||||
builder = InlineKeyboardBuilder()
|
||||
self._build_task_buttons(builder, monitors)
|
||||
await self._edit_or_send(message, text, builder.as_markup(), edit)
|
||||
|
||||
async def _process_user_task_input(self, message: Message):
|
||||
user_id = message.from_user.id
|
||||
state = self._user_task_state[user_id]
|
||||
@@ -2303,18 +2444,22 @@ class BotInterface:
|
||||
sent = await message.answer(
|
||||
f"✅ Цикл: {series_label} кликов\n\n"
|
||||
"Шаг 4/4 — таймаут между циклами (в минутах)\n\n"
|
||||
"Введите одно число, например `3` — пауза 3 минуты.",
|
||||
"`3` — ровно 3 минуты.\n"
|
||||
"`2-5` — случайно от 2 до 5 минут.",
|
||||
reply_markup=builder.as_markup()
|
||||
)
|
||||
self._menu_msg[user_id] = sent.message_id
|
||||
|
||||
elif state["step"] == "delay":
|
||||
try:
|
||||
mn_d = mx_d = int(text)
|
||||
if "-" in text:
|
||||
mn_d, mx_d = parse_range(text, default_min=1)
|
||||
else:
|
||||
mn_d = mx_d = int(text)
|
||||
if mn_d < 1:
|
||||
raise ValueError
|
||||
except Exception:
|
||||
await self._send_temp(message, "Введите целое число минут, например: `3`")
|
||||
await self._send_temp(message, "Введите число или диапазон минут, например: `3` или `2-5`")
|
||||
return
|
||||
|
||||
del self._user_task_state[user_id]
|
||||
@@ -2325,7 +2470,7 @@ class BotInterface:
|
||||
mn = state["min_series"]
|
||||
mx = state["max_series"]
|
||||
series_label = f"{mn}–{mx}" if mn != mx else str(mn)
|
||||
delay_label = str(mn_d)
|
||||
delay_label = f"{mn_d}–{mx_d}" if mn_d != mx_d else str(mn_d)
|
||||
|
||||
task_id = f"u{user_id}_{extract_domain(url)[:12]}_{datetime.now().strftime('%H%M%S')}"
|
||||
params = TaskParams(
|
||||
|
||||
Reference in New Issue
Block a user