Сохранение файлов - Telebot

Решил написать простого бота для Telegram-а на telebot. Столкнулся с проблемой: мне нужно скачать все файлы и текст отправленные юзером. Делаю вот так:

from config import TOKEN
import telebot
import os
import time

bot = telebot.TeleBot(TOKEN)

@bot.message_handler(commands=['start'])
def start(message):
    bot.send_message(message.chat.id, 'Отправь своё (фото, видео, музыку, или текст)')

@bot.message_handler(content_types=['text', 'photo', 'video', 'audio'])
def download_data(message):
    user_directory = f'data/{message.from_user.username}'

    if not os.path.exists(user_directory):
        os.makedirs(user_directory)
    
    if message.photo:
        photo = message.photo[-1]
        file = bot.get_file(photo.file_id)
        downloaded_file = bot.download_file(file.file_path)
        filename = f'{user_directory}/photo_{int(time.time())}.jpg'

        with open(filename, 'wb') as f:
            f.write(downloaded_file)

    elif message.video:
        video = message.video
        file = bot.get_file(video.file_id)
        downloaded_file = bot.download_file(file.file_path)
        filename = f'{user_directory}/video_{int(time.time())}.mp4'

        with open(filename, 'wb') as f:
            f.write(downloaded_file)

    elif message.audio:
        audio = message.audio
        file = bot.get_file(audio.file_id)
        downloaded_file = bot.download_file(file.file_path)
        filename = f'{user_directory}/audio_{int(time.time())}.mp3'
        
        with open(filename, 'wb') as f:
            f.write(downloaded_file)

    elif message.text:
        filename = f'{user_directory}/text.txt'
        
        with open(filename, 'w') as f:
            f.write(message.text)

bot.infinity_polling()

При отправке множества изображений, видео или аудио - скачивается меньшая часть отправленного. Мне нужно чтобы сохранялись все отправленные файлы. Заранее спасибо!


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

Автор решения: Рустам Рысаев

Ваша проблема связана с тем, что обработчик @bot.message_handler обрабатывает только одно сообщение за раз. Если пользователь отправляет несколько файлов одним сообщением (например, в виде альбома), Telegram отправляет их в виде группы, и ваша логика обрабатывает только одну часть сообщения. Чтобы решить проблему, нужно обработать все файлы из группы.

from config import TOKEN
import telebot
import os
import time

bot = telebot.TeleBot(TOKEN)

@bot.message_handler(commands=['start'])
def start(message):
    bot.send_message(message.chat.id, 'Отправь своё (фото, видео, музыку, или текст)')

@bot.message_handler(content_types=['photo', 'video', 'audio', 'text', 'document'])
def download_data(message):
    user_directory = f'data/{message.from_user.username}'
    if not os.path.exists(user_directory):
        os.makedirs(user_directory)

    if message.photo:  # Фото (может быть несколько в одном сообщении)
        for photo in message.photo:
            file = bot.get_file(photo.file_id)
            downloaded_file = bot.download_file(file.file_path)
            filename = f'{user_directory}/photo_{int(time.time())}.jpg'

            with open(filename, 'wb') as f:
                f.write(downloaded_file)

    elif message.video:  # Видео
        file = bot.get_file(message.video.file_id)
        downloaded_file = bot.download_file(file.file_path)
        filename = f'{user_directory}/video_{int(time.time())}.mp4'

        with open(filename, 'wb') as f:
            f.write(downloaded_file)

    elif message.audio:  # Аудио
        file = bot.get_file(message.audio.file_id)
        downloaded_file = bot.download_file(file.file_path)
        filename = f'{user_directory}/audio_{int(time.time())}.mp3'

        with open(filename, 'wb') as f:
            f.write(downloaded_file)

    elif message.document:  # Документы
        file = bot.get_file(message.document.file_id)
        downloaded_file = bot.download_file(file.file_path)
        filename = f'{user_directory}/{message.document.file_name}'

        with open(filename, 'wb') as f:
            f.write(downloaded_file)

    elif message.text:  # Текст
        filename = f'{user_directory}/text_{int(time.time())}.txt'

        with open(filename, 'w') as f:
            f.write(message.text)

# Обработка альбомов медиа (группы медиафайлов)
@bot.message_handler(content_types=['media_group'])
def download_media_group(message):
    user_directory = f'data/{message.from_user.username}'
    if not os.path.exists(user_directory):
        os.makedirs(user_directory)

    for media in message.media_group_id:
        if media.photo:  # Фото из альбома
            file = bot.get_file(media.photo[-1].file_id)
            downloaded_file = bot.download_file(file.file_path)
            filename = f'{user_directory}/photo_{int(time.time())}.jpg'

            with open(filename, 'wb') as f:
                f.write(downloaded_file)

        elif media.video:  # Видео из альбома
            file = bot.get_file(media.video.file_id)
            downloaded_file = bot.download_file(file.file_path)
            filename = f'{user_directory}/video_{int(time.time())}.mp4'

            with open(filename, 'wb') as f:
                f.write(downloaded_file)

# Запуск бота
bot.infinity_polling()

→ Ссылка