100 lines
3.9 KiB
Python
100 lines
3.9 KiB
Python
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}")
|