Skip to content

Files handling

According to the documentation there are several ways to work with files:

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:

val bot: TelegramBot;
val fileId: FileId;

val tempFile: File = bot.downloadFileToTemp(fileId)

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

val bot: TelegramBot;
val fileId: FileId;

val bytes: ByteArray = bot.downloadFile(fileId)

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.

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 the FileId 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 or File (on any platform)

In most cases, sending via files looks like in the next snippet:

val file: File;

bot.sendDocument(chatId, file.asMultipartFile())