You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Node.js的Telegraf模块下载Telegram机器人收到的文件或图片

如何用Telegraf下载Telegram机器人收到的图片/文件

嘿,我来帮你搞定这个问题~你之前的代码误区在于,https://api.telegram.org/bot1234-ABCD/getFile?file_id=${picture} 只是一个API请求地址,直接把它赋值给photo变量后,它只是个普通字符串,根本没有file_path属性。你得先发送HTTP请求调用这个API,拿到返回的文件路径,才能拼接出真正的下载链接。

下面给你两种靠谱的实现方式,都是基于Node.js的Telegraf框架:

方法一:用Telegraf内置API(推荐)

Telegraf已经封装了Telegram Bot API的调用,用ctx.telegram.getFile()就能直接获取文件信息,不用自己手动写HTTP请求,代码更简洁:

const { Telegraf } = require('telegraf');
const fs = require('fs');
const axios = require('axios'); // 也可以用node-fetch,按需选择

// 替换成你的机器人Token
const bot = new Telegraf('YOUR_BOT_TOKEN');

// 监听用户发送的图片
bot.on('photo', async (ctx) => {
  // 注意:Telegram会发送多分辨率的图片,最后一个元素是最高清的版本,[0]是缩略图
  const highestResPhotoId = ctx.message.photo[ctx.message.photo.length - 1].file_id;

  try {
    // 获取文件的详细信息(包含file_path)
    const fileInfo = await ctx.telegram.getFile(highestResPhotoId);
    // 拼接真正的下载地址
    const downloadUrl = `https://api.telegram.org/file/bot${bot.token}/${fileInfo.file_path}`;

    // 以流的方式下载并保存文件,适合大文件,避免内存溢出
    const downloadResponse = await axios({
      url: downloadUrl,
      method: 'GET',
      responseType: 'stream'
    });

    // 保存到本地,这里可以自定义文件名,比如用Telegram返回的文件名(如果有的话)
    const savePath = `./downloaded_${Date.now()}.jpg`;
    const fileWriter = fs.createWriteStream(savePath);

    downloadResponse.data.pipe(fileWriter);

    // 监听保存完成事件
    fileWriter.on('finish', () => {
      console.log(`图片已保存到:${savePath}`);
      ctx.reply('图片下载保存成功啦!');
    });

    // 监听保存错误事件
    fileWriter.on('error', (err) => {
      console.error('保存文件出错:', err);
      ctx.reply('哎呀,保存图片时出问题了😥');
    });
  } catch (error) {
    console.error('获取文件信息失败:', error);
    ctx.reply('获取图片信息出错了😢');
  }
});

// 监听用户发送的普通文件(比如文档、压缩包等)
bot.on('document', async (ctx) => {
  const fileId = ctx.message.document.file_id;
  const fileName = ctx.message.document.file_name || `file_${Date.now()}`;

  try {
    const fileInfo = await ctx.telegram.getFile(fileId);
    const downloadUrl = `https://api.telegram.org/file/bot${bot.token}/${fileInfo.file_path}`;

    const downloadResponse = await axios({
      url: downloadUrl,
      method: 'GET',
      responseType: 'stream'
    });

    const savePath = `./${fileName}`;
    const fileWriter = fs.createWriteStream(savePath);

    downloadResponse.data.pipe(fileWriter);

    fileWriter.on('finish', () => {
      console.log(`文件已保存到:${savePath}`);
      ctx.reply('文件下载保存成功啦!');
    });

    fileWriter.on('error', (err) => {
      console.error('保存文件出错:', err);
      ctx.reply('保存文件时出问题了😥');
    });
  } catch (error) {
    console.error('获取文件信息失败:', error);
    ctx.reply('获取文件信息出错了😢');
  }
});

bot.launch();

方法二:手动调用Telegram API(适合自定义需求)

如果你想自己控制HTTP请求的细节,可以直接调用Telegram的getFile API,再拼接下载链接:

const { Telegraf } = require('telegraf');
const fs = require('fs');
const axios = require('axios');

const bot = new Telegraf('YOUR_BOT_TOKEN');
const BOT_TOKEN = bot.token;

bot.on('photo', async (ctx) => {
  const photoFileId = ctx.message.photo[ctx.message.photo.length - 1].file_id;

  try {
    // 第一步:调用getFile API获取file_path
    const getFileRes = await axios.get(`https://api.telegram.org/bot${BOT_TOKEN}/getFile`, {
      params: { file_id: photoFileId }
    });

    const file_path = getFileRes.data.result.file_path;
    const downloadUrl = `https://api.telegram.org/file/bot${BOT_TOKEN}/${file_path}`;

    // 第二步:下载并保存文件,逻辑和方法一一致
    const downloadRes = await axios({
      url: downloadUrl,
      method: 'GET',
      responseType: 'stream'
    });

    const savePath = `./downloaded_${Date.now()}.jpg`;
    const writer = fs.createWriteStream(savePath);

    downloadRes.data.pipe(writer);

    writer.on('finish', () => {
      console.log(`图片保存完成:${savePath}`);
      ctx.reply('图片下载成功!');
    });
  } catch (err) {
    console.error('出错了:', err);
    ctx.reply('操作失败,请重试😢');
  }
});

bot.launch();

关键注意事项

  • 安装依赖:别忘了安装需要的包,执行npm install telegraf axios(用axios的话),如果用node-fetch就装npm install telegraf node-fetch。
  • 文件权限:确保你的Node.js进程有写入本地文件的权限,不然会保存失败。
  • 文件名处理:可以用fileInfo.file_name(如果Telegram返回了文件名)来命名,避免重复;也可以用时间戳来生成唯一文件名。
  • 大文件优化:用流(stream)的方式下载大文件,比直接下载到内存更高效,不会导致内存溢出。

内容的提问来源于stack exchange,提问作者tesfalem mesele

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 04:42:52