Node-Telegram-Bot-API中内联按钮点击回调查询引发重复消息的修改方案问询
解决Node-Telegram-Bot-API中内联按钮回调查询重复发送消息的问题
这个问题我之前踩过坑!本质原因是Telegram的回调请求重试机制:当用户点击内联按钮后,Telegram会发送回调请求给你的机器人,如果机器人没有明确确认收到这个请求,Telegram会在一段时间内反复重试发送同一回调,导致你的sendDocument被多次触发,最终出现重复消息。
你需要做两个关键修改:
必须调用
answerCallbackQuery确认回调请求
Telegram要求机器人在收到回调后必须回复answerCallbackQuery,否则它会认为请求未送达,持续重试。这是解决重复问题的核心。避免使用全局的
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
相关产品推荐
相关产品推荐

