Dan Naim
Dan Naim

Reputation: 161

Telegram bot - receive photo URL

When a user send an image via Telegram bot it there any way to get the image URL? or I just need to save the image somewhere?

Upvotes: 7

Views: 23328

Answers (3)

Peter
Peter

Reputation: 1348

This is a three steps process First when the user send an image, your bot get a JSON structure like this:

Array
(
    [update_id] => 820488009
    [message] => Array
        (
            [message_id] => 11338
            [from] => Array
                (
                    [id] => xxxxxx
                    [is_bot] => 
                    [first_name] => ANSB
                    [language_code] => fr
                )

            [chat] => Array
                (
                    [id] => 333333333
                    [first_name] => ANSB
                    [type] => private
                )

            [date] => 1606316785
            [photo] => Array
                (
                    [0] => Array
                        (
                            [file_id] => AgACAgEAAxkBAAIsSl--cvE_bez8g1Kzbk6LsR4JZOJWAALxqDEbw8TxRQpbG7Np1dvbARV2ShcAAwEAAwIAA20AA6SRAAIeBA
                            [file_unique_id] => AQADARV2ShcAA6SRAAI
                            [file_size] => 34888
                            [width] => 320
                            [height] => 240
                        )

                    [1] => Array
                        (
                            [file_id] => AgACAgEAAxkBAAIsSl--cvE_bez8g1Kzbk6LsR4JZOJWAALxqDEbw8TxRQpbG7Np1dvbARV2ShcAAwEAAwIAA3gAA6WRAAIeBA
                            [file_unique_id] => AQADARV2ShcAA6WRAAI
                            [file_size] => 204583
                            [width] => 800
                            [height] => 600
                        )

                    [2] => Array
                        (
                            [file_id] => AgACAgEAAxkBAAIsSl--cvE_bez8g1Kzbk6LsR4JZOJWAALxqDEbw8TxRQpbG7Np1dvbARV2ShcAAwEAAwIAA3kAA6KRAAIeBA
                            [file_unique_id] => AQADARV2ShcAA6KRAAI
                            [file_size] => 372915
                            [width] => 1280
                            [height] => 960
                        )
                )
        )
)

As you can see, Telegram create low resolution of the image. If the original image is small, you can have only the original. If it's medium you'll get two. Here yu can see I have 3 images (the original is the big one 1280*960). So you have to check the size of the array of image wih (eg i PHP)

$nbr_image = count($jsondata['message']['photo']);

in order to read the file_id of your choice so the oe of the smallest, the biggest etc... Take care, the id is NOT the file_unique_id but the big one so the file_id.

Notice if the user send in one time more than one picture, you will get one message for each picture. So each message is about ONE picture, in multiple resolutions.

Once your bot has the file_id, you must call Telegram sending the file_id. The call is a basic one with:

https://api.telegram.org/bot<token_of_your_bot>/getFile?file_id=<file_id of the picture>

You get back a JSON with:

{"ok":true,
   "result":
   {"file_id":"AgACAgEAAxkBAAIsUV--hZoxZ5_ctnfbVa0zFWjRtMYUAALyqDEbw8TxRdkTI6iDNvHUmKQSMAAEAQADAgADeAADsx8EAAEeBA",
   "file_unique_id":"AQADmKQSMAAEsx8EAAE",
   "file_size":41597,
   "file_path":"photos/file_0.jpg"
 }

So a copy of the file_id, the weight (notice you don't get back pixel size!) and the path.

After that, just make a call using the path like this:

https://api.telegram.org/file/bot<token_of_your_bot>/<file_path from the JSON>

and you'll get the picture

One point: each time I get a JSON with the picture in more than one resolution, the big one is the last. But I've find nothing in the doc about that fact. So I'm note sure you can't have the big one in index [0]...

Note: just edit my answer. You can, of course, look at the size of the pictures and send to Telegram the file_id corresponding to the size you want. But if you have a close look at all the file_id of a picture, you'll seen that they are... identical!! So in fact it seems IMPOSSIBLE to ask for the "small image" or "the big one" as Telegram will send you the same...

Upvotes: 4

Manuchekhr
Manuchekhr

Reputation: 109

I know I'm too late, but I was researching for it too long. Here is the answer:

const TelegramBot =         require('node-telegram-bot-api');
let bot = new TelegramBot(token, {polling: true});

And the function to download it requires file id, which comes within the message

var file_id  = (msg.photo[msg.photo.length-1].file_id);




  var downloadDir = './images';
  let something = ''
  var https = require('https')
  bot.getFileLink(fileId).then( async (fileUri) => {
    var base64Img = require('base64-img');

      let time = process.hrtime();
      let extension = fileUri.split('.').pop();
      let newName = `${time[0]}${time[1]}.${extension}`;
      let file = fs.createWriteStream(`${downloadDir}/${newName}`);
      let request = await https.get(fileUri, (response) => {
         response.pipe(file);

        });
        file.on('finish', () =>{
          console.log('msg.text ='/images/'+newName')
         })
      //

  });
};

Main function is the bot.getFileLink(fileId). Hope it will help who will read this :)

Upvotes: 3

Maak
Maak

Reputation: 5038

In the message array you receive you can find the key photo. There you will find multiple arrays with the following format

"file_id" : "XXXX",
"file_size" : 1107,
"width" : 90,
"height" : 51

From one of those array you need to take the file_id. You can then request the file_path with a simple get get on the url https://api.telegram.org/bot<token>/getFile?file_id=<file_id>

You will receive an array that looks as following

"ok" : true,
"result" : {
    "file_id" : "XXXX",
    "file_size" : 27935,
    "file_path" : "photo\/file_1.jpg"
}

From the result you need the file_path and you then got the image location https://api.telegram.org/file/bot<token>/<file_path>

Upvotes: 18

Related Questions