tesfalem mesele
tesfalem mesele

Reputation: 101

How do I download a file or photo that was sent to my telegram bot using telegraf module?

I am using node.js telegraf module to create a telegram bot.

I am using the code below.

var picture = (context)ctx.message.photo[0].file_id; 
var photo = `https://api.telegram.org/bot1234-ABCD/getFile?file_id=${picture}`;
console.log(photo.file_path);

Upvotes: 3

Views: 13402

Answers (4)

Youcef Hammadi
Youcef Hammadi

Reputation: 71

When the user sends an image, the content of ctx.message is as follows:

{
    message_id: 111,
    from: {...},
    ...
    photo: [
      {
        file_id: 'XXXX',
        file_unique_id: 'YYYY',
        file_size: 1234,
        width: 43,
        height: 90
      },
       ...
      {
        file_id: 'XXXX',
        file_unique_id: 'YYYY',
        file_size: 64202,
        width: 606,
        height: 1280
      }
    ]
}

The last element of photo array is the highest resolution

const { Telegraf } = require("telegraf");
const { message } = require("telegraf/filters");
const https = require("https");
const fs = require("fs");


bot.on(message("photo"), async (ctx) => {
    let imageId = ctx.message.photo.pop().file_id;

    ctx.telegram.getFileLink(imageId).then((link) => {
        https.get(link, (response) =>
            response.pipe(fs.createWriteStream(`path/img/${imageId}.jpeg`))
        );
    });
});

Use pop() to get the last element, What we need from this element is file_id

Upvotes: 1

Vatsal
Vatsal

Reputation: 36

If you want to download the highest quality photo you can use this command for the high quality file id let fileId = ctx.message.photo.pop().file_id;

Upvotes: 0

tesfalem mesele
tesfalem mesele

Reputation: 101

$ npm install needle
var needle = require('needle');

...

needle.get(`https://api.telegram.org/bot1234:ABCD/getFile?file_id=${picture}`, function(error, response) {
  if (!error && response.statusCode == 200)
    console.log(response.body.result);
});

Upvotes: 1

Merhawi Fissehaye
Merhawi Fissehaye

Reputation: 2807

You can use axios to store the images. Assuming you have the file id as fileId and the context as ctx. I am storing the image at the path ${config.basePath}/public/images/profiles/${ctx.update.message.from.id}.jpg

ctx.telegram.getFileLink(fileId).then(url => {    
    axios({url, responseType: 'stream'}).then(response => {
        return new Promise((resolve, reject) => {
            response.data.pipe(fs.createWriteStream(`${config.basePath}/public/images/profiles/${ctx.update.message.from.id}.jpg`))
                        .on('finish', () => /* File is saved. */)
                        .on('error', e => /* An error has occured */)
                });
            })
})

How do I get the file id of the image sent for the bot

bot.on('message', ctx => {
    const files = ctx.update.message.photo;
    // telegram stores the photos for different sizes
    // here is a sample files result
    // [ { file_id:
    //   'AgADBAADgbAxG768CFDXChKUnJnzU5jjLBsABAEAAwIAA20AA_PFBwABFgQ',
    //   file_size: 29997,
    //   width: 320,
    //   height: 297 },
    //   { file_id:
    //   'AgADBAADgbAxG768CFDXChKUnJnzU5jjLBsABAEAAwIAA3gAA_HFBwABFgQ',
    //   file_size: 80278,
    //   width: 580,
    //   height: 538 } ]
    //   })

    // I am getting the bigger image
    fileId = files[1].file_id
    // Proceed downloading
});

Don't forget to install axios as npm install axios --save and require it as const axios = require('axios')

N.B. Don't publish the file links publicly as it exposes your bot token.

Upvotes: 7

Related Questions