Node.js Telegram Bot的sendPhoto无报错但无法发送图片问题
Telegram Bot部署在AWS Lambda(Docker镜像)中sendPhoto无输出但无报错的问题排查方案
核心问题分析
你的Lambda函数执行日志显示流程完成,但Bot未发送任何消息,本质是sendPhoto或后续操作隐性失败,现有代码未捕获错误详情,加上Lambda环境的网络、资源限制特性,导致问题被隐藏。
排查与修复步骤
1. 捕获完整错误信息,定位根源
现有catch块未捕获错误对象,无法知晓sendPhoto的具体失败原因。修改代码,打印完整错误日志:
const { createCanvas } = require("canvas"); const telegramBot = require("node-telegram-bot-api"); // 显式关闭polling,适配Lambda无服务器环境 const bot = new telegramBot("5233454187:XXXXX", { polling: false }); exports.handler = async function (event, context) { console.log("Inside the func"); const canvas = createCanvas(200, 200); const ctx = canvas.getContext("2d"); // 替换为镜像中存在的字体,避免渲染失败 ctx.font = "20px Liberation Sans"; ctx.fillStyle = "black"; ctx.fillText(Math.random().toString(), 20, 50, 150); try { const buffer = canvas.toBuffer(); console.log("生成的图片buffer大小:", buffer.length); // 验证buffer有效性 // 指定文件名和MIME类型,帮助Telegram识别图片 await bot.sendPhoto("-1001177958034", buffer, { filename: "random-number.png", contentType: "image/png" }); console.log("sendPhoto执行成功"); } catch (err) { console.error("sendPhoto失败详情:", err); // 打印完整错误栈 // 尝试发送错误消息,同时捕获sendMessage的失败 await bot.sendMessage("-1001177958034", `错误详情:${err.message}`).catch(msgErr => { console.error("sendMessage也失败:", msgErr); }); } };
2. 检查Lambda网络访问权限
- 如果Lambda配置在VPC内,必须确保有NAT网关或互联网网关,允许出站访问
api.telegram.org(HTTPS 443端口) - 安全组出站规则需放行HTTPS流量到公网
- 若Lambda不在VPC,默认具备公网访问权限,可通过测试调用
https://api.telegram.org/bot<你的token>/getMe验证网络连通性
3. 修复Canvas字体依赖问题
Lambda基础镜像默认没有Arial字体,会导致文字渲染失败,生成空图片。在Dockerfile中添加字体安装步骤:
ARG ARCH=arm64 FROM public.ecr.aws/lambda/nodejs:18-${ARCH} COPY . ${LAMBDA_TASK_ROOT} RUN yum update -y && \ yum groupinstall "Development Tools" -y && \ # 添加字体包,同时清理yum缓存减小镜像体积 yum install -y gcc-c++ cairo-devel pango-devel libjpeg-turbo-devel giflib-devel librsvg2-devel pango-devel bzip2-devel jq python3 liberation-sans-fonts && \ yum clean all && rm -rf /var/cache/yum RUN mkdir ${LAMBDA_TASK_ROOT}/lib RUN npm install canvas --build-from-source RUN npm install CMD [ "index.handler" ]
4. 调整Lambda超时时间
Lambda默认超时时间为3秒,若sendPhoto因网络延迟超时,函数会被静默终止。在Lambda控制台将超时时间调整为10秒以上再测试。
额外优化建议
- 将Bot Token和Chat ID存入Lambda环境变量,避免硬编码:
const botToken = process.env.TELEGRAM_BOT_TOKEN; const chatId = process.env.TELEGRAM_CHAT_ID; const bot = new telegramBot(botToken, { polling: false });
内容的提问来源于stack exchange,提问作者Emiliano
相关产品推荐
相关产品推荐

