from telegram import Bot, InlineKeyboardMarkup, InlineKeyboardButton from django.conf import settings from django.core.exceptions import ImproperlyConfigured from urllib.parse import urljoin from bot.models import BotConfig, BotEventMessageConfig import logging from asgiref.sync import sync_to_async from telegram import InputFile import os logger = logging.getLogger(__name__) logger.setLevel(logging.DEBUG) def create_bot_instance(): config = BotConfig.objects.first() if not config: raise ImproperlyConfigured("BotConfig не задан.") logger.debug("Создан экземпляр бота с токеном.") return Bot(token=config.bot_token) def get_event_message_sync(event_key: str, context_vars: dict = None): logger.debug(f"get_event_message_sync для события: {event_key}") try: config = BotEventMessageConfig.objects.select_related("message").get(event=event_key, enabled=True) msg = config.message context_vars = context_vars or {} text = msg.text.format(**context_vars) if msg.text else None image_name = msg.image.name if msg.image else None # только имя файла keyboard = None if msg.buttons_json: keyboard = InlineKeyboardMarkup([ [InlineKeyboardButton(btn["text"], url=btn["url"])] for btn in msg.buttons_json ]) return { "text": text, "image": image_name, "keyboard": keyboard } except Exception as e: logger.error(f"Ошибка get_event_message_sync для события '{event_key}': {e}") return None def send_event_message_sync(event: str, bot: Bot, chat_id: int, context_vars: dict = None): msg = get_event_message_sync(event, context_vars) if not msg: logger.warning(f"Пропущена отправка: шаблон события '{event}' не найден.") return try: if msg["image"]: bot.send_photo(chat_id=chat_id, photo=msg["image"], caption=msg["text"], reply_markup=msg["keyboard"]) elif msg["text"]: bot.send_message(chat_id=chat_id, text=msg["text"], reply_markup=msg["keyboard"]) logger.info(f"Сообщение '{event}' успешно отправлено пользователю {chat_id}") except Exception as e: logger.error(f"Ошибка при отправке сообщения '{event}' пользователю {chat_id}: {e}") @sync_to_async def get_event_message_async(event_key: str, context_vars: dict = None): return get_event_message_sync(event_key, context_vars) async def send_event_message_async(event: str, bot: Bot, chat_id: int, context_vars: dict = None): msg = await get_event_message_async(event, context_vars) if not msg: logger.warning(f"[ASYNC] Пропущена отправка: шаблон события '{event}' не найден.") return try: if msg["image"]: # локальный путь к файлу from django.conf import settings file_path = os.path.join(settings.MEDIA_ROOT, msg["image"]) logger.debug(f"[ASYNC] Отправка фото из {file_path}") with open(file_path, "rb") as photo: await bot.send_photo( chat_id=chat_id, photo=InputFile(photo), caption=msg["text"], reply_markup=msg["keyboard"] ) elif msg["text"]: await bot.send_message( chat_id=chat_id, text=msg["text"], reply_markup=msg["keyboard"] ) logger.info(f"[ASYNC] Сообщение '{event}' отправлено пользователю {chat_id}") except Exception as e: logger.error(f"[ASYNC] Ошибка Telegram при отправке '{event}' пользователю {chat_id}: {e}")