Node.js Telegraf机器人函数内reply失效及Promise返回问题排查
修复Telegraf维基百科爬虫机器人的无响应、Promise报错问题
核心问题分析
- 错误的事件绑定逻辑:原代码中
bot.on("message", getData())直接执行了getData函数,而非传入事件处理回调,导致初始化阶段就触发一次爬虫逻辑,后续用户消息无法被正确监听;同时getData内部重复绑定bot.on("message"),造成逻辑彻底混乱。 - 全局变量引发并发问题:用全局
input存储用户输入,多用户交互时会出现数据覆盖,且无法实时获取当前消息的输入内容。 - 异步操作不规范:
browser.close()未加await,可能导致浏览器在页面操作完成前就关闭;异步函数未正确等待执行结果,引发[Promise object]相关报错。 - 缺失错误捕获:没有处理爬虫或Telegraf操作中的异常,导致出现"unhandled error while processing message"错误。
修复后的完整代码
import puppeteer from "puppeteer"; import { Telegraf } from "telegraf"; const bot = new Telegraf("bot token here"); // 接收ctx参数,从上下文获取用户输入,返回抓取的文本内容 const getData = async (ctx) => { let browser; try { const input = ctx.message.text.trim(); if (!input) { return "请输入要搜索的内容"; } browser = await puppeteer.launch(); const page = await browser.newPage(); // 对用户输入进行URL编码,避免特殊字符导致请求失败 await page.goto(`https://fa.wikipedia.org/w/index.php?search=${encodeURIComponent(input)}&title=%D9%88%DB%8C%DA%98%D9%87%3A%D8%AC%D8%B3%D8%AA%D8%AC%D9%88&ns0=1`, { timeout: 0 }); const searchResult = await page.$(".mw-search-result-heading > a[data-serp-pos='0']"); let textReply; if (!searchResult) { // 当前页面直接取第一段文本 const maghale = await page.$('p'); textReply = maghale ? await maghale.evaluate(el => el.textContent.trim()) : "未找到相关内容"; } else { // 跳转到搜索结果页面取第一段文本 const maghaleLink = await searchResult.evaluate(el => el.href); await page.goto(maghaleLink, { timeout: 0 }); const maghale1 = await page.$('p'); textReply = maghale1 ? await maghale1.evaluate(el => el.textContent.trim()) : "未找到相关内容"; } return textReply; } catch (error) { console.error("抓取出错:", error); return "搜索过程中出现错误,请稍后重试"; } finally { // 确保浏览器无论成功失败都能关闭 if (browser) { await browser.close(); } } }; bot.start(ctx => ctx.reply("salam mashti")); // 正确绑定消息事件:收到消息后调用getData,等待结果再回复用户 bot.on("message", async ctx => { const result = await getData(ctx); await ctx.reply(result); }); bot.launch();
关键改动说明
- 事件绑定修正:改用
async ctx => { ... }作为消息处理回调,确保每次用户发送消息时才触发爬虫逻辑,而非初始化阶段执行。 - 移除全局变量:直接从
ctx.message.text获取当前用户的输入内容,避免多用户并发时的数据冲突。 - 异步操作规范:用
try/finally块确保浏览器实例被正确关闭;所有异步操作都添加await,避免Promise未处理的问题。 - 错误处理完善:添加
try/catch捕获爬虫过程中的异常,返回友好提示的同时打印错误日志,便于排查问题。 - 输入安全处理:用
encodeURIComponent对用户输入进行编码,避免特殊字符导致URL无效。
内容的提问来源于stack exchange,提问作者aghasibil
相关产品推荐
相关产品推荐

