Search code examples
pythonbotstelegrampython-telegram-bot

Download files (spec. images) with telegram bot (python-telegram-bot)


Goal: I'm trying to set up a telegram bot, which downloads pictures that are sent to it.

After doing some manual playing with requests, I'd rather like to use the python-telegram-bot library. Yet unfortunately most examples outside the docs are written for some Version <20, the official docs are purely written for Versions >20 and unfortunately never cover this topic to an extend which allowed me to write working code. I dont want to downgrade the version of my lib, I want to understand the current Version (v21.x.x).

My relevant current code looks like this:

from dotenv import load_dotenv
import os
import asyncio
import telegram
from telegram import Update
from telegram.ext import Application, CommandHandler, MessageHandler, filters, ContextTypes, ApplicationBuilder
from telegram.ext import InlineQueryHandler, ExtBot

load_dotenv()
TOKEN = os.getenv('TOKEN')


### **Downloader**
async def downloader(update: Update, context: ContextTypes.DEFAULT_TYPE):
    logging.DEBUG("in downloader app!")
    new_file = await update.message.effective_attachment[-1].get_file() # [-1] for largest size of photo
    file = await new_file.download_to_drive()
    # file2 = await ExtBot.get_file()
    return file

### **Main**
if __name__ == '__main__':
    application = ApplicationBuilder().token(TOKEN).build()

    downloader_handler = MessageHandler(filters.Document.IMAGE, downloader) #**here are the filters**;
    application.add_handler(downloader_handler)

    #file_handler = MessageHandler(filters.Document.JPG, downloader)   # another try, also Document.ALL 
    #application.add_handler(file_handler)

    application.run_polling()

My observations so far:

  • when filters set for Document.ALL and i send a pdf-File, it seems to enter the downloader, yet the pdf I'm not able to retrieve the downloaded pdf everytime (it seems its sometimes saving it to a path which is unknown to me)
  • when i send an image (jpg), it seems, the downloader is never entered (no debug/print statements)
  • I was running in all heaps of Errors, when trying to replace code with snippets from other posts, as it seems most rely on v>20-way of writing this.

To me it seems, this shouldn't be that much hustle...


Any help would be highly apprechiated. I don't think, I will be the only one struggling with this after the major overhaul of the library. Thanks in advance and happy coding to everyone :)

I've tried various stackoverflow-Posts related to this, from all I've read, this example snippet, specifically designed with v20 syntax should work. It does for pdfs (see above weird behaviour), but it doesn't for images, which leads me to believe it is some sort of problem related to filters.

Filters I've tried:

  • filters.Document.IMAGE
  • filters.Document.JPG
  • filters.Document.ALL

Questions:

  • which would be the appropriate filter that should work for jpgs?
  • What else am I maybe missing here?

Solution

  • Yet unfortunately most examples outside the docs are written for some Version <20, the official docs are purely written for Versions >20 and unfortunately never cover this topic to an extend which allowed me to write working code.

    All documentation that is provided by the PTB team is up to date for v20+. Please look here for an overview of available resources.

    it seems its sometimes saving it to a path which is unknown to me

    The method File.download_to_drive gives you the storage path as return value. In your code you already save that return value to the variable file. Printing/logging that file path should help resolving the issue. Note that you can also specfiy a custom path to save the file to via the corresponding argument

    when i send an image (jpg), it seems, the downloader is never entered (no debug/print statements)

    filters.Document.* catches messages that have Message.document set. If you send an image in the "compressed" mode, the message will instead of Message.photo set. You can use filters.PHOTO to catch those messages.

    What else am I maybe missing here?

    Please also check out the wiki page dedicated to working with files and media in PTB


    Disclaimer: I'm currently the maintainer of python-telegram-bot.