Telegram getUpdates API添加offset参数后仍重复返回旧更新问题求助
Telegram getUpdates API重复返回旧更新的排查与解决
我之前也碰到过类似的问题,结合你的描述,大概率是这几个环节出了问题,咱们一步步来梳理:
1. 先修正request模块的参数传递方式
你提到的requestOptions里用了data字段来传递offset,但在request模块中,当设置json: true时,POST请求的JSON数据应该放在body字段里,而不是data。如果用错了字段,Telegram的API根本接收不到你的offset参数,自然会一直返回最旧的更新。
修正后的请求配置应该是这样:
const requestOptions = { method: 'POST', url: 'https://api.telegram.org/bot<你的BotToken>/getUpdates', json: true, body: { offset: latestOffset } // 用body替代data };
2. 确保offset是动态实时更新的
你说已经尝试用最大update_id或加1,但要注意:每次获取到更新后,必须实时更新offset的值,而不是一直用固定的初始值。具体步骤:
- 每次拿到返回的
updates数组后,提取所有update_id并找出最大值 - 把下一次请求的offset设为这个最大值加1
- 这个
latestOffset必须是全局/闭包变量,保证每次请求都用最新的数值
示例代码片段:
// 假设你从响应里拿到了updates数组 const updates = response.body.result; if (updates.length > 0) { // 提取所有update_id并取最大值 const maxUpdateId = Math.max(...updates.map(item => item.update_id)); // 更新offset为最大值+1,确保下次只获取新更新 latestOffset = maxUpdateId + 1; }
3. 换掉setInterval,改用Telegram原生长轮询模式
Telegram的getUpdates支持长轮询,通过timeout参数可以让请求挂起直到有新消息或超时(建议设30秒),比每秒轮询更高效,也能避免短间隔请求导致的重复返回问题。
推荐用递归回调的方式发起轮询,而不是setInterval:
let latestOffset = 0; function pollTelegramUpdates() { const requestOptions = { method: 'POST', url: 'https://api.telegram.org/bot<你的BotToken>/getUpdates', json: true, body: { offset: latestOffset, timeout: 30 // 长轮询超时时间,单位秒 } }; request(requestOptions, (err, res, body) => { if (!err && res.statusCode === 200) { const updates = body.result; if (updates.length > 0) { // 这里处理你的消息逻辑 console.log('收到新消息:', updates); // 更新offset const maxUpdateId = Math.max(...updates.map(item => item.update_id)); latestOffset = maxUpdateId + 1; } // 完成当前请求后立即发起下一次轮询 pollTelegramUpdates(); } else { console.error('请求失败:', err || `状态码: ${res.statusCode}`); // 出错后延迟5秒再重试,避免频繁请求 setTimeout(pollTelegramUpdates, 5000); } }); } // 启动轮询 pollTelegramUpdates();
4. 额外排查点
- 打印每次请求的
offset和返回的update_id,确认offset确实被正确传递,且返回的update_id都大于等于你设置的offset - 确认你的Bot Token没有写错,避免请求到错误的bot实例
内容的提问来源于stack exchange,提问作者Jenny L.
相关产品推荐
相关产品推荐

