What's the best way to download and store images from Telegram bot users to local storage?

I’m working on a Telegram bot using Spring Boot and LongPollingBot. I need help figuring out how to properly download pictures that users send to my bot and save them to my computer with good image quality.

Right now I’m trying something like this but it’s not working correctly:

PhotoSize imageData = message.getPhoto().get(0);

File imageFile = new File("./images/" + imageData.getFileId() + ".jpg");
try (FileOutputStream fileWriter = new FileOutputStream(imageFile)) {
    fileWriter.write(imageData.getFileId().getBytes());
} catch (IOException ex) {
    ex.printStackTrace();
}

The problem is this code only saves the file ID as text instead of the actual image. I’ve looked at tutorials that mention using methods like imageData.getData().getInputStream() but those seem to be old approaches that don’t work anymore. Can someone show me the correct modern way to do this?

You’re trying to write the file ID string directly instead of downloading the actual image from Telegram’s servers. The file ID is just a reference - not the image itself.

First use GetFile to get the file path, then download it from Telegram’s file API. Here’s what worked for me:

GetFile getFile = new GetFile();
getFile.setFileId(imageData.getFileId());
org.telegram.telegrambots.meta.api.objects.File file = execute(getFile);

String fileUrl = "https://api.telegram.org/file/bot" + getBotToken() + "/" + file.getFilePath();

URL url = new URL(fileUrl);
try (InputStream in = url.openStream()) {
    Files.copy(in, Paths.get("./images/" + imageData.getFileId() + ".jpg"));
}

Also grab the largest photo size from the array instead of index 0 for better quality. The photos are sorted by size so pick the last element.

yeah ethan’s got the right idea, but watch out for telegram’s 20mb file size limit on bot api downloads. also, try photoSize.get(photoSize.size()-1) to automatically grab the highest quality version instead of hardcoding the index.

Yeah, you’re saving the file ID string instead of the actual image data. The other answers are right about using GetFile, but wrap your download in error handling - Telegram’s servers can be slow or throw errors. I learned this the hard way: always validate the file exists before downloading. Users send corrupted files all the time, or files become unavailable between sending and processing. Add a retry mechanism for failed downloads too. Don’t just use the file ID for naming - if users send the same image twice, you’ll have problems. I append timestamps or use UUIDs for unique filenames. Prevents overwrites and makes debugging way easier when you need to trace who sent what.