Enhance message sending functionality to filter unsupported parameters
- Introduced a `SUPPORTED_PARAMS` dictionary to define valid parameters for each message type. - Added a `filter_kwargs` utility function to filter out unsupported parameters based on the content type. - Updated `send_message_by_type`, `send_message_via_queue`, and `send_direct_message` functions to utilize the new filtering logic, ensuring only valid parameters are passed during message sending. - Improved handling for unknown content types by sending a default text message.
This commit is contained in:
+66
-32
@@ -1,7 +1,7 @@
|
|||||||
# Bot utilities package
|
# Bot utilities package
|
||||||
|
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
from typing import Optional
|
from typing import Optional, Dict, Any
|
||||||
from aiogram import types
|
from aiogram import types
|
||||||
|
|
||||||
|
|
||||||
@@ -13,6 +13,26 @@ class MessageContent:
|
|||||||
text: Optional[str] = None
|
text: Optional[str] = None
|
||||||
|
|
||||||
|
|
||||||
|
# Словари поддерживаемых параметров для каждого типа сообщения
|
||||||
|
SUPPORTED_PARAMS = {
|
||||||
|
"text": {"parse_mode", "entities", "disable_web_page_preview", "disable_notification", "protect_content", "reply_markup", "reply_to_message_id", "allow_sending_without_reply", "message_thread_id"},
|
||||||
|
"photo": {"caption", "parse_mode", "caption_entities", "disable_notification", "protect_content", "reply_markup", "reply_to_message_id", "allow_sending_without_reply", "message_thread_id", "has_spoiler"},
|
||||||
|
"video": {"duration", "width", "height", "thumbnail", "caption", "parse_mode", "caption_entities", "supports_streaming", "disable_notification", "protect_content", "reply_markup", "reply_to_message_id", "allow_sending_without_reply", "message_thread_id", "has_spoiler"},
|
||||||
|
"animation": {"duration", "width", "height", "thumbnail", "caption", "parse_mode", "caption_entities", "disable_notification", "protect_content", "reply_markup", "reply_to_message_id", "allow_sending_without_reply", "message_thread_id", "has_spoiler"},
|
||||||
|
"document": {"thumbnail", "caption", "parse_mode", "caption_entities", "disable_content_type_detection", "disable_notification", "protect_content", "reply_markup", "reply_to_message_id", "allow_sending_without_reply", "message_thread_id"},
|
||||||
|
"audio": {"caption", "parse_mode", "caption_entities", "duration", "performer", "title", "thumbnail", "disable_notification", "protect_content", "reply_markup", "reply_to_message_id", "allow_sending_without_reply", "message_thread_id"},
|
||||||
|
"voice": {"caption", "parse_mode", "caption_entities", "duration", "disable_notification", "protect_content", "reply_markup", "reply_to_message_id", "allow_sending_without_reply", "message_thread_id"},
|
||||||
|
"sticker": {"disable_notification", "protect_content", "reply_markup", "reply_to_message_id", "allow_sending_without_reply", "message_thread_id"},
|
||||||
|
"video_note": {"duration", "length", "thumbnail", "disable_notification", "protect_content", "reply_markup", "reply_to_message_id", "allow_sending_without_reply", "message_thread_id"},
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def filter_kwargs(content_type: str, kwargs: Dict[str, Any]) -> Dict[str, Any]:
|
||||||
|
"""Фильтрует kwargs, оставляя только поддерживаемые параметры для данного типа сообщения"""
|
||||||
|
supported = SUPPORTED_PARAMS.get(content_type, set())
|
||||||
|
return {k: v for k, v in kwargs.items() if k in supported}
|
||||||
|
|
||||||
|
|
||||||
def get_message_content(message: types.Message) -> MessageContent:
|
def get_message_content(message: types.Message) -> MessageContent:
|
||||||
"""
|
"""
|
||||||
Определяет тип контента сообщения и возвращает его данные.
|
Определяет тип контента сообщения и возвращает его данные.
|
||||||
@@ -53,76 +73,79 @@ async def send_message_by_type(bot, chat_id: int, content: MessageContent, **kwa
|
|||||||
"""
|
"""
|
||||||
Отправляет сообщение указанного типа.
|
Отправляет сообщение указанного типа.
|
||||||
Использует match/case вместо длинных if-elif цепочек.
|
Использует match/case вместо длинных if-elif цепочек.
|
||||||
|
Автоматически фильтрует неподдерживаемые параметры.
|
||||||
"""
|
"""
|
||||||
|
# Фильтруем kwargs для данного типа сообщения
|
||||||
|
filtered_kwargs = filter_kwargs(content.content_type, kwargs)
|
||||||
|
|
||||||
match content.content_type:
|
match content.content_type:
|
||||||
case "text":
|
case "text":
|
||||||
await bot.send_message(
|
await bot.send_message(
|
||||||
chat_id=chat_id,
|
chat_id=chat_id,
|
||||||
text=content.text,
|
text=content.text,
|
||||||
**kwargs
|
**filtered_kwargs
|
||||||
)
|
)
|
||||||
case "photo":
|
case "photo":
|
||||||
await bot.send_photo(
|
await bot.send_photo(
|
||||||
chat_id=chat_id,
|
chat_id=chat_id,
|
||||||
photo=content.file_id,
|
photo=content.file_id,
|
||||||
caption=content.text or None,
|
caption=content.text or None,
|
||||||
**kwargs
|
**filtered_kwargs
|
||||||
)
|
)
|
||||||
case "video":
|
case "video":
|
||||||
await bot.send_video(
|
await bot.send_video(
|
||||||
chat_id=chat_id,
|
chat_id=chat_id,
|
||||||
video=content.file_id,
|
video=content.file_id,
|
||||||
caption=content.text or None,
|
caption=content.text or None,
|
||||||
**kwargs
|
**filtered_kwargs
|
||||||
)
|
)
|
||||||
case "animation":
|
case "animation":
|
||||||
await bot.send_animation(
|
await bot.send_animation(
|
||||||
chat_id=chat_id,
|
chat_id=chat_id,
|
||||||
animation=content.file_id,
|
animation=content.file_id,
|
||||||
caption=content.text or None,
|
caption=content.text or None,
|
||||||
**kwargs
|
**filtered_kwargs
|
||||||
)
|
)
|
||||||
case "document":
|
case "document":
|
||||||
await bot.send_document(
|
await bot.send_document(
|
||||||
chat_id=chat_id,
|
chat_id=chat_id,
|
||||||
document=content.file_id,
|
document=content.file_id,
|
||||||
caption=content.text or None,
|
caption=content.text or None,
|
||||||
**kwargs
|
**filtered_kwargs
|
||||||
)
|
)
|
||||||
case "audio":
|
case "audio":
|
||||||
await bot.send_audio(
|
await bot.send_audio(
|
||||||
chat_id=chat_id,
|
chat_id=chat_id,
|
||||||
audio=content.file_id,
|
audio=content.file_id,
|
||||||
caption=content.text or None,
|
caption=content.text or None,
|
||||||
**kwargs
|
**filtered_kwargs
|
||||||
)
|
)
|
||||||
case "voice":
|
case "voice":
|
||||||
await bot.send_voice(
|
await bot.send_voice(
|
||||||
chat_id=chat_id,
|
chat_id=chat_id,
|
||||||
voice=content.file_id,
|
voice=content.file_id,
|
||||||
caption=content.text or None,
|
caption=content.text or None,
|
||||||
**kwargs
|
**filtered_kwargs
|
||||||
)
|
)
|
||||||
case "sticker":
|
case "sticker":
|
||||||
await bot.send_sticker(
|
await bot.send_sticker(
|
||||||
chat_id=chat_id,
|
chat_id=chat_id,
|
||||||
sticker=content.file_id,
|
sticker=content.file_id,
|
||||||
# stickers не поддерживают caption - удаляем его из kwargs
|
**filtered_kwargs
|
||||||
**{k: v for k, v in kwargs.items() if k != 'caption'}
|
|
||||||
)
|
)
|
||||||
case "video_note":
|
case "video_note":
|
||||||
await bot.send_video_note(
|
await bot.send_video_note(
|
||||||
chat_id=chat_id,
|
chat_id=chat_id,
|
||||||
video_note=content.file_id,
|
video_note=content.file_id,
|
||||||
# video_note не поддерживает caption - удаляем его из kwargs
|
**filtered_kwargs
|
||||||
**{k: v for k, v in kwargs.items() if k != 'caption'}
|
|
||||||
)
|
)
|
||||||
case _:
|
case _:
|
||||||
# Fallback для неизвестных типов
|
# Fallback для неизвестных типов - отправляем как текст
|
||||||
|
text_kwargs = filter_kwargs("text", kwargs)
|
||||||
await bot.send_message(
|
await bot.send_message(
|
||||||
chat_id=chat_id,
|
chat_id=chat_id,
|
||||||
text=content.text or "Unknown content type",
|
text=content.text or "Unknown content type",
|
||||||
**{k: v for k, v in kwargs.items() if k != 'caption'}
|
**text_kwargs
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -130,48 +153,53 @@ async def send_message_via_queue(queue_manager, uid: int, content: MessageConten
|
|||||||
"""
|
"""
|
||||||
Отправляет сообщение через очередь в зависимости от типа контента.
|
Отправляет сообщение через очередь в зависимости от типа контента.
|
||||||
Использует match/case вместо длинных if-elif цепочек.
|
Использует match/case вместо длинных if-elif цепочек.
|
||||||
|
Автоматически фильтрует неподдерживаемые параметры.
|
||||||
"""
|
"""
|
||||||
|
# Фильтруем kwargs для данного типа сообщения
|
||||||
|
filtered_kwargs = filter_kwargs(content.content_type, kwargs)
|
||||||
|
|
||||||
match content.content_type:
|
match content.content_type:
|
||||||
case "text":
|
case "text":
|
||||||
await queue_manager.send_message(
|
await queue_manager.send_message(
|
||||||
chat_id=uid, text=content.text, **kwargs
|
chat_id=uid, text=content.text, **filtered_kwargs
|
||||||
)
|
)
|
||||||
case "photo":
|
case "photo":
|
||||||
await queue_manager.send_photo(
|
await queue_manager.send_photo(
|
||||||
chat_id=uid, photo=content.file_id, caption=content.text or None, **kwargs
|
chat_id=uid, photo=content.file_id, caption=content.text or None, **filtered_kwargs
|
||||||
)
|
)
|
||||||
case "video":
|
case "video":
|
||||||
await queue_manager.send_video(
|
await queue_manager.send_video(
|
||||||
chat_id=uid, video=content.file_id, caption=content.text or None, **kwargs
|
chat_id=uid, video=content.file_id, caption=content.text or None, **filtered_kwargs
|
||||||
)
|
)
|
||||||
case "animation":
|
case "animation":
|
||||||
await queue_manager.send_animation(
|
await queue_manager.send_animation(
|
||||||
chat_id=uid, animation=content.file_id, caption=content.text or None, **kwargs
|
chat_id=uid, animation=content.file_id, caption=content.text or None, **filtered_kwargs
|
||||||
)
|
)
|
||||||
case "document":
|
case "document":
|
||||||
await queue_manager.send_document(
|
await queue_manager.send_document(
|
||||||
chat_id=uid, document=content.file_id, caption=content.text or None, **kwargs
|
chat_id=uid, document=content.file_id, caption=content.text or None, **filtered_kwargs
|
||||||
)
|
)
|
||||||
case "audio":
|
case "audio":
|
||||||
await queue_manager.send_audio(
|
await queue_manager.send_audio(
|
||||||
chat_id=uid, audio=content.file_id, caption=content.text or None, **kwargs
|
chat_id=uid, audio=content.file_id, caption=content.text or None, **filtered_kwargs
|
||||||
)
|
)
|
||||||
case "voice":
|
case "voice":
|
||||||
await queue_manager.send_voice(
|
await queue_manager.send_voice(
|
||||||
chat_id=uid, voice=content.file_id, caption=content.text or None, **kwargs
|
chat_id=uid, voice=content.file_id, caption=content.text or None, **filtered_kwargs
|
||||||
)
|
)
|
||||||
case "sticker":
|
case "sticker":
|
||||||
await queue_manager.send_sticker(
|
await queue_manager.send_sticker(
|
||||||
chat_id=uid, sticker=content.file_id
|
chat_id=uid, sticker=content.file_id, **filtered_kwargs
|
||||||
)
|
)
|
||||||
case "video_note":
|
case "video_note":
|
||||||
await queue_manager.send_video_note(
|
await queue_manager.send_video_note(
|
||||||
chat_id=uid, video_note=content.file_id
|
chat_id=uid, video_note=content.file_id, **filtered_kwargs
|
||||||
)
|
)
|
||||||
case _:
|
case _:
|
||||||
# Fallback для неизвестных типов
|
# Fallback для неизвестных типов - отправляем как текст
|
||||||
|
text_kwargs = filter_kwargs("text", kwargs)
|
||||||
await queue_manager.send_message(
|
await queue_manager.send_message(
|
||||||
chat_id=uid, text=content.text or "Unknown content type", **kwargs
|
chat_id=uid, text=content.text or "Unknown content type", **text_kwargs
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -179,45 +207,51 @@ async def send_direct_message(bot, chat_id: int, content: MessageContent, extra_
|
|||||||
"""
|
"""
|
||||||
Отправляет прямое сообщение с дополнительной обработкой для sticker и video_note.
|
Отправляет прямое сообщение с дополнительной обработкой для sticker и video_note.
|
||||||
Для этих типов медиа отправляется отдельное текстовое сообщение, т.к. они не поддерживают caption.
|
Для этих типов медиа отправляется отдельное текстовое сообщение, т.к. они не поддерживают caption.
|
||||||
|
Автоматически фильтрует неподдерживаемые параметры.
|
||||||
"""
|
"""
|
||||||
match content.content_type:
|
match content.content_type:
|
||||||
case "sticker":
|
case "sticker":
|
||||||
# Отправляем стикер
|
# Отправляем стикер с отфильтрованными параметрами
|
||||||
|
sticker_kwargs = filter_kwargs("sticker", kwargs)
|
||||||
await bot.send_sticker(
|
await bot.send_sticker(
|
||||||
chat_id=chat_id,
|
chat_id=chat_id,
|
||||||
sticker=content.file_id,
|
sticker=content.file_id,
|
||||||
**{k: v for k, v in kwargs.items() if k != 'caption'}
|
**sticker_kwargs
|
||||||
)
|
)
|
||||||
# Если есть текст с подписью, отправляем отдельно
|
# Если есть текст с подписью, отправляем отдельно
|
||||||
if content.text or extra_text:
|
if content.text or extra_text:
|
||||||
text_to_send = (content.text + extra_text) if content.text else extra_text
|
text_to_send = (content.text + extra_text) if content.text else extra_text
|
||||||
|
text_kwargs = filter_kwargs("text", kwargs)
|
||||||
await bot.send_message(
|
await bot.send_message(
|
||||||
chat_id,
|
chat_id,
|
||||||
text_to_send,
|
text_to_send,
|
||||||
**{k: v for k, v in kwargs.items() if k not in ['caption']}
|
**text_kwargs
|
||||||
)
|
)
|
||||||
case "video_note":
|
case "video_note":
|
||||||
# Отправляем видео-заметку
|
# Отправляем видео-заметку с отфильтрованными параметрами
|
||||||
|
video_note_kwargs = filter_kwargs("video_note", kwargs)
|
||||||
await bot.send_video_note(
|
await bot.send_video_note(
|
||||||
chat_id=chat_id,
|
chat_id=chat_id,
|
||||||
video_note=content.file_id,
|
video_note=content.file_id,
|
||||||
**{k: v for k, v in kwargs.items() if k != 'caption'}
|
**video_note_kwargs
|
||||||
)
|
)
|
||||||
# Если есть текст с подписью, отправляем отдельно
|
# Если есть текст с подписью, отправляем отдельно
|
||||||
if content.text or extra_text:
|
if content.text or extra_text:
|
||||||
text_to_send = (content.text + extra_text) if content.text else extra_text
|
text_to_send = (content.text + extra_text) if content.text else extra_text
|
||||||
|
text_kwargs = filter_kwargs("text", kwargs)
|
||||||
await bot.send_message(
|
await bot.send_message(
|
||||||
chat_id,
|
chat_id,
|
||||||
text_to_send,
|
text_to_send,
|
||||||
**{k: v for k, v in kwargs.items() if k not in ['caption']}
|
**text_kwargs
|
||||||
)
|
)
|
||||||
case "text":
|
case "text":
|
||||||
# Для текста объединяем с extra_text
|
# Для текста объединяем с extra_text
|
||||||
final_text = (content.text + extra_text) if content.text else extra_text
|
final_text = (content.text + extra_text) if content.text else extra_text
|
||||||
|
text_kwargs = filter_kwargs("text", kwargs)
|
||||||
await bot.send_message(
|
await bot.send_message(
|
||||||
chat_id=chat_id,
|
chat_id=chat_id,
|
||||||
text=final_text,
|
text=final_text,
|
||||||
**kwargs
|
**text_kwargs
|
||||||
)
|
)
|
||||||
case _:
|
case _:
|
||||||
# Для остальных типов медиа используем caption
|
# Для остальных типов медиа используем caption
|
||||||
|
|||||||
Reference in New Issue
Block a user