При отправки медиагруппы (несколько фото + текст) бот предложки отправляет каждое фото(видео) отдельно. А мне нужно, чтобы вместе) как исправить то?
вот код:
import logging
import time
import uuid
import asyncio
from telegram import Update, InlineKeyboardButton, InlineKeyboardMarkup, InputMediaPhoto
from telegram.ext import Application, MessageHandler, filters, CallbackQueryHandler, CommandHandler, ContextTypes
from cryptography.fernet import Fernet
# Загрузка зашифрованного токена и ключа из файла
with open('config.txt', 'r') as file:
key = file.readline().strip()
encrypted_token = file.readline().strip()
# Обработчик команды /start
async def start(update: Update, context: ContextTypes.DEFAULT_TYPE):
await update.message.reply_text("Хай! Кидайте свои мемы, новости, обзоры и всяческие приколмбасы, без ПorNo, иначе BAN.")
# Обработчик сообщений от пользователей
async def handle_message(update: Update, context: ContextTypes.DEFAULT_TYPE):
try:
logger.info("Received a message")
if update.message:
user_id = update.message.from_user.id
# Проверка на забаненного пользователя
if user_id in banned_users:
await update.message.reply_text("Вы заблокированы и не можете отправлять сообщения.")
return
# Ограничение частоты сообщений (защита от DDoS)
current_time = time.time()
if user_id in user_message_times:
if current_time - user_message_times[user_id] < 0.1: # 0.1 секунд между сообщениями
await update.message.reply_text("Вы отправляете сообщения слишком часто. Подождите немного.")
return
user_message_times[user_id] = current_time
username = update.message.from_user.username or update.message.from_user.full_name or "NoUsername"
message = update.message
logger.info(f"Message from user {user_id} ({username})")
# Генерация уникального идентификатора для каждого сообщения
message_id = str(uuid.uuid4())
# Сохранение сообщения
if user_id not in user_messages:
user_messages[user_id] = {}
user_messages[user_id][message_id] = message
# Уведомление пользователя о получении сообщения
await update.message.reply_text("Ваше сообщение отправлено Кумяшу.")
# Пересылка сообщения админу
caption = message.caption or message.text or ""
forward_message = f"{caption}\n\nОт пользователя: {username}"
if message.photo:
logger.info(f"Photo message from user {user_id} ({username})")
photos = message.photo
media = [InputMediaPhoto(photo.file_id, caption=(forward_message if i == 0 else None)) for i, photo in enumerate(photos)]
await context.bot.send_media_group(chat_id=ADMIN_ID, media=media, reply_markup=get_admin_keyboard(encoded_user_id, encoded_message_id))
elif message.video:
logger.info(f"Video message from user {user_id} ({username})")
await context.bot.send_video(chat_id=ADMIN_ID, video=message.video.file_id, caption=forward_message, reply_markup=get_admin_keyboard(encoded_user_id, encoded_message_id))
elif message.document:
logger.info(f"Document message from user {user_id} ({username})")
await context.bot.send_document(chat_id=ADMIN_ID, document=message.document.file_id, caption=forward_message, reply_markup=get_admin_keyboard(encoded_user_id, encoded_message_id))
else:
await context.bot.send_message(chat_id=ADMIN_ID, text=forward_message, reply_markup=get_admin_keyboard(encoded_user_id, encoded_message_id))
else:
logger.info("Update does not contain a message")
except Exception as e:
logger.error(f"An error occurred: {e}")
if update.message:
await update.message.reply_text("Произошла ошибка. Пожалуйста, попробуйте позже.")
if action == "skip":
logger.info(f"Skipping message {message_id} from user {user_id}")
# Удалить сообщение из памяти
if user_id in user_messages and message_id in user_messages[user_id]:
del user_messages[user_id][message_id]
await query.message.delete()
elif action == "ban":
logger.info(f"Banning user {user_id}")
# Заблокировать пользователя
banned_users.add(user_id)
await query.message.delete()
elif action == "post":
logger.info(f"Posting message {message_id} from user {user_id}")
# Запостить сообщение в канал
message = user_messages.get(user_id, {}).get(message_id)
if message:
username = message.from_user.username or message.from_user.full_name or "NoUsername"
forward_message = (message.caption or message.text or "") + f"\n\nОт пользователя: {username}"
if message.photo:
logger.info(f"Sending photo to channel with caption: {forward_message}")
photos = message.photo
media = [InputMediaPhoto(photo.file_id, caption=(forward_message if i == 0 else None)) for i, photo in enumerate(photos)]
await context.bot.send_media_group(chat_id=CHANNEL_ID, media=media)
elif message.video:
logger.info(f"Sending video to channel with caption: {forward_message}")
await context.bot.send_video(chat_id=CHANNEL_ID, video=message.video.file_id, caption=forward_message)
elif message.document:
logger.info(f"Sending document to channel with caption: {forward_message}")
await context.bot.send_document(chat_id=CHANNEL_ID, document=message.document.file_id, caption=forward_message)
else:
logger.info(f"Sending text message to channel: {forward_message}")
await context.bot.send_message(chat_id=CHANNEL_ID, text=forward_message)
if user_id in user_messages and message_id in user_messages[user_id]:
del user_messages[user_id][message_id]
await query.message.delete()
except Exception as e:
logger.error(f"An error occurred in callback query: {e}")
await query.message.reply_text("Произошла ошибка. Пожалуйста, попробуйте позже.")
А где медиагруппа, собственно?
У тебя только send_photo есть. Для отправки нескольких фотографий можно использовать bot.send_media_group и передавать в аргумент media массив фотографий, например [InputMediaPhoto(image_url, caption) for image_url in photo_list]
Это известная тема. Чтобы отправить медиагруппу, нужно контролировать её начало и конец. Но бот так же ловит каждое сообщение отдельным обновлением, у них разные id. Из общего - mediagrouop_id. Поэтому и отправляются они не группой, а каждое после получения обновления.
Чтобы собрать группу, нужна либо машина состояний, либо функция для парсинга последних сообщений и проверки у них того же значения mediagroup_id. Но в Telegram Bot API по-моему нет возможности смотреть историю, только работать с обновлениями. Так что задача усложняется работой на лету.
Как ещё одна альтернатива — использовать какой-нибудь Pyrogram на MTProto, в нём есть метод copy_mediagroup. Но конкретно эта библиотека давно не обновляется, будут проблемы с типизацией. Аналог — Telethon, но я ей не пользуюсь, не знаю есть ли там нужные инструменты.