Утиита для проверки типа сообщений
This commit is contained in:
613
bot/utils/type_message.py
Normal file
613
bot/utils/type_message.py
Normal file
@@ -0,0 +1,613 @@
|
||||
"""
|
||||
Утилиты для работы с типами контента и чатов
|
||||
"""
|
||||
from typing import Final, Optional, Dict, Any
|
||||
from enum import Enum
|
||||
|
||||
from aiogram.types import Message
|
||||
from aiogram.enums import ContentType, ChatType
|
||||
|
||||
__all__ = (
|
||||
'CHAT_TYPES_RU',
|
||||
'CONTENT_TYPES_RU',
|
||||
'CONTENT_EMOJI',
|
||||
'get_chat_type',
|
||||
'get_content_type',
|
||||
'get_content_text',
|
||||
'get_content_emoji',
|
||||
'get_media_info',
|
||||
'has_media',
|
||||
'has_text',
|
||||
'format_content_info',
|
||||
'ContentCategory',
|
||||
'get_content_category',
|
||||
'is_private_chat',
|
||||
'is_group_chat',
|
||||
'is_channel',
|
||||
'type_msg',
|
||||
'type_chat'
|
||||
)
|
||||
|
||||
# ==================== КОНСТАНТЫ ====================
|
||||
|
||||
# Типы чатов на русском
|
||||
CHAT_TYPES_RU: Final[Dict[str, str]] = {
|
||||
ChatType.PRIVATE: "Личные сообщения",
|
||||
ChatType.GROUP: "Группа",
|
||||
ChatType.SUPERGROUP: "Супергруппа",
|
||||
ChatType.CHANNEL: "Канал",
|
||||
"private": "Личные сообщения",
|
||||
"group": "Группа",
|
||||
"supergroup": "Супергруппа",
|
||||
"channel": "Канал",
|
||||
}
|
||||
|
||||
# Типы контента на русском
|
||||
CONTENT_TYPES_RU: Final[Dict[str, str]] = {
|
||||
# Текст и медиа
|
||||
ContentType.TEXT: "Текст",
|
||||
ContentType.ANIMATION: "GIF анимация",
|
||||
ContentType.AUDIO: "Аудиофайл",
|
||||
ContentType.DOCUMENT: "Документ",
|
||||
ContentType.PHOTO: "Фотография",
|
||||
ContentType.STICKER: "Стикер",
|
||||
ContentType.VIDEO: "Видео",
|
||||
ContentType.VIDEO_NOTE: "Видеосообщение",
|
||||
ContentType.VOICE: "Голосовое сообщение",
|
||||
|
||||
# Контакты и локации
|
||||
ContentType.CONTACT: "Контакт",
|
||||
ContentType.LOCATION: "Геолокация",
|
||||
ContentType.VENUE: "Место на карте",
|
||||
|
||||
# Игры и развлечения
|
||||
ContentType.DICE: "Игральная кость",
|
||||
ContentType.GAME: "Игра",
|
||||
ContentType.POLL: "Опрос",
|
||||
|
||||
# События чата
|
||||
ContentType.NEW_CHAT_MEMBERS: "Новые участники",
|
||||
ContentType.LEFT_CHAT_MEMBER: "Участник покинул чат",
|
||||
ContentType.NEW_CHAT_TITLE: "Изменено название чата",
|
||||
ContentType.NEW_CHAT_PHOTO: "Изменена аватарка чата",
|
||||
ContentType.DELETE_CHAT_PHOTO: "Удалена аватарка чата",
|
||||
ContentType.GROUP_CHAT_CREATED: "Группа создана",
|
||||
ContentType.SUPERGROUP_CHAT_CREATED: "Супергруппа создана",
|
||||
ContentType.CHANNEL_CHAT_CREATED: "Канал создан",
|
||||
ContentType.MESSAGE_AUTO_DELETE_TIMER_CHANGED: "Изменён таймер автоудаления",
|
||||
ContentType.MIGRATE_TO_CHAT_ID: "Миграция в супергруппу",
|
||||
ContentType.MIGRATE_FROM_CHAT_ID: "Миграция из группы",
|
||||
ContentType.PINNED_MESSAGE: "Закреплено сообщение",
|
||||
|
||||
# Платежи
|
||||
ContentType.INVOICE: "Счёт на оплату",
|
||||
ContentType.SUCCESSFUL_PAYMENT: "Успешная оплата",
|
||||
|
||||
# Другое
|
||||
ContentType.CONNECTED_WEBSITE: "Подключён сайт",
|
||||
ContentType.PASSPORT_DATA: "Данные Telegram Passport",
|
||||
ContentType.PROXIMITY_ALERT_TRIGGERED: "Сработал алерт приближения",
|
||||
|
||||
# Видеочаты
|
||||
ContentType.VIDEO_CHAT_SCHEDULED: "Запланирован видеочат",
|
||||
ContentType.VIDEO_CHAT_STARTED: "Начался видеочат",
|
||||
ContentType.VIDEO_CHAT_ENDED: "Завершён видеочат",
|
||||
ContentType.VIDEO_CHAT_PARTICIPANTS_INVITED: "Приглашены в видеочат",
|
||||
|
||||
# Web App
|
||||
ContentType.WEB_APP_DATA: "Данные Web App",
|
||||
|
||||
# Форумы
|
||||
ContentType.FORUM_TOPIC_CREATED: "Создана тема форума",
|
||||
ContentType.FORUM_TOPIC_EDITED: "Изменена тема форума",
|
||||
ContentType.FORUM_TOPIC_CLOSED: "Закрыта тема форума",
|
||||
ContentType.FORUM_TOPIC_REOPENED: "Открыта тема форума",
|
||||
ContentType.GENERAL_FORUM_TOPIC_HIDDEN: "Скрыта общая тема",
|
||||
ContentType.GENERAL_FORUM_TOPIC_UNHIDDEN: "Показана общая тема",
|
||||
|
||||
# Розыгрыши
|
||||
ContentType.GIVEAWAY_CREATED: "Создан розыгрыш",
|
||||
ContentType.GIVEAWAY: "Розыгрыш",
|
||||
ContentType.GIVEAWAY_WINNERS: "Победители розыгрыша",
|
||||
ContentType.GIVEAWAY_COMPLETED: "Завершён розыгрыш",
|
||||
|
||||
# Истории и реакции
|
||||
ContentType.STORY: "История",
|
||||
}
|
||||
|
||||
# Эмодзи для типов контента
|
||||
CONTENT_EMOJI: Final[Dict[str, str]] = {
|
||||
ContentType.TEXT: "💬",
|
||||
ContentType.ANIMATION: "🎞️",
|
||||
ContentType.AUDIO: "🎵",
|
||||
ContentType.DOCUMENT: "📄",
|
||||
ContentType.PHOTO: "📷",
|
||||
ContentType.STICKER: "🎨",
|
||||
ContentType.VIDEO: "🎥",
|
||||
ContentType.VIDEO_NOTE: "🎬",
|
||||
ContentType.VOICE: "🎤",
|
||||
ContentType.CONTACT: "👤",
|
||||
ContentType.LOCATION: "📍",
|
||||
ContentType.VENUE: "🏢",
|
||||
ContentType.DICE: "🎲",
|
||||
ContentType.GAME: "🎮",
|
||||
ContentType.POLL: "📊",
|
||||
ContentType.INVOICE: "💰",
|
||||
ContentType.SUCCESSFUL_PAYMENT: "✅",
|
||||
}
|
||||
|
||||
|
||||
class ContentCategory(str, Enum):
|
||||
"""Категории контента"""
|
||||
TEXT = "text" # Текстовые сообщения
|
||||
MEDIA = "media" # Медиа (фото, видео, и т.д.)
|
||||
FILE = "file" # Файлы и документы
|
||||
VOICE = "voice" # Голосовые сообщения
|
||||
LOCATION = "location" # Локации и места
|
||||
INTERACTION = "interaction" # Игры, опросы, кости
|
||||
SERVICE = "service" # Служебные сообщения
|
||||
PAYMENT = "payment" # Платежи
|
||||
UNKNOWN = "unknown" # Неизвестный тип
|
||||
|
||||
|
||||
# ==================== ОСНОВНЫЕ ФУНКЦИИ ====================
|
||||
|
||||
def get_chat_type(message: Message, russian: bool = True) -> str:
|
||||
"""
|
||||
Возвращает тип чата.
|
||||
|
||||
Args:
|
||||
message: Объект сообщения
|
||||
russian: Вернуть на русском языке
|
||||
|
||||
Returns:
|
||||
str: Тип чата
|
||||
|
||||
Example:
|
||||
>>> get_chat_type(message)
|
||||
'Личные сообщения'
|
||||
>>> get_chat_type(message, russian=False)
|
||||
'private'
|
||||
"""
|
||||
chat_type = message.chat.type
|
||||
|
||||
if russian:
|
||||
return CHAT_TYPES_RU.get(chat_type, f"Неизвестный тип ({chat_type})")
|
||||
|
||||
return chat_type
|
||||
|
||||
|
||||
def get_content_type(message: Message, russian: bool = True) -> str:
|
||||
"""
|
||||
Возвращает тип контента сообщения.
|
||||
|
||||
Args:
|
||||
message: Объект сообщения
|
||||
russian: Вернуть на русском языке
|
||||
|
||||
Returns:
|
||||
str: Тип контента
|
||||
|
||||
Example:
|
||||
>>> get_content_type(message)
|
||||
'Фотография'
|
||||
>>> get_content_type(message, russian=False)
|
||||
'photo'
|
||||
"""
|
||||
content_type = message.content_type
|
||||
|
||||
if russian:
|
||||
return CONTENT_TYPES_RU.get(content_type, f"Неизвестный тип ({content_type})")
|
||||
|
||||
return content_type
|
||||
|
||||
|
||||
def get_content_emoji(message: Message) -> str:
|
||||
"""
|
||||
Возвращает эмодзи для типа контента.
|
||||
|
||||
Args:
|
||||
message: Объект сообщения
|
||||
|
||||
Returns:
|
||||
str: Эмодзи
|
||||
|
||||
Example:
|
||||
>>> get_content_emoji(message)
|
||||
'📷'
|
||||
"""
|
||||
return CONTENT_EMOJI.get(message.content_type, "📎")
|
||||
|
||||
|
||||
def get_content_text(message: Message, max_length: Optional[int] = None) -> Optional[str]:
|
||||
"""
|
||||
Извлекает текст из сообщения (текст или caption).
|
||||
|
||||
Args:
|
||||
message: Объект сообщения
|
||||
max_length: Максимальная длина текста (обрезает если больше)
|
||||
|
||||
Returns:
|
||||
Optional[str]: Текст сообщения или None
|
||||
|
||||
Example:
|
||||
>>> get_content_text(message)
|
||||
'Привет, мир!'
|
||||
|
||||
>>> get_content_text(message) # Фото с подписью
|
||||
'Красивое фото'
|
||||
|
||||
>>> get_content_text(message, max_length=10)
|
||||
'Привет,...'
|
||||
"""
|
||||
text = message.text or message.caption
|
||||
|
||||
if text and max_length and len(text) > max_length:
|
||||
return f"{text[:max_length]}..."
|
||||
|
||||
return text
|
||||
|
||||
|
||||
def has_media(message: Message) -> bool:
|
||||
"""
|
||||
Проверяет, содержит ли сообщение медиа.
|
||||
|
||||
Args:
|
||||
message: Объект сообщения
|
||||
|
||||
Returns:
|
||||
bool: True если есть медиа
|
||||
|
||||
Example:
|
||||
>>> has_media(message)
|
||||
True
|
||||
"""
|
||||
media_types = {
|
||||
ContentType.PHOTO,
|
||||
ContentType.VIDEO,
|
||||
ContentType.ANIMATION,
|
||||
ContentType.AUDIO,
|
||||
ContentType.VOICE,
|
||||
ContentType.VIDEO_NOTE,
|
||||
ContentType.DOCUMENT,
|
||||
ContentType.STICKER
|
||||
}
|
||||
|
||||
return message.content_type in media_types
|
||||
|
||||
|
||||
def has_text(message: Message) -> bool:
|
||||
"""
|
||||
Проверяет, есть ли в сообщении текст (или caption).
|
||||
|
||||
Args:
|
||||
message: Объект сообщения
|
||||
|
||||
Returns:
|
||||
bool: True если есть текст
|
||||
|
||||
Example:
|
||||
>>> has_text(message)
|
||||
True
|
||||
"""
|
||||
return bool(message.text or message.caption)
|
||||
|
||||
|
||||
# ==================== ДЕТАЛЬНАЯ ИНФОРМАЦИЯ О МЕДИА ====================
|
||||
|
||||
def get_media_info(message: Message) -> Dict[str, Any]:
|
||||
"""
|
||||
Возвращает детальную информацию о медиа в сообщении.
|
||||
|
||||
Args:
|
||||
message: Объект сообщения
|
||||
|
||||
Returns:
|
||||
Dict: Словарь с информацией о медиа
|
||||
|
||||
Example:
|
||||
>>> get_media_info(message)
|
||||
{
|
||||
'type': 'photo',
|
||||
'type_ru': 'Фотография',
|
||||
'emoji': '📷',
|
||||
'has_caption': True,
|
||||
'caption': 'Красивое фото',
|
||||
'file_size': 123456,
|
||||
'file_size_mb': 0.12,
|
||||
'width': 1920,
|
||||
'height': 1080,
|
||||
'duration': None
|
||||
}
|
||||
"""
|
||||
info = {
|
||||
'type': message.content_type,
|
||||
'type_ru': get_content_type(message),
|
||||
'emoji': get_content_emoji(message),
|
||||
'has_caption': bool(message.caption),
|
||||
'caption': message.caption,
|
||||
'has_text': bool(message.text),
|
||||
'text': message.text,
|
||||
}
|
||||
|
||||
# Фото
|
||||
if message.photo:
|
||||
largest_photo = max(message.photo, key=lambda p: p.file_size or 0)
|
||||
info.update({
|
||||
'file_id': largest_photo.file_id,
|
||||
'file_unique_id': largest_photo.file_unique_id,
|
||||
'file_size': largest_photo.file_size,
|
||||
'file_size_kb': round(largest_photo.file_size / 1024, 2) if largest_photo.file_size else None,
|
||||
'width': largest_photo.width,
|
||||
'height': largest_photo.height,
|
||||
'count': len(message.photo) # Количество размеров
|
||||
})
|
||||
|
||||
# Видео
|
||||
elif message.video:
|
||||
info.update({
|
||||
'file_id': message.video.file_id,
|
||||
'file_unique_id': message.video.file_unique_id,
|
||||
'file_size': message.video.file_size,
|
||||
'file_size_mb': round(message.video.file_size / (1024 * 1024), 2) if message.video.file_size else None,
|
||||
'width': message.video.width,
|
||||
'height': message.video.height,
|
||||
'duration': message.video.duration,
|
||||
'duration_formatted': _format_duration(message.video.duration) if message.video.duration else None,
|
||||
'mime_type': message.video.mime_type,
|
||||
'file_name': message.video.file_name
|
||||
})
|
||||
|
||||
# Документ
|
||||
elif message.document:
|
||||
info.update({
|
||||
'file_id': message.document.file_id,
|
||||
'file_unique_id': message.document.file_unique_id,
|
||||
'file_size': message.document.file_size,
|
||||
'file_size_mb': round(message.document.file_size / (1024 * 1024),
|
||||
2) if message.document.file_size else None,
|
||||
'file_name': message.document.file_name,
|
||||
'mime_type': message.document.mime_type
|
||||
})
|
||||
|
||||
# Аудио
|
||||
elif message.audio:
|
||||
info.update({
|
||||
'file_id': message.audio.file_id,
|
||||
'file_unique_id': message.audio.file_unique_id,
|
||||
'file_size': message.audio.file_size,
|
||||
'file_size_mb': round(message.audio.file_size / (1024 * 1024), 2) if message.audio.file_size else None,
|
||||
'duration': message.audio.duration,
|
||||
'duration_formatted': _format_duration(message.audio.duration) if message.audio.duration else None,
|
||||
'performer': message.audio.performer,
|
||||
'title': message.audio.title,
|
||||
'mime_type': message.audio.mime_type,
|
||||
'file_name': message.audio.file_name
|
||||
})
|
||||
|
||||
# Голосовое сообщение
|
||||
elif message.voice:
|
||||
info.update({
|
||||
'file_id': message.voice.file_id,
|
||||
'file_unique_id': message.voice.file_unique_id,
|
||||
'file_size': message.voice.file_size,
|
||||
'file_size_kb': round(message.voice.file_size / 1024, 2) if message.voice.file_size else None,
|
||||
'duration': message.voice.duration,
|
||||
'duration_formatted': _format_duration(message.voice.duration) if message.voice.duration else None,
|
||||
'mime_type': message.voice.mime_type
|
||||
})
|
||||
|
||||
# Видеосообщение
|
||||
elif message.video_note:
|
||||
info.update({
|
||||
'file_id': message.video_note.file_id,
|
||||
'file_unique_id': message.video_note.file_unique_id,
|
||||
'file_size': message.video_note.file_size,
|
||||
'file_size_kb': round(message.video_note.file_size / 1024, 2) if message.video_note.file_size else None,
|
||||
'duration': message.video_note.duration,
|
||||
'duration_formatted': _format_duration(
|
||||
message.video_note.duration) if message.video_note.duration else None,
|
||||
'length': message.video_note.length # Диаметр
|
||||
})
|
||||
|
||||
# Анимация (GIF)
|
||||
elif message.animation:
|
||||
info.update({
|
||||
'file_id': message.animation.file_id,
|
||||
'file_unique_id': message.animation.file_unique_id,
|
||||
'file_size': message.animation.file_size,
|
||||
'file_size_mb': round(message.animation.file_size / (1024 * 1024),
|
||||
2) if message.animation.file_size else None,
|
||||
'width': message.animation.width,
|
||||
'height': message.animation.height,
|
||||
'duration': message.animation.duration,
|
||||
'duration_formatted': _format_duration(message.animation.duration) if message.animation.duration else None,
|
||||
'mime_type': message.animation.mime_type,
|
||||
'file_name': message.animation.file_name
|
||||
})
|
||||
|
||||
# Стикер
|
||||
elif message.sticker:
|
||||
info.update({
|
||||
'file_id': message.sticker.file_id,
|
||||
'file_unique_id': message.sticker.file_unique_id,
|
||||
'file_size': message.sticker.file_size,
|
||||
'width': message.sticker.width,
|
||||
'height': message.sticker.height,
|
||||
'is_animated': message.sticker.is_animated,
|
||||
'is_video': message.sticker.is_video,
|
||||
'emoji': message.sticker.emoji,
|
||||
'set_name': message.sticker.set_name
|
||||
})
|
||||
|
||||
return info
|
||||
|
||||
|
||||
def format_content_info(message: Message, include_text: bool = True, max_text_length: int = 50) -> str:
|
||||
"""
|
||||
Форматирует информацию о контенте в читаемую строку.
|
||||
|
||||
Args:
|
||||
message: Объект сообщения
|
||||
include_text: Включать текст/caption в описание
|
||||
max_text_length: Максимальная длина текста
|
||||
|
||||
Returns:
|
||||
str: Отформатированная строка
|
||||
|
||||
Example:
|
||||
>>> format_content_info(message)
|
||||
'📷 Фотография (1920x1080, 123 KB) + "Красивое фото"'
|
||||
|
||||
>>> format_content_info(message)
|
||||
'🎥 Видео (1920x1080, 5.2 MB, 1:30) + "Смотрите это видео"'
|
||||
"""
|
||||
emoji = get_content_emoji(message)
|
||||
content_type = get_content_type(message)
|
||||
|
||||
parts = [f"{emoji} {content_type}"]
|
||||
|
||||
# Добавляем детали медиа
|
||||
if message.photo:
|
||||
largest = max(message.photo, key=lambda p: p.file_size or 0)
|
||||
size_kb = largest.file_size / 1024 if largest.file_size else 0
|
||||
parts.append(f"({largest.width}x{largest.height}, {size_kb:.1f} KB)")
|
||||
|
||||
elif message.video:
|
||||
size_mb = message.video.file_size / (1024 * 1024) if message.video.file_size else 0
|
||||
duration = _format_duration(message.video.duration) if message.video.duration else "?"
|
||||
parts.append(f"({message.video.width}x{message.video.height}, {size_mb:.1f} MB, {duration})")
|
||||
|
||||
elif message.document:
|
||||
size_mb = message.document.file_size / (1024 * 1024) if message.document.file_size else 0
|
||||
file_name = message.document.file_name or "без имени"
|
||||
parts.append(f'("{file_name}", {size_mb:.2f} MB)')
|
||||
|
||||
elif message.audio:
|
||||
duration = _format_duration(message.audio.duration) if message.audio.duration else "?"
|
||||
title = message.audio.title or "без названия"
|
||||
parts.append(f'("{title}", {duration})')
|
||||
|
||||
elif message.voice:
|
||||
duration = _format_duration(message.voice.duration) if message.voice.duration else "?"
|
||||
parts.append(f"({duration})")
|
||||
|
||||
elif message.video_note:
|
||||
duration = _format_duration(message.video_note.duration) if message.video_note.duration else "?"
|
||||
parts.append(f"({duration})")
|
||||
|
||||
elif message.sticker:
|
||||
emoji_text = message.sticker.emoji or ""
|
||||
parts.append(f"({emoji_text})")
|
||||
|
||||
# Добавляем текст/caption
|
||||
if include_text:
|
||||
text = get_content_text(message, max_length=max_text_length)
|
||||
if text:
|
||||
parts.append(f'+ "{text}"')
|
||||
|
||||
return ' '.join(parts)
|
||||
|
||||
|
||||
def get_content_category(message: Message) -> ContentCategory:
|
||||
"""
|
||||
Определяет категорию контента.
|
||||
|
||||
Args:
|
||||
message: Объект сообщения
|
||||
|
||||
Returns:
|
||||
ContentCategory: Категория контента
|
||||
|
||||
Example:
|
||||
>>> get_content_category(message)
|
||||
ContentCategory.MEDIA
|
||||
"""
|
||||
content_type = message.content_type
|
||||
|
||||
# Текст
|
||||
if content_type == ContentType.TEXT:
|
||||
return ContentCategory.TEXT
|
||||
|
||||
# Медиа
|
||||
if content_type in {ContentType.PHOTO, ContentType.VIDEO, ContentType.ANIMATION, ContentType.STICKER}:
|
||||
return ContentCategory.MEDIA
|
||||
|
||||
# Файлы
|
||||
if content_type in {ContentType.DOCUMENT, ContentType.AUDIO}:
|
||||
return ContentCategory.FILE
|
||||
|
||||
# Голосовые
|
||||
if content_type in {ContentType.VOICE, ContentType.VIDEO_NOTE}:
|
||||
return ContentCategory.VOICE
|
||||
|
||||
# Локации
|
||||
if content_type in {ContentType.LOCATION, ContentType.VENUE}:
|
||||
return ContentCategory.LOCATION
|
||||
|
||||
# Интерактивные
|
||||
if content_type in {ContentType.DICE, ContentType.GAME, ContentType.POLL}:
|
||||
return ContentCategory.INTERACTION
|
||||
|
||||
# Платежи
|
||||
if content_type in {ContentType.INVOICE, ContentType.SUCCESSFUL_PAYMENT}:
|
||||
return ContentCategory.PAYMENT
|
||||
|
||||
# Служебные
|
||||
if content_type in {
|
||||
ContentType.NEW_CHAT_MEMBERS,
|
||||
ContentType.LEFT_CHAT_MEMBER,
|
||||
ContentType.NEW_CHAT_TITLE,
|
||||
ContentType.PINNED_MESSAGE
|
||||
}:
|
||||
return ContentCategory.SERVICE
|
||||
|
||||
return ContentCategory.UNKNOWN
|
||||
|
||||
|
||||
# ==================== ВСПОМОГАТЕЛЬНЫЕ ФУНКЦИИ ====================
|
||||
|
||||
def _format_duration(seconds: int) -> str:
|
||||
"""
|
||||
Форматирует длительность в читаемый вид.
|
||||
|
||||
Args:
|
||||
seconds: Длительность в секундах
|
||||
|
||||
Returns:
|
||||
str: Отформатированная строка (MM:SS или HH:MM:SS)
|
||||
|
||||
Example:
|
||||
>>> _format_duration(90)
|
||||
'1:30'
|
||||
>>> _format_duration(3661)
|
||||
'1:01:01'
|
||||
"""
|
||||
hours = seconds // 3600
|
||||
minutes = (seconds % 3600) // 60
|
||||
secs = seconds % 60
|
||||
|
||||
if hours > 0:
|
||||
return f"{hours}:{minutes:02d}:{secs:02d}"
|
||||
else:
|
||||
return f"{minutes}:{secs:02d}"
|
||||
|
||||
|
||||
def is_private_chat(message: Message) -> bool:
|
||||
"""Проверяет, является ли чат личным"""
|
||||
return message.chat.type == ChatType.PRIVATE
|
||||
|
||||
|
||||
def is_group_chat(message: Message) -> bool:
|
||||
"""Проверяет, является ли чат группой"""
|
||||
return message.chat.type in {ChatType.GROUP, ChatType.SUPERGROUP}
|
||||
|
||||
|
||||
def is_channel(message: Message) -> bool:
|
||||
"""Проверяет, является ли чат каналом"""
|
||||
return message.chat.type == ChatType.CHANNEL
|
||||
|
||||
|
||||
# Алиасы для обратной совместимости
|
||||
type_msg = get_content_type
|
||||
type_chat = get_chat_type
|
||||
Reference in New Issue
Block a user