Telezab/backend_bot.py
UdoChudo 52e31864b3 feat: Develop web interface
- Implemented the initial version of the web interface.
refactor: Begin Telegram bot refactoring
- Started restructuring the bot’s code for better maintainability.
chore: Migrate to Flask project structure
- Reorganized the application to follow Flask's project structure.
cleanup: Extensive code cleanup
- Removed redundant code and improved readability.

Signed-off-by: UdoChudo <stream@udochudo.ru>
2025-06-10 14:39:11 +05:00

199 lines
9.2 KiB
Python
Raw 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.

import telebot
import telezab
from app import app
from backend_locks import bot
from bot_database import is_whitelisted, format_regions_list, get_sorted_regions, log_user_event, \
get_user_subscribed_regions
from app.models import Regions, Subscriptions
from app.extensions.db import db
from utilities.telegram_utilities import show_main_menu, show_settings_menu
from handlers import handle_my_subscriptions_button, handle_active_regions_button, handle_notification_mode_button
def handle_main_menu(message, chat_id, text):
"""Обработка команд в главном меню."""
if text == 'Регистрация':
telezab.state.set_state(chat_id, "REGISTRATION")
telezab.handle_register(message)
elif text == 'Настройки':
telezab.state.set_state(chat_id, "SETTINGS_MENU")
telezab.show_settings_menu(chat_id)
elif text == 'Помощь':
telezab.handle_help(message)
elif text == 'Активные события':
telezab.handle_active_triggers(message)
else:
bot.send_message(chat_id, "Команда не распознана.")
show_main_menu(chat_id)
def handle_settings_menu(message, chat_id, text):
"""Обработка команд в меню настроек."""
if text.lower() == 'подписаться':
telezab.state.set_state(chat_id, "SUBSCRIBE")
handle_subscribe_button(message)
elif text.lower() == 'отписаться':
telezab.state.set_state(chat_id, "UNSUBSCRIBE")
handle_unsubscribe_button(message)
elif text.lower() == 'мои подписки':
handle_my_subscriptions_button(message)
elif text.lower() == 'активные регионы':
handle_active_regions_button(message)
elif text.lower() == "режим уведомлений":
handle_notification_mode_button(message)
elif text.lower() == 'назад':
telezab.state.set_state(chat_id, "MAIN_MENU")
show_main_menu(chat_id)
else:
bot.send_message(chat_id, "Команда не распознана.")
show_settings_menu(chat_id)
def handle_subscribe_button(message):
chat_id = message.chat.id
if not is_whitelisted(chat_id):
bot.send_message(chat_id, "Вы не авторизованы для использования этого бота.")
return
username = message.from_user.username
if username:
username = f"@{username}"
else:
username = "N/A"
regions_list = format_regions_list(get_sorted_regions())
markup = telebot.types.InlineKeyboardMarkup()
markup.add(telebot.types.InlineKeyboardButton(text="Отмена",
callback_data=f"cancel_action"))
bot.send_message(chat_id, f"Отправьте номера регионов через запятую:\n{regions_list}\n", reply_markup=markup)
bot.register_next_step_handler_by_chat_id(chat_id, process_subscription_button, chat_id, username)
def process_subscription_button(message, chat_id, username):
subbed_regions = []
invalid_regions = []
if message.text.lower() == 'отмена':
bot.send_message(chat_id, "Действие отменено.")
telezab.state.set_state(chat_id, "SETTINGS_MENU")
return show_settings_menu(chat_id)
if not all(part.strip().isdigit() for part in message.text.split(',')):
markup = telebot.types.InlineKeyboardMarkup()
markup.add(telebot.types.InlineKeyboardButton(text="Отмена",
callback_data=f"cancel_action"))
bot.send_message(chat_id, "Неверный формат данных. Введите номер или номера регионов через запятую.",
reply_markup=markup)
bot.register_next_step_handler_by_chat_id(chat_id, process_subscription_button, chat_id, username)
return
region_ids = [int(part.strip()) for part in message.text.split(',')]
with app.app_context():
# Получаем список валидных ID регионов из базы
valid_region_ids = [r.region_id for r in Regions.query.filter(Regions.active == True).all()]
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:
# Уже подписан, можно тоже добавить для отчета
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()
if invalid_regions:
bot.send_message(chat_id, f"Регион с ID {', '.join(invalid_regions)} не существует. Введите корректные номера или 'отмена'.")
if subbed_regions:
bot.send_message(chat_id, f"Подписка на регионы: {', '.join(subbed_regions)} оформлена.")
log_user_event(chat_id, username, f"Subscribed to regions: {', '.join(subbed_regions)}")
telezab.state.set_state(chat_id, "SETTINGS_MENU")
show_settings_menu(chat_id)
def handle_unsubscribe_button(message):
chat_id = message.chat.id
if not is_whitelisted(chat_id):
bot.send_message(chat_id, "Вы не авторизованы для использования этого бота.")
telebot.logger.info(f"Unauthorized access attempt by {chat_id}")
telezab.state.set_state(chat_id, "REGISTRATION")
return show_main_menu(chat_id)
username = message.from_user.username
if username:
username = f"@{username}"
else:
username = "N/A"
# Получаем список подписок пользователя
user_regions = get_user_subscribed_regions(chat_id)
if not user_regions:
bot.send_message(chat_id, "Вы не подписаны ни на один регион.")
telezab.state.set_state(chat_id, "SETTINGS_MENU")
return show_settings_menu(chat_id)
regions_list = format_regions_list(user_regions)
markup = telebot.types.InlineKeyboardMarkup()
markup.add(telebot.types.InlineKeyboardButton(text="Отмена", callback_data=f"cancel_action"))
bot.send_message(chat_id,
f"Отправьте номер или номера регионов, от которых хотите отписаться (через запятую):\n{regions_list}\n",
reply_markup=markup)
bot.register_next_step_handler_by_chat_id(chat_id, process_unsubscription_button, chat_id, username)
def process_unsubscription_button(message, chat_id, username):
unsubbed_regions = []
invalid_regions = []
markup = telebot.types.InlineKeyboardMarkup()
markup.add(telebot.types.InlineKeyboardButton(text="Отмена", callback_data="cancel_action"))
if message.text.lower() == 'отмена':
bot.send_message(chat_id, "Действие отменено.")
telezab.state.set_state(chat_id, "SETTINGS_MENU")
return show_settings_menu(chat_id)
# Проверка корректности формата ввода
if not all(part.strip().isdigit() for part in message.text.split(',')):
bot.send_message(chat_id, "Некорректный формат. Введите номера регионов через запятую.", reply_markup=markup)
bot.register_next_step_handler_by_chat_id(chat_id, process_unsubscription_button, chat_id, username)
return
region_ids = [region_id.strip() for region_id in message.text.split(',')]
with app.app_context():
valid_region_ids = [str(region[0]) for region in get_user_subscribed_regions(chat_id)] # get_user_subscribed_regions уже внутри app_context
for region_id in region_ids:
if region_id not in valid_region_ids:
invalid_regions.append(region_id)
continue
subscription = db.session.query(Subscriptions).filter_by(
chat_id=chat_id,
region_id=int(region_id)
).first()
if subscription:
subscription.active = False
unsubbed_regions.append(region_id)
db.session.commit()
if invalid_regions:
bot.send_message(chat_id, f"Регион(ы) с ID {', '.join(invalid_regions)} не найдены в ваших подписках.")
bot.send_message(chat_id, f"Отписка от регионов: {', '.join(unsubbed_regions)} выполнена.")
log_user_event(chat_id, username, f"Unsubscribed from regions: {', '.join(unsubbed_regions)}")
telezab.state.set_state(chat_id, "SETTINGS_MENU")
show_settings_menu(chat_id)