bot prime refactor. Notification events & messages
This commit is contained in:
@@ -1,39 +1,99 @@
|
||||
# bot/utils.py
|
||||
from telegram import Bot
|
||||
from telegram import Bot, InlineKeyboardMarkup, InlineKeyboardButton
|
||||
from django.conf import settings
|
||||
from telegram import Bot
|
||||
from bot.models import BotConfig
|
||||
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():
|
||||
"""
|
||||
Получает настройки бота из БД и создаёт экземпляр Telegram Bot.
|
||||
"""
|
||||
config = BotConfig.objects.first() # предполагается, что конфигурация одна
|
||||
config = BotConfig.objects.first()
|
||||
if not config:
|
||||
raise ImproperlyConfigured("Настройки бота (BotConfig) не сконфигурированы в базе данных.")
|
||||
raise ImproperlyConfigured("BotConfig не задан.")
|
||||
|
||||
# Можно дополнительно использовать config.channel_id и config.bot_name при необходимости.
|
||||
bot = Bot(token=config.bot_token)
|
||||
return bot
|
||||
logger.debug("Создан экземпляр бота с токеном.")
|
||||
return Bot(token=config.bot_token)
|
||||
|
||||
|
||||
def notify_user(binding_request, approved=True):
|
||||
bot_token = settings.BOT_CONFIG.bot_token # можно использовать модель BotConfig или настройку из settings
|
||||
bot = Bot(token=bot_token)
|
||||
message = "Ваша заявка на привязку успешно подтверждена!" if approved else "Ваша заявка на привязку отклонена."
|
||||
def get_event_message_sync(event_key: str, context_vars: dict = None):
|
||||
logger.debug(f"get_event_message_sync для события: {event_key}")
|
||||
try:
|
||||
bot.send_message(chat_id=binding_request.telegram_chat_id, text=message)
|
||||
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:
|
||||
# Обработка ошибок отправки сообщения
|
||||
print(f"Ошибка уведомления: {e}")
|
||||
logger.error(f"Ошибка get_event_message_sync для события '{event_key}': {e}")
|
||||
return None
|
||||
|
||||
|
||||
# Пример использования в точке входа приложения:
|
||||
if __name__ == '__main__':
|
||||
# Предполагается, что Django уже настроен (например, через manage.py shell или management command)
|
||||
bot = create_bot_instance()
|
||||
# Теперь можно использовать объект bot для отправки сообщений, обработки обновлений и т.д.
|
||||
print(f"Бот {bot.name} успешно создан!")
|
||||
|
||||
|
||||
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}")
|
||||
|
||||
Reference in New Issue
Block a user