Делаю функцию рассылки бота на 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 шт):
Из сообщения получится вернуть только первое изображение. Дело в том, что медиагруппа это не одно сообщение, а фактически серия сообщений объединённых одним 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)