如何通过Telegram Bot API发送超1GB大文件?Express框架
Telegram Bot 发送超过50MB大文件到私人频道的实现指南
核心原理
Telegram Bot API默认的sendDocument/sendVideo等方法仅支持最大50MB的文件,但通过**分块上传(Resumable Upload)**方式,可发送最大2GB的文件。分块上传会将大文件拆分为5MB-50MB的小块,依次上传到Telegram的服务器,完成后获取file_id,再用该ID发送文件到频道。
分步实现(Node.js + Express)
方法一:使用node-telegram-bot-api库(推荐,内置分块支持)
这个库会自动处理分块逻辑,无需手动拆分文件。
- 安装依赖
npm install node-telegram-bot-api
- 实现发送逻辑
const TelegramBot = require('node-telegram-bot-api'); const express = require('express'); const app = express(); // 初始化Bot,关闭polling(Express项目无需主动轮询) const bot = new TelegramBot('你的Bot Token', { polling: false }); // 发送大文件的异步函数 async function sendLargeFileToChannel(channelId, filePath) { try { // 用sendDocument发送,支持任意类型文件(最大2GB),如果是视频也可用sendVideo const result = await bot.sendDocument(channelId, filePath, { chunkSize: 5 * 1024 * 1024, // 设置5MB分块,可选,默认值为5MB caption: '大文件测试' // 可选,文件描述 }); console.log(`文件发送成功,消息ID:${result.message_id}`); return true; } catch (err) { console.error('发送失败:', err.message); return false; } } // Express路由示例 app.post('/send-large-file', async (req, res) => { // 私人频道ID,格式为@频道用户名 或 -100开头的数字ID const channelId = '@your_private_channel'; // 本地大文件路径(如果是用户上传的文件,需先保存到服务器本地) const filePath = '/path/to/your/large_file.mp4'; const success = await sendLargeFileToChannel(channelId, filePath); res.status(success ? 200 : 500).send(success ? '发送成功' : '发送失败'); }); app.listen(3000, () => console.log('Express服务启动,端口3000'));
方法二:手动实现分块上传(灵活控制上传流程)
如果需要更精细的控制(比如断点续传),可以手动调用Telegram的上传API。
- 安装依赖
npm install axios form-data express
- 实现分块上传与发送
const axios = require('axios'); const FormData = require('form-data'); const fs = require('fs'); const path = require('path'); const express = require('express'); const app = express(); const BOT_TOKEN = '你的Bot Token'; const CHANNEL_ID = '@your_private_channel'; // 分块上传核心函数 async function uploadAndSendLargeFile(filePath) { // 1. 获取Telegram上传服务器地址 const uploadServerResp = await axios.get(`https://api.telegram.org/bot${BOT_TOKEN}/getUploadServer`, { params: { file_type: 'document' } // 指定文件类型,document支持任意文件 }); const uploadUrl = uploadServerResp.data.result.upload_url; // 2. 获取文件信息 const fileStats = fs.statSync(filePath); const fileSize = fileStats.size; const chunkSize = 5 * 1024 * 1024; // 5MB分块,必须在5MB-50MB之间 let offset = 0; // 3. 循环上传分块 while (offset < fileSize) { const end = Math.min(offset + chunkSize, fileSize); // 读取当前分块的二进制数据 const chunk = fs.readFileSync(filePath, { start: offset, end: end - 1 }); const formData = new FormData(); formData.append('file', chunk, { filename: path.basename(filePath) }); formData.append('offset', offset.toString()); // 最后一块标记为final if (end === fileSize) formData.append('final', 'true'); const uploadResp = await axios.post(uploadUrl, formData, { headers: formData.getHeaders() }); if (!uploadResp.data.ok) throw new Error(`分块上传失败: ${uploadResp.data.description}`); offset = end; console.log(`已上传 ${(offset / fileSize * 100).toFixed(2)}%`); // 上传完成后,获取file_id并发送到频道 if (end === fileSize) { const fileId = uploadResp.data.result.file_id; await axios.post(`https://api.telegram.org/bot${BOT_TOKEN}/sendDocument`, { chat_id: CHANNEL_ID, document: fileId, caption: '手动分块上传的大文件' }); console.log('文件发送完成'); } } } // Express路由 app.post('/manual-send-large-file', async (req, res) => { const filePath = '/path/to/your/large_file.mp4'; try { await uploadAndSendLargeFile(filePath); res.status(200).send('发送成功'); } catch (err) { res.status(500).send(`发送失败: ${err.message}`); } }); app.listen(3000, () => console.log('Express服务启动,端口3000'));
关键注意事项
- Bot权限:确保你的Bot是目标私人频道的管理员,拥有「发送消息」和「上传文件」的权限。
- 文件类型:用
sendDocument发送可避开媒体编码限制(比如视频格式要求),仅受2GB大小限制;如果用sendVideo,需确保视频符合Telegram的编码规范(如MP4、H.264编码等)。 - 分块大小:必须设置在5MB-50MB之间,过小会增加请求次数,过大易导致超时。
- 断点续传:手动实现时,可记录当前上传的
offset,如果上传中断,下次从该位置继续上传。 - 磁盘空间:如果是处理用户上传的文件,建议直接从请求流中读取分块,避免将完整大文件保存到服务器磁盘。
内容的提问来源于stack exchange,提问作者mirco crescente
相关产品推荐
相关产品推荐

