0

How can I download a file which has been sent by a user in chat?

For example

I need to download the file moonloader.log from Telegram to my local path C:\text-folder\moonloader.log and read it.

Code so far

def checkFile(path):
    if os.path.isfile(path):
        f = open(path, 'r')
        log = f.read()
        print('начинаю проверку...')
        # check log
        result = re.search('MoonLoader v.(.+) loaded.', log)
        if result:
            moonlog_version = result.group(1)
            print('• Версия moonloader: ' + moonlog_version)
            for err in range(0, len(errors)):
                for i in errors[err]:
                    print('   • Ошибка: ' + errors[err][i])

# ON RECEIVE FILE 
@dp.message_handler(content_types=types.ContentType.DOCUMENT)
async def fileHandle(message: types.File):
    await message.reply(text='файл получен, начинаю поиск ошибок...')
    ## LOAD FILE CODE
    checkFile(LOADED FILE PATH)

Updated Code

I tried to follow the answer of hc_dev and added the download method. But not sure how to get the File or file_path from message. I tried this:

def download_file(file: types.File):
    file_path = file.file_path 
    destination = r'C:\\Users\\admin\\Desktop\\moonlog inspector\\download'
    destination_file = bot.download_file(file_path, destination) # ON RECEIVE FILE 

@dp.message_handler(content_types=types.ContentType.DOCUMENT)
async def fileHandle(message: types.Document):
    await message.reply(text='файл получен, начинаю поиск ошибок...')
    ## LOAD FILE CODE
    download_file(message.file_id)

But when running it raises the error:

'Message' object has no attribute 'file_id'

hc_dev
  • 8,389
  • 1
  • 26
  • 38
chapo
  • 1
  • 1
  • 1
  • What about [`download_file()`](https://docs.aiogram.dev/en/latest/telegram/bot.html?highlight=file#aiogram.bot.base.BaseBot.download_file) to download a file from telegram server to your local disk. This method seems a facade to [Telegram-API as guided in Downloading Files](https://core.telegram.org/api/files#downloading-files) – hc_dev Sep 09 '21 at 17:35

2 Answers2

0

Following question welcomed and explained the new getFile operation in Telegram Bot API: How do I download a file or photo that was sent to my Telegram bot?

In aiogram you would use download_file on you Bot object: As parameters you can pass the string file_path (path identifying the file on the telegram server) and a destination on your local volume.

The file_path is an attribute of an types.File object.

bot = # your_bot accessing Telegram's API

def download_file(file: types.File):
     file_path = file.file_path
     destination = r"C:\folder\file.txt"
     destination_file = bot.download_file(file_path, destination)
hc_dev
  • 8,389
  • 1
  • 26
  • 38
  • 1
    but how can i get file_path? can you help me? ``` def download_file(file: types.File): file_path = file.file_path destination = r'C:\\Users\\admin\\Desktop\\moonlog inspector\\download' destination_file = bot.download_file(file_path, destination) # ON RECEIVE FILE @dp.message_handler(content_types=types.ContentType.DOCUMENT) async def fileHandle(message: types.Document): await message.reply(text='файл получен, начинаю поиск ошибок...') ## LOAD FILE CODE download_file(message.file_id) ``` 'Message' object has no attribute 'file_id' – chapo Sep 09 '21 at 19:55
0

If you don't want to save files locally, you could use io.BytesIO. In my projects I am used to save files like that:

@dp.message_handler(content_types=['photo', 'document'])
async def photo_or_doc_handler(message: types.Message):
    file_in_io = io.BytesIO()
    if message.content_type == 'photo':
        await message.photo[-1].download(destination_file=file_in_io)
    elif message.content_type == 'document':
        await message.document.download(destination_file=file_in_io)
    # file_in_io - do smth with this file-like object

or with a context manager:

async with io.BytesIO() as file_in_io:
    await message.photo[-1].download(destination_file=file_in_io)
    file_in_io.seek(0)
    # file_in_io - do smth with this file-like object
Maksim K.
  • 156
  • 5