Telezab/app/bot/processors/subscribe_processor.py
UdoChudo 60f77b39eb feat(subscription): add "subscribe all" and "unsubscribe all" buttons
feat(subscription): add check on unsubscribe to notify user if no active subscriptions

Signed-off-by: UdoChudo <stream@udochudo.ru>
2025-06-19 23:52:48 +05:00

125 lines
5.6 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from telebot.types import Message, InlineKeyboardMarkup, InlineKeyboardButton, MessageID
from app import Regions, Subscriptions
from app.bot.constants import UserStates
from app.bot.keyboards.settings_menu import get_settings_menu
from app.bot.utils.tg_audit import log_user_event
from app.extensions.db import db
def process_subscription_button(message: Message, app, bot, chat_id: int, state_manager, bot_message: MessageID):
parts = [part.strip() for part in message.text.split(',')]
if not parts or not all(part.isdigit() for part in parts):
markup = InlineKeyboardMarkup()
markup.add(InlineKeyboardButton(text="Отмена", callback_data="cancel_input"))
bot.send_message(chat_id,
"❌ Неверный ввод, введите число(а) через запятую, либо нажмите отмена.",
reply_markup=markup)
def delayed_handler(msg):
message_id = msg.message_id
process_subscription_button(msg, app, bot, chat_id, state_manager, message_id)
bot.register_next_step_handler(message, delayed_handler)
return
bot.delete_message(chat_id, bot_message)
region_ids = [int(part) for part in parts]
try:
with app.app_context():
valid_region_ids = [r.region_id for r in Regions.query.filter(Regions.active == True).all()]
subbed_regions = []
invalid_regions = []
for region_id in region_ids:
if region_id not in valid_region_ids:
invalid_regions.append(str(region_id))
continue
subscription = Subscriptions.query.filter_by(chat_id=chat_id, region_id=region_id).first()
if subscription:
if not subscription.active:
subscription.active = True
db.session.add(subscription)
subbed_regions.append(str(region_id))
else:
new_sub = Subscriptions(chat_id=chat_id, region_id=region_id, active=True)
db.session.add(new_sub)
subbed_regions.append(str(region_id))
db.session.commit()
except Exception as e:
bot.send_message(chat_id, "⚠️ Произошла ошибка при обработке запроса. Попробуйте позже.")
return
if invalid_regions:
bot.send_message(chat_id,
f"⚠️ Регион с ID {', '.join(invalid_regions)} не существует. Введите корректные номера или 'отмена'.")
# Можно не менять состояние, чтобы пользователь мог повторить ввод
# И снова ждём ввод:
bot.register_next_step_handler(message, process_subscription_button, bot, chat_id, state_manager)
return
if subbed_regions:
username = f"{message.from_user.username}" if message.from_user.username else "N/A"
log_user_event(chat_id, app, username, f"Подписался на регионы: {', '.join(subbed_regions)}")
# Сбрасываем состояние, чтобы не продолжать ждать ввод
state_manager.set_state(chat_id, UserStates.SETTINGS_MENU)
# Показываем меню
bot.send_message(chat_id, f"✅ Подписка на регионы: {', '.join(subbed_regions)} оформлена.", reply_markup=get_settings_menu())
def process_subscribe_all_regions(call, app, bot, chat_id: int, state_manager):
try:
with app.app_context():
username = f"{call.from_user.username}" if call.from_user.username else "N/A"
# Получаем все активные регионы
active_regions = Regions.query.filter_by(active=True).all()
active_region_ids = {r.region_id for r in active_regions}
# Получаем уже подписанные регионы
existing_subs = Subscriptions.query.filter_by(chat_id=chat_id).all()
existing_region_ids = {sub.region_id for sub in existing_subs if sub.active}
newly_added = []
for region in active_regions:
if region.region_id in existing_region_ids:
continue
existing = next((sub for sub in existing_subs if sub.region_id == region.region_id), None)
if existing:
existing.active = True
db.session.add(existing)
else:
new_sub = Subscriptions(chat_id=chat_id, region_id=region.region_id, active=True)
db.session.add(new_sub)
newly_added.append(str(region.region_id))
db.session.commit()
# Логирование действия
if newly_added:
log_user_event(chat_id, app, username, f"Подписался на все регионы: {', '.join(newly_added)}")
bot.answer_callback_query(call.id)
bot.clear_step_handler_by_chat_id(chat_id)
bot.delete_message(chat_id, call.message.message_id)
bot.send_message(chat_id,
"✅ Вы подписались на все доступные регионы.",
reply_markup=get_settings_menu())
state_manager.set_state(chat_id, UserStates.SETTINGS_MENU)
except Exception as e:
bot.send_message(chat_id, "⚠️ Не удалось выполнить подписку. Попробуйте позже.")