In order for me to download an image published on a Telegram channel, I need this path:
var contents = JSON.parse(e.postData.contents);
Logger.log(contents.channel_post.photo);
And the answer is:
[{
"file_id":"AAAAA",
"file_size":11111,
"width":253,
"height":320
},{
"file_id":"BBBBB",
"file_size":22222,
"width":632,
"height":800
},{
"file_id":"CCCCC",
"file_size":44444,
"width":1400,
"height":1100
},{
"file_id":"DDDDD",
"file_size":33333,
"width":980,
"height":750
}]
The user @Newbie told me to use Math.max(width, height) to be able to define which of the container has the highest quality image so that I can define in this call which file_id should i use for download:
contents.channel_post.photo[CONTAINER NUMBER].file_id
In this case the container would be number 3. But I couldn't work with this Math.max, I need help to understand how my code should be to do this work.
To retrieve an image URL from a Message object from the Telegram Bot Api you will need to:
Message object (from any of the various APIs)photo field of type PhotoSize[] Documented HerePhotoSize (in your case the biggest one) you have file_idfile_id to getFile() Documented HereFile object Documented Herehttps://api.telegram.org/file/bot<token>/<file_path>Is the image quality not already determined by the file_size property? It appears as the resolution increases (width * height), so does the file_size and thereby the quality as well. For this, check my first solution above.
If instead, you want to find the highest quality image based on a ratio comparing width * height and file_size to find the average file_size in bytes per pixel (not recommended), please check my second solution below:
This solution sorts the returned array of image data by comparing their resolution (width * height) and then takes the first (largest) image from the newly sorted array.
const contents = {}; contents.channel_post = {}; contents.channel_post.photo = [
{ file_id: "AAAAA", file_size: 11111, width: 253, height: 320 },
{ file_id: "BBBBB", file_size: 22222, width: 632, height: 800 },
{ file_id: "CCCCC", file_size: 44444, width: 1400, height: 1100 },
{ file_id: "DDDDD", file_size: 33333, width: 980, height: 750 }
];
const largestImage = contents.channel_post.photo.sort((a, b) => (b.width * b.height) - (a.width * a.height))[0];
console.log(`The largest image's file_id is ${largestImage.file_id}, which contains ${largestImage.width * largestImage.height} pixels (${largestImage.width}×${largestImage.height})`);
If you are specifically trying to determine the actual "quality" of the image regardless of resolution, the closest you could get with the data provided would be to divide the file_size by the total pixel area to determine the average file_size in byte per pixel.
By this logic though, the highest quality image would actually be "AAAAA" which I doubt is what you are going for, so you should probably use the first solution I provided, which returns the largest image.
It's worth noting that because image compression algorithms are quite advanced these days, using a formula like this to determine quality per pixel is hardly reliable as it is, so I do recommend using the first solution.
const contents = {}; contents.channel_post = {}; contents.channel_post.photo = [
{ file_id: "AAAAA", file_size: 11111, width: 253, height: 320 },
{ file_id: "BBBBB", file_size: 22222, width: 632, height: 800 },
{ file_id: "CCCCC", file_size: 44444, width: 1400, height: 1100 },
{ file_id: "DDDDD", file_size: 33333, width: 980, height: 750 }
];
const calcImageQuality = ({ file_size, width, height }) => file_size / (width * height);
const highestQualityImage = contents.channel_post.photo.sort((a, b) => calcImageQuality(b) - calcImageQuality(a))[0];
console.log(`The highest quality image's file_id is ${highestQualityImage.file_id}, which contains ${calcImageQuality(highestQualityImage)} bytes per pixel on average`);
you can find highest quality image like this:
Math.max.apply(Math, array.map(function(o) { return o.width * o.height; }))