Делаю функцию рассылки бота на Python на Telebot

Столкнулся с такой проблемой:

Пишу бота для библиотеки Telebot. Пытаюсь сделать функцию рассылки сообщений пользователям. Суть такая: Администратор отправляет команду /broadcast, предварительно "Ответив" на сообщение которое нужно переслать. После чего бот с помощью метода копирования рассылает нужное сообщение всем пользователям бота. Проблема заключается в том, что при исполнении данной функции бот (Если в сообщении для рассылки есть медиафайлы), вместо того, чтобы скопировать все медиафайлы из исходного сообщения произвольно берет один медиафайл и копирует его в одном сообщении несколько раз. Я тестировал: после каждого перезапуска бота пользователи каждый раз получали разные медиафайлы. Всего запуска было 3 (См. скриншоты). Буду рад если поможете решить данную проблему. Заранее спасибо!

Что отправляет администратор Что приходит пользователю

Функция рассылки:

def handle_broadcast(message):
    if message.from_user.id == ADMIN_ID:
        if message.reply_to_message:
            msg = message.reply_to_message
        else:
            bot.reply_to(message, "Пожалуйста, ответьте на сообщение, которое вы хотите разослать.")
            return  # Завершаем выполнение функции, если нет сообщения для рассылки

        user_ids = execute_query('SELECT user_id FROM users WHERE is_subscribed = 1').fetchall()
        sent_count = 0  # Счетчик успешно отправленных сообщений

        if msg.photo:  # Проверяем, есть ли медиафайлы в сообщении
            media = []
            caption = msg.caption if msg.caption else ""

            for i, photo in enumerate(msg.photo):
                if i == 0:
                    media.append(types.InputMediaPhoto(photo.file_id, caption=caption))
                else:
                    media.append(types.InputMediaPhoto(photo.file_id))

            for user_id in user_ids:
                try:
                    bot.send_media_group(chat_id=user_id[0], media=media)
                    sent_count += 1
                    time.sleep(0.5)
                except Exception as e:
                    print(f"Failed to send media to {user_id[0]}: {e}")

        else:  # Если это не фото, просто копируем сообщение
            for user_id in user_ids:
                try:
                    bot.copy_message(chat_id=user_id[0], from_chat_id=msg.chat.id, message_id=msg.message_id)
                    sent_count += 1
                    time.sleep(0.5)
                except Exception as e:
                    print(f"Failed to send message to {user_id[0]}: {e}")

        bot.reply_to(message, f"Сообщение успешно разослано. Количество получателей: {sent_count}.")```

Ответы (1 шт):

Автор решения: Amgarak

Связанный ответ.

Из сообщения получится вернуть только первое изображение. Дело в том, что медиагруппа это не одно сообщение, а фактически серия сообщений объединённых одним ID-медиагруппы. Так что если нужно, что бы бот вернул медиагруппу, то её сперва нужно сохранить, а уже потом по запросу вернуть.

Примерно так:

import telebot
from telebot import types

TOKEN = ''
bot = telebot.TeleBot(TOKEN)

# Словарь для хранения данных о медиагруппах
media_groups = {}

@bot.message_handler(content_types=['photo'])
def save_media_group(message):
    user_id = message.from_user.id
    media_group_id = message.media_group_id

    # Если сообщение не часть медиагруппы
    if media_group_id is None:
        return

    # Идентификатор фото
    photo_id = message.photo[-1].file_id
    caption = message.caption

    # Проверяем, есть ли уже сохраненные данные о группе
    if media_group_id in media_groups:
        media_groups[media_group_id]['photo_ids'].append(photo_id)
    else:
        media_groups[media_group_id] = {
            'photo_ids': [photo_id],
            'caption': caption,
            'user_id': user_id,
        }

    # Если у сообщения есть подпись, обновляем её в медиагруппе
    if caption:
        media_groups[media_group_id]['caption'] = caption

    # Отладка
    print(f"Сохранено: {media_groups}")

@bot.message_handler(content_types=['text'])
def handle_replied_message(message):
    if not message.reply_to_message:
        bot.send_message(message.chat.id, "Пожалуйста, процитируйте сообщение с медиагруппой.")
        return

    # Получаем процитированное сообщение
    replied_message = message.reply_to_message
    media_group_id = replied_message.media_group_id

    # Проверяем, есть ли media_group_id
    if media_group_id is None:
        bot.send_message(message.chat.id, "Цитируемое сообщение не является частью медиагруппы.")
        return

    # Проверяем, есть ли данные о медиагруппе
    if media_group_id in media_groups:
        group = media_groups[media_group_id]
        
        # Формируем медиагруппу для отправки
        media = [
            types.InputMediaPhoto(photo_id, caption=group['caption'] if i == 0 else '')
            for i, photo_id in enumerate(group['photo_ids'])
        ]
        bot.send_media_group(chat_id=message.chat.id, media=media)
    else:
        bot.send_message(message.chat.id, "Данные о процитированной медиагруппе не найдены.")

bot.polling(none_stop=True)

введите сюда описание изображения

→ Ссылка