3

I'm writing a telegram bot (in Python) that sends images. I'm sending every images several times, and the documentation recommends to sent send a file_id of a file that is already stored in Telegram's sever.

But I can't find any documentation about storing a file In the sever and getting a file_id. I can try to send an image (to myself? to the bot?) and get it's file_id, but it seems sooo hacky.

Ronen
  • 466
  • 4
  • 16

3 Answers3

3

OK, I got it.. you do have to send an image once, but it easy to get the file_id:

msg = bot.send_photo(chat_id=chat_id, photo=open("filename", "rb"))
file_id = msg.photo[0].file_id
 ...
bot.send_photo(photo=file_id)
Ronen
  • 466
  • 4
  • 16
1

Sure! You can send photo from disk or from URL.
In other case, if you send a photo to bot from client you will receive file_id and file_path for different photo size in update.message.photo.

Then you can get real file by link: https://api.telegram.org/file/bot:TOKEN:/photos/file_3.jpg
Also you able to get photo array with file_id: https://api.telegram.org/bot:TOKEN:/getFile?file_id=AAAAAA

Example of received data with photo:

{'update_id': 773777337,
 'message': {'message_id': 737,

             ........

             'date': 7373377337,
             'photo': [{'file_id': 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
                        'file_size': 962,
                        'file_path': 'photos/file_3.jpg',
                        'width': 90,
                        'height': 48},
                       {'file_id': 'BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB',
                        'file_size': 17399,
                        'width': 320,
                        'height': 172},
                       {'file_id': 'CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC',
                        'file_size': 88245,
                        'width': 800,
                        'height': 431},
                       {'file_id': 'DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD',
                        'file_size': 168202,
                        'width': 1174,
                        'height': 633}],
             'caption': 'comment_to_my_uploaded_photo'}}  

Finally, example of my simple bot to send random image from URL:

#!/usr/bin/python3

from telegram.ext import Updater, Filters
from telegram.ext import CommandHandler, CallbackQueryHandler, MessageHandler
from telegram import InlineKeyboardButton, InlineKeyboardMarkup
import requests

def start(bot, update):
    update.message.reply_text('Hello! I can show an awesome images for you!',
                              reply_markup=main_keyboard())

def meow(bot, update):
    query = update.callback_query
    photo = requests.get('http://aws.random.cat/meow').json()
    bot.send_photo(caption="Meow! :)",
                   photo=photo['file'],
                   chat_id=query.message.chat_id,
                   message_id=query.message.message_id,
                   reply_markup=action_keyboard())

def wooff(bot, update):
    query = update.callback_query
    photo = requests.get('https://dog.ceo/api/breed/husky/images/random').json()
    bot.send_photo(caption="Bwoof! :)",
                   photo=photo['message'],
                   chat_id=query.message.chat_id,
                   message_id=query.message.message_id,
                   reply_markup=action_keyboard())

def like(bot, update):
    query = update.callback_query
    bot.send_message(text='{}Likewise!'.format(u'\U0001F60A'),
                     chat_id=query.message.chat_id,
                     reply_markup=main_keyboard())

def great(bot, update):
    query = update.callback_query
    bot.send_message(text='{}Great!'.format(u'\U0001F60B'),
                     chat_id=query.message.chat_id,
                     reply_markup=main_keyboard())

def main_keyboard():
    keyboard = [[InlineKeyboardButton("Get Meow", callback_data='meow`'),
                 InlineKeyboardButton("Get Wooff", callback_data='wooff')]]
    return InlineKeyboardMarkup(keyboard)

def action_keyboard():
    keyboard = [[InlineKeyboardButton("Like!", callback_data='like'),
                 InlineKeyboardButton("Great!", callback_data='great')]]
    return InlineKeyboardMarkup(keyboard)

updater = Updater('XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX')

updater.dispatcher.add_handler(CommandHandler('start', start))
updater.dispatcher.add_handler(CallbackQueryHandler(meow, pattern='meow'))
updater.dispatcher.add_handler(CallbackQueryHandler(wooff, pattern='wooff'))
updater.dispatcher.add_handler(CallbackQueryHandler(like, pattern='like'))
updater.dispatcher.add_handler(CallbackQueryHandler(great, pattern='great'))
updater.dispatcher.add_handler(MessageHandler(Filters.text|Filters.photo, start))

updater.start_polling()

Enjoy!

dzNET
  • 930
  • 1
  • 9
  • 14
1

Here is a vanilla python solution:

from io import BytesIO
import requests
from PIL import Image

CHAT_ID = 'id'
SEND_PHOTO = f'https://api.telegram.org/bot{TOKEN}/sendPhoto'

image = Image.open('photo.jpg')

with BytesIO() as output:
    image.save(output, format='JPEG')
    output.seek(0)
    requests.post(SEND_PHOTO, data={'chat_id': CHAT_ID}, files={'photo': output.read()})

Note that chat_id should be passed via data parameter (not json) and bytes via file parameter of requests.post. It also has to include photo key.

Aray Karjauv
  • 2,679
  • 2
  • 26
  • 44