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

Node-Telegram-Bot-API中内联按钮点击回调查询引发重复消息的修改方案问询

解决Node-Telegram-Bot-API中内联按钮回调查询重复发送消息的问题

这个问题我之前踩过坑!本质原因是Telegram的回调请求重试机制:当用户点击内联按钮后,Telegram会发送回调请求给你的机器人,如果机器人没有明确确认收到这个请求,Telegram会在一段时间内反复重试发送同一回调,导致你的sendDocument被多次触发,最终出现重复消息。

你需要做两个关键修改:

  1. 必须调用answerCallbackQuery确认回调请求
    Telegram要求机器人在收到回调后必须回复answerCallbackQuery,否则它会认为请求未送达,持续重试。这是解决重复问题的核心。

  2. 避免使用全局的userChatId,从回调数据中获取聊天ID
    你的代码里用了全局变量userChatId,如果有多个用户同时使用机器人,很容易出现消息发错对象的问题。应该从回调的message对象里直接取聊天ID,更安全可靠。

修改后的完整代码:

var keyboard = [];
movieRatingList.map((movie, idx) => {
    var movieRating = Math.round(movie.rating * 10) / 10;
    if (movieRating == bestRating) {
        var firstName = movieList[idx].firstName;
        keyboard.push([{ text: firstName, callback_data: idx }]);
    }
});
bot.sendMessage(userChatId, userText, {
    reply_markup: JSON.stringify({
        resize_keyboard: true,
        inline_keyboard: keyboard,
    }),
});
bot.on("callback_query", (callBackData) => {
    // 第一步:立即确认回调,阻止Telegram重试
    bot.answerCallbackQuery(callBackData.id, {
        text: '正在发送文档,请稍等...', // 可选:给用户的反馈提示
        show_alert: false // 是否弹窗显示,默认false即可
    });

    // 第二步:从回调数据中获取正确的聊天ID
    const chatId = callBackData.message.chat.id;
    var idx = Number(callBackData.data);
    var fileID = movieList[idx].file_id;
    var firstName = movieList[idx].firstName;
    console.log(fileID);
    console.log(firstName);
    bot.sendDocument(chatId, fileID, { caption: firstName });
});

补充说明:

  • answerCallbackQuery的text参数是可选的,如果不需要给用户提示,可以直接传空字符串'',但必须调用这个方法。
  • 如果你担心回调处理耗时较长,可以先调用answerCallbackQuery确认,再处理后续的发送文档逻辑,这样用户不会看到按钮一直处于加载状态,体验更好。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.27 19:28:10