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

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();

关键改动说明

  1. 事件绑定修正:改用async ctx => { ... }作为消息处理回调,确保每次用户发送消息时才触发爬虫逻辑,而非初始化阶段执行。
  2. 移除全局变量:直接从ctx.message.text获取当前用户的输入内容,避免多用户并发时的数据冲突。
  3. 异步操作规范:用try/finally块确保浏览器实例被正确关闭;所有异步操作都添加await,避免Promise未处理的问题。
  4. 错误处理完善:添加try/catch捕获爬虫过程中的异常,返回友好提示的同时打印错误日志,便于排查问题。
  5. 输入安全处理:用encodeURIComponent对用户输入进行编码,避免特殊字符导致URL无效。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 02:07:46