11

i want to write a telegram bot that save photos . this is my code , but its not working. and i don't know what is my problem?

def image_handler(bot, update):
    file = bot.getFile(update.message.photo.file_id)
    print ("file_id: " + str(update.message.photo.file_id))
    file.download('image.jpg')

updater.dispatcher.add_handler(MessageHandler(Filters.photo, image_handler))
updater.start_polling()
updater.idle()

pleas help me to solve my problem.

Ali Akhtari
  • 1,211
  • 2
  • 21
  • 42

5 Answers5

17

update.message.photo is an array of photos sizes (PhotoSize objects).

Use file = bot.getFile(update.message.photo[-1].file_id). This will get the image with biggest size available.

dev4Fun
  • 990
  • 9
  • 18
  • 2
    why i should write "[-1]" ? what is this? – Ali Akhtari May 19 '18 at 20:27
  • 4
    @Ali [-1] is the last item of array. This is how indices work in python. I recommend getting familiar with it as it's very common feature. You actually don't have to use the last item, but last image is the biggest image according to docs (https://github.com/python-telegram-bot/python-telegram-bot/wiki/Code-snippets#download-a-file) – dev4Fun May 19 '18 at 21:05
5

Here is my code

from telegram.ext import *
import telegram

def start_command(update, context):
    name = update.message.chat.first_name
    update.message.reply_text("Hello " + name)
    update.message.reply_text("Please share your image")

def image_handler(update, context):
    file = update.message.photo[0].file_id
    obj = context.bot.get_file(file)
    obj.download()
    
    update.message.reply_text("Image received")

def main():
    print("Started")
    TOKEN = "your-token"
    updater = Updater(TOKEN, use_context = True)
    dp = updater.dispatcher
    dp.add_handler(CommandHandler("start", start_command))

    dp.add_handler(MessageHandler(Filters.photo, image_handler))

    updater.start_polling()
    updater.idle()

if __name__ == '__main__':
    main()
1

Unlike the accepted answer suggests, you don't actually need the bot object to get the file:

file = update.message.photo[-1].get_file()

and then download the file:

path = file.download("output.jpg")

to use it for further processing or just have it on your device : )

finnmglas
  • 1,626
  • 4
  • 22
  • 37
0

Here is a vanilla python solution:

import requests
from PIL import Image

# for example, we get the last message
# update = requests.post(f'https://api.telegram.org/bot{TOKEN}/getUpdates').json()['result'][-1]

msg = update['message']

# check whether the message contains a photo
if msg.get('photo', None) == None:
  return

# get the photo id with the biggest resolution
file_id = msg['photo'][-1]['file_id']

# get URL by id
file_path = requests.get(f'https://api.telegram.org/bot{TOKEN}/getFile?file_id={file_id}').json()['result']['file_path']

# open URL with Pillow
img = Image.open(requests.get(f'https://api.telegram.org/file/bot{TOKEN}/{file_path}', stream=True).raw)

# save on the disk if needed
img.save('photo.jpg')
Aray Karjauv
  • 2,679
  • 2
  • 26
  • 44
-1

@dp.message_handler(commands='start')
9 async def s_photo(message: types.Message):
10 """getting str type of json file"""
11photostr = await bot.get_user_profile_photos(message.from_user.id)
12 """parsing str to json"""
13 photojson = json.loads(photostr.as_json())
14 """giving file unic code to get_file method"""
15 photo = await bot.get_file(photojson['photo'][0][0]['file_id'])
16 """end downloading object with download method"""
17 downloadphoto = await photo.download('filename'+'.jpeg')