init commit
This commit is contained in:
92
lottery/bot/chat.py
Normal file
92
lottery/bot/chat.py
Normal file
@@ -0,0 +1,92 @@
|
||||
# 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)
|
||||
Reference in New Issue
Block a user