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

Node环境下如何为telegrap.js Telegram Bot添加express API路由

Telegraf.js 搭配 Express 实现外部API触发Bot发PDF到频道

核心逻辑:不存在“为Telegraf.js绑定Express路由”的特殊封装。Telegraf仅负责和Telegram服务端通信,Express是独立的HTTP服务,二者运行在同个Node进程时,Express路由的处理逻辑中可以直接调用Bot实例的通信方法,不需要做额外的适配绑定。

实现步骤

1. 安装依赖

需要安装的核心包和功能包:

  • telegraf:Telegram 官方推荐的Node.js Bot SDK
  • express:HTTP路由框架
  • pdfkit:用于内存生成PDF文件,无需写本地临时文件
  • cors:按需安装,处理跨域请求
    安装命令:
npm install telegraf express pdfkit cors

2. 初始化服务实例

全局只初始化一次Bot和Express实例,避免重复连接导致的异常:

const { Telegraf } = require('telegraf');
const express = require('express');
const PDFDocument = require('pdfkit');
const cors = require('cors');

// 配置项替换成你自己的参数
const BOT_TOKEN = '你的Telegram Bot Token';
const TARGET_CHANNEL_ID = '目标频道ID,公开频道填@频道用户名,私有频道填-100开头的数字ID';
const PORT = 3000;

const bot = new Telegraf(BOT_TOKEN);
const app = express();

// 基础中间件
app.use(cors());
app.use(express.json({ limit: '10mb' })); // 调整请求体大小限制适配大参数

3. 编写自定义触发API路由

以POST接口/api/generate-and-send-pdf为例,接口接收JSON参数,生成PDF后直接发送到目标频道:

app.post('/api/generate-and-send-pdf', async (req, res) => {
  try {
    // 校验必填参数,按需调整你需要的字段
    const { title, content, operator } = req.body;
    if (!title || !content) {
      return res.status(400).json({ code: 400, msg: '缺少必填参数:title、content' });
    }

    // 内存中生成PDF流,不写入本地磁盘,减少IO开销和临时文件清理问题
    const doc = new PDFDocument();
    const chunks = [];
    doc.on('data', chunk => chunks.push(chunk));
    const pdfBuffer = await new Promise((resolve, reject) => {
      doc.on('end', () => resolve(Buffer.concat(chunks)));
      doc.on('error', reject);
      // 自定义PDF排版,按需调整
      doc.fontSize(20).text(title, { align: 'center' });
      doc.moveDown();
      doc.fontSize(12).text(content, { lineGap: 6 });
      doc.moveDown(2);
      doc.fontSize(10).text(`生成时间:${new Date().toLocaleString('zh-CN')}`, { align: 'right' });
      if (operator) doc.text(`操作人:${operator}`, { align: 'right' });
      doc.end();
    });

    // 调用Bot能力发送PDF到目标频道
    await bot.telegram.sendDocument(
      TARGET_CHANNEL_ID,
      { source: pdfBuffer, filename: `${title}.pdf` },
      { caption: `文档自动推送:${title}` }
    );

    return res.status(200).json({ code: 200, msg: 'PDF生成并发送成功' });
  } catch (err) {
    console.error('请求处理失败:', err);
    return res.status(500).json({ code: 500, msg: '服务内部错误', error: err.message });
  }
});

4. 启动服务

根据部署场景二选一即可:

开发调试:长轮询模式

不需要公网IP,本地就能跑,适合开发阶段调试:

bot.launch().then(() => console.log('Bot长轮询连接成功'));
app.listen(PORT, () => {
  console.log(`服务启动成功,端口:${PORT}`);
  console.log(`本地触发接口:POST http://localhost:${PORT}/api/generate-and-send-pdf`);
});

// 优雅退出
process.once('SIGINT', () => bot.stop('SIGINT'));
process.once('SIGTERM', () => bot.stop('SIGTERM'));

生产部署:Webhook模式

性能更好,不需要维持长连接,要求服务有公网可访问的HTTPS域名:

// webhook路径加随机字符串避免被恶意扫描
const WEBHOOK_PATH = `/tg-bot-webhook-${Math.random().toString(36).slice(2)}`;
app.use(bot.webhookCallback(WEBHOOK_PATH));

app.listen(PORT, async () => {
  const webhookUrl = `https://你的公网域名${WEBHOOK_PATH}`;
  await bot.telegram.setWebhook(webhookUrl);
  console.log(`服务启动成功,端口:${PORT}`);
  console.log(`Webhook已配置:${webhookUrl}`);
  console.log(`线上触发接口:POST https://你的公网域名/api/generate-and-send-pdf`);
});

常见踩坑点

  • Bot权限:必须把Bot拉进目标频道,设置为管理员,开启「发送消息」「发送文档」权限,否则会抛出403无权限错误
  • 频道ID获取:私有频道的ID是-100开头的长数字,可以在长轮询模式下给频道发一条消息,调用bot.telegram.getUpdates()查看返回的chat.id字段获取
  • 文件大小限制:Telegram Bot单次发送的文件最大为50MB,生成的PDF超过限制时需要先上传到对象存储,再调用sendDocument传文件链接发送
  • 接口鉴权:生产环境一定要给自定义API加鉴权逻辑(比如请求头校验固定token),避免被恶意调用刷频道消息
  • 实例复用:不要在路由处理函数内初始化Telegraf实例,全局复用同一个实例即可,否则会出现重复接收消息、连接泄漏的问题

内容的提问来源于stack exchange,提问作者Hyperledger Q

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 07:54:23