Files handling¶
According to the documentation there are several ways to work with files:
- By FileId
- By FileUrl (
typealias
for theFileId
) - By some MultipartFile (in Telegram Bot API it is multipart requests)
Files receiving¶
There are several cases you may need in your app to work with files:
- Save
FileId
(for sending in future) - Download some file into memory/file in filesystem
Where to get File id or url?¶
The most simple way to send some file is to get file id and send it. You may get file id from any message with media. For example, if you have received some Message, you may use asCommonMessage conversation to be able to get its content
and then convert it to some content with media. Full code here:
val message: Message;
val fileId = message.asCommonMessage() ?.withContent<MediaContent>() ?.content ?.media ?.fileId;
WAT? O.o
In the code above we get some message, safely converted it to CommonMessage
with asCommonMessage
, then safely took its content via withContent<MediaContent>() ?.content
and then just get its media file id.
Download files¶
There are three ways to download files:
- Download it in memory as
ByteArray
- Take
ByteReadChannelAllocator
which allow to retrieve ByteReadChannel and do whatever you want with it [JVM Only]
Download it directly to file or temporal file
Downloading with API
extensions¶
Files (JVM/Android)¶
val bot: TelegramBot;
val fileId: FileId;
val outputFile: File;
bot.downloadFile(fileId, outputFile)
See downloadFile extension docs in the JVM tab to get more available options
There is also way with saving of data into temporal file. That will allow you to do with data whatever you want without high requirements to memory or network connection:
See downloadFileToTemp extension docs to get more available options
Byte read channel¶
val bot: TelegramBot;
val fileId: FileId;
val bytes: ByteReadChannelAllocator = bot.downloadFileStream(fileId)
See downloadFileStream extension docs to get more available options
Byte read channel allocator¶
val bot: TelegramBot;
val fileId: FileId;
val bytes: ByteReadChannelAllocator = bot.downloadFileStreamAllocator(fileId)
See downloadFileStreamAllocator extension docs to get more available options
Byte arrays¶
See downloadFile extension docs to get more available options
Low level or how does it work?
¶
You may download file with streams or with downloading into the memory first. On low level you should do several things. They are presented in next snippet:
val bot: TelegramBot;
val fileId: FileId;
val pathedFile: PathedFile = bot.execute(GetFile(fileId))
val downloadedBytes: ByteArray = bot.execute(DownloadFile(pathedFile.filePath))
In the snippet above we are getting file PathedFile
by its FileId
and use it to download file bytes into memory using DownloadFile
request.
You may use almost the same way but with byte read channel allocator:
val bot: TelegramBot;
val fileId: FileId;
val pathedFile: PathedFile = bot.execute(GetFile(fileId))
val channelAllocator: ByteReadChannelAllocator = bot.execute(DownloadFileStream(pathedFile.filePath))
val byteReadChannel: ByteReadChannel = channelAllocator()
And then you may look into ByteReadChannel docs to get more info about what you can do with that.
Several useful links
Files sending¶
Of course, in most cases you must be sure that file have correct type.
FileId and FileUrl¶
It is the most simple way to send any media in Telegram, but this way have several restrictions:
- The
FileId
which has retrieved for file should not (and probably will not too) equal to theFileId
retrieved by some other bot - There is a chance that the file id you are using will be expired with time
Sending via file¶
JS Restrictions
Sending via file is accessible from all supported platforms, but there is small note about JS
- due to restrictions of work with streams and stream-like data (JS
have no native support of files streaming) on this platform all the files will be loaded inside of RAM before the sending to the telegram services.
Sending via file is available throw the MultipartFile. There are several wayt to get it:
- Simple creating via its constructor:
MultipartFile("filename.jpg") { /* here Input allocation */ }
- Via asMultiparFile extension applicable to any
ByteArray
,ByteReadChannel
,ByteReadChannelAllocator
orFile
(on any platform)
In most cases, sending via files looks like in the next snippet: