# chat.py import logging from telegram import Update, InputMediaPhoto from telegram.ext import ContextTypes from asgiref.sync import sync_to_async from bot.state import BINDING_PENDING class ChatHandler: def __init__(self, bot): self.bot = bot self.logger = logging.getLogger(__name__) @sync_to_async def get_bot_settings(self): from bot.models import BotConfig settings = BotConfig.objects.first() if settings is None: settings = BotConfig.objects.create(chat_enabled=True) return settings @sync_to_async def get_client_by_telegram_id(self, telegram_id: int): from webapp.models import Client try: return Client.objects.get(telegram_id=str(telegram_id)) except Client.DoesNotExist: return None @sync_to_async def get_all_clients(self): from webapp.models import Client return list(Client.objects.all()) async def broadcast_message(self, sender, message_text: str, photo_media: InputMediaPhoto = None): clients = await self.get_all_clients() for client in clients: if client.telegram_id == sender.telegram_id: continue try: if photo_media: await self.bot.send_photo( chat_id=client.telegram_id, photo=photo_media.media, caption=photo_media.caption, parse_mode="Markdown" ) else: await self.bot.send_message( chat_id=client.telegram_id, text=message_text, parse_mode="Markdown" ) except Exception as e: self.logger.error(f"Ошибка отправки сообщения пользователю {client.telegram_id}: {e}") async def handle_chat_message(self, update: Update, context: ContextTypes.DEFAULT_TYPE): if not update.message: return bot_settings = await self.get_bot_settings() if not bot_settings.chat_enabled: await update.message.reply_text("🚫 Чат временно отключён администрацией.") return chat_id = update.message.chat_id sender = await self.get_client_by_telegram_id(chat_id) # Если пользователь не привязан, но находится в pending, обрабатываем как ввод КК if not sender and chat_id in BINDING_PENDING: # Импортируем функцию process_binding_input из bot.handlers from bot.handlers import process_binding_input await process_binding_input(update, context) return # Если пользователь не привязан и не находится в pending, просим привязаться if not sender: await update.message.reply_text("🚫 Для участия в чате привяжите свою клиентскую карту с помощью /bind") return # Если у пользователя отключена возможность отправки сообщений if getattr(sender, "chat_disabled", False): await update.message.reply_text("🚫 Вы не можете отправлять сообщения. Обратитесь к администратору.") return sender_name = sender.name if sender else "Аноним" broadcast_text = f"💬 *{sender_name} пишет:*\n{update.message.text or ''}" photo_media = None if update.message.photo: photo = update.message.photo[-1] caption = update.message.caption or broadcast_text photo_media = InputMediaPhoto(photo.file_id, caption=caption) await self.broadcast_message(sender, broadcast_text, photo_media)