diff --git a/backend/bot/app/web/admin_api_impl/_runtime.py b/backend/bot/app/web/admin_api_impl/_runtime.py index 041eab0..e0dec2e 100644 --- a/backend/bot/app/web/admin_api_impl/_runtime.py +++ b/backend/bot/app/web/admin_api_impl/_runtime.py @@ -34,7 +34,7 @@ from bot.services.settings_override_service import ( current_value, update_overrides, ) -from bot.utils import MessageContent, send_message_via_queue +from bot.utils import MessageContent, send_message_via_queue, SUPPORTED_PARAMS from bot.utils.message_queue import get_queue_manager from config.settings import Settings from config.tariffs_config import TariffsConfig, default_payment_currency_code_for_settings diff --git a/backend/bot/app/web/admin_api_impl/broadcast.py b/backend/bot/app/web/admin_api_impl/broadcast.py index 986988a..5138eda 100644 --- a/backend/bot/app/web/admin_api_impl/broadcast.py +++ b/backend/bot/app/web/admin_api_impl/broadcast.py @@ -167,11 +167,32 @@ async def admin_broadcast_route(request: web.Request) -> web.Response: payload = await _read_json(request) text = str(payload.get("text") or "").strip() target = str(payload.get("target") or "all").strip().lower() - if not text: - return _error(400, "empty_text") + + # --- НОВЫЕ ПОЛЯ ДЛЯ МЕДИА --- + media_type = payload.get("media_type") # например "photo", "video", "document" и т.д. + media_file_id = payload.get("media_file_id") # file_id или URL (строка) + # --------------------------- + if target not in BROADCAST_TARGETS: target = "all" + # --- ЛОГИКА ФОРМИРОВАНИЯ MessageContent --- + if media_type and media_file_id: + # Отправляем медиа: текст становится подписью (caption) + if media_type not in SUPPORTED_PARAMS: + return _error(400, "unsupported_media_type") + content = MessageContent( + content_type=media_type, + file_id=media_file_id, + text=text, # будет использован как caption + ) + else: + # Текстовое сообщение + if not text: + return _error(400, "empty_text") + content = MessageContent(content_type="text", text=text) + # -------------------------------------- + queue_manager = get_queue_manager() if not queue_manager: return _error(503, "queue_unavailable") @@ -201,10 +222,11 @@ async def admin_broadcast_route(request: web.Request) -> web.Response: failed = 0 for uid in user_ids: try: + # Передаём content (уже с нужным типом), а остальные параметры остаются await send_message_via_queue( queue_manager, int(uid), - MessageContent(content_type="text", text=text), + content, parse_mode="HTML", disable_web_page_preview=True, ) @@ -218,14 +240,13 @@ async def admin_broadcast_route(request: web.Request) -> web.Response: { "user_id": actor_id, "event_type": "admin_broadcast_webapp", - "content": f"target={target} sent={sent} failed={failed} text={text[:120]}", - "is_admin_event": True, + "content": f"target={target} sent={sent} failed={failed} " + f"type={content.content_type} text={text[:120]}", }, ) return _ok({"queued": sent, "failed": failed, "target": target}) - async def admin_broadcast_audience_counts_route(request: web.Request) -> web.Response: """Return how many users each broadcast audience currently resolves to.""" _require_admin_user_id(request)