Bots interacting with users in plain text messages is often times not enough for a pleasant user experience.
Providing the users with images, videos, files and other media is therefore a common use case for bot programmers and the Bot API provides several ways to do this.
On this wiki page, we explain how files and media are handled in the python-telegram-bot
framework.
Sending files
If you want to send a file (e.g. send a document or a photo) with the bot, you have three options:
- Upload the file
- Send an HTTP URL that leads to the file
- Send a
file_id
of a file that has already been sent.
Note that not every method is supported everywhere (e.g. for thumbnails you can't pass a file_id
). Make sure to check out the documentation of the corresponding bot method for details.
Please also check out the official Telegram API docs on sending files.
Let's have a look at how sending a document can be done. In these examples, we'll be using Bot
's send_document()
method.
Note
In discussion and examples below, we will be using methods of
Bot
, but most of them (includingsend_document()
) have shortcut methods in classes likeUser
,Chat
orMessage
that can be more convenient to use in your particular situation. Documentation for every method inBot
contains links to shortcut methods in other classes.
-
Uploading a file
await bot.send_document(chat_id=chat_id, document=open('tests/test.png', 'rb'))
or even just
await bot.send_document(chat_id=chat_id, document='tests/test.png')
When you pass a file path (note that both
str
andpathlib.Path
are accepted asdocument
parameter), PTB will automatically check if your bot is running in local mode. If it is, the file does not need to be uploaded. Otherwise, the file is read in binary mode, so just as when you passopen('tests/test.png', 'rb')
. -
Sending an HTTP URL
await bot.send_document(chat_id=chat_id, document='https://python-telegram-bot.org/static/testfiles/telegram.gif')
-
Sending by
file_id
:await bot.send_document(chat_id=chat_id, document=file_id)
Two further notes on this:
-
Each bot has its own
file_id
s, i.e. you can't use afile_id
from a different bot to send a photo -
How do you get a
file_id
of a photo you sent? Read it from the return value ofbot.send_document()
(or any otherMessage
object you get your hands on):message = await bot.send_document(...) file_id = message.document.file_id
-
This pretty much works the same way for all the other send_<media_type>()
methods like send_photo()
, send_video()
etc. There is one exception, though: send_media_group()
.
Sending a media group
A call to send_media_group()
looks like this:
await bot.send_media_group(chat_id=chat_id, media=[media_1, media_2, ...])
Each of the items in the media
sequence (list or tuple) must be an instances of InputMediaAudio
, InputMediaDocument
, InputMediaPhoto
or InputMediaVideo
. The media comes into play like so:
media_1 = InputMediaDocument(media=open('tests/test.png', 'rb'), ...)
media_1 = InputMediaDocument(media='https://python-telegram-bot.org/static/testfiles/telegram.gif', ...)
media_1 = InputMediaDocument(media=file_id, ...)
Caution
For the
InputMedia*
classes, passing a file path only works if your bot is running in local mode.
Sending files via inline mode
You may want to allow users to send media via your bots inline mode. This works a little bit different than posting media via send_*
. Most notably, you can't upload files for inline mode! You must provide either an HTTP URL or a file_id
.
Let's stick to example of sending a document. You have to provide bot.answer_inline_query()
with an InlineQueryResult
that represents that document. There are two ways of doing that:
-
HTTP URL:
result = InlineQueryResultDocument(document_url='https://python-telegram-bot.org/static/testfiles/telegram.gif', ...)
-
file_id
:result = InlineQueryResultCachedDocument(document_file_id=file_id, ...)
In this example, we are using InlineQueryResultDocument
for option #1 and InlineQueryResultCachedDocument
for option #2. The scheme InlineQueryResult<media_type>
vs InlineQueryResultCached<media_type>
is similar for the other media types.
Again, please check out the docs for details on required and optional arguments.
Editing a file
When you have sent a file, you may want to edit it. This works similarly as send_media_group
, i.e. the media must be wrapped into a InputMedia<media_type>
object. Again, with document
as example, we'll call bot.edit_message_media()
and pass an instance of InputMediaDocument
as media
:
await bot.edit_message_media(chat_id=chat_id, message_id=message_id, media=InputMediaDocument(media=open('tests/test.png'), ...))
Please check out the restrictions on editing media in the official docs of editMessageMedia
.
Downloading a file
When you receive files from a user, you sometimes want to download and save them. If it's a document, that could look like this:
file_id = message.document.file_id
new_file = await bot.get_file(file_id)
await new_file.download_to_drive()
For a received video/voice/... change message.document
to message.video/voice/...
. However, there is one exception: message.photo
is a list of PhotoSize
objects, which represent different sizes of the same photo. Use message.photo[-1].file_id
to get the largest size.
See also:
Documentation for
Bot.get_file()
Moreover, the above snippet can be shortened by using PTB's built-in utility shortcuts:
new_file = await message.effective_attachment.get_file()
await new_file.download_to_drive('file_name')
message.effective_attachment
automatically contains whichever media attachment the message has. In case of a photo, you'll again have to use e.g. message.effective_attachment[-1].get_file()
.
See also:
Documentation for
File.download_to_drive()
andFile.download_to_memory()
Must read
Concepts & Important Elements
- Architecture Overview
- Builder Pattern for
Application
- Types of Handlers
- Working with Files and Media
- Exceptions, Warnings and Logging
- Concurrency in PTB
Notable Features
- Advanced Filters
- Storing data
- Making your bot persistent
- Adding Defaults
- Job Queue
- Arbitrary
callback_data
- Avoiding flood limits
- Webhooks
- Bot API Forward Compatiblity
Code Resources
- Frequently requested design patterns
- Code snippets
- Performance Optimizations
- Telegram Passport
- Bots built with PTB
- Automated Bot Tests
Examples explained
Networking
Other resources
- Where to host Telegram Bots
- How to host your bot
- Local API Server
- Type Checking with PTB
- Press
- Notes on GAE
- Related Projects
- Emoji
Transition Guides
Administration
- Wiki of
python-telegram-bot
© Copyright 2015-2024 – Licensed by Creative Commons