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

Telegraf开发Telegram机器人如何让inline keyboard在所有回复发送后再显示

问题根源

你的代码存在两个核心问题导致键盘提前弹出:

  • ctx.replyWithVideo 是异步方法,返回Promise对象,你使用forEach遍历调用时,不会等待所有异步发送任务执行完成,就直接执行了后续的sendOptionsKeyboard逻辑
  • sendOptionsKeyboard 放在了try/catch块外部,即便发送流程出错,也会弹出选择键盘,不符合预期逻辑
可行解决方案

把遍历发送gif的逻辑改为等待所有异步任务完成后,再调用发送键盘的方法,推荐两种实现方式:

方式1:使用for...of串行发送(适合低并发场景,请求顺序可控)

const showSpecificGif = async (ctx, bot) => {
  try {
    // 先应答回调查询,避免用户端按钮长时间显示加载状态
    await ctx.answerCbQuery()
    await ctx.reply('Loading...🤔')
    const offset = Math.floor(Math.random() * 4500)
    const res = await axios.get(
      `https://api.giphy.com/v1/gifs/search?api_key=${process.env.GIPHY_API_KEY}&q=${ctx.update.callback_query.data}&limit=3&offset=${offset}&rating=g&lang=en`
    )
    const gifArray = res.data.data
    // 用for...of等待每一张gif发送完成再发下一张
    for (const gif of gifArray) {
      await ctx.replyWithVideo(gif.images.downsized_medium.url)
    }
    // 所有gif发送完成后再弹出选择键盘
    await sendOptionsKeyboard(ctx, bot, 'Send again? 😀')
  } catch (err) {
    await ctx.reply('You got error')
    // 出错后也可以选择弹出键盘让用户重试,不需要就删掉下面这行
    await sendOptionsKeyboard(ctx, bot, 'Try again? 😀')
  }
}

方式2:使用Promise.all并行发送(适合需要提升发送速度的场景)

如果不需要严格按接口返回的gif顺序发送,可以用Promise.all等待所有发送请求同时完成:

const showSpecificGif = async (ctx, bot) => {
  try {
    await ctx.answerCbQuery()
    await ctx.reply('Loading...🤔')
    const offset = Math.floor(Math.random() * 4500)
    const res = await axios.get(
      `https://api.giphy.com/v1/gifs/search?api_key=${process.env.GIPHY_API_KEY}&q=${ctx.update.callback_query.data}&limit=3&offset=${offset}&rating=g&lang=en`
    )
    const gifArray = res.data.data
    // 批量生成发送任务,等待所有任务执行完成
    const sendTasks = gifArray.map(gif => ctx.replyWithVideo(gif.images.downsized_medium.url))
    await Promise.all(sendTasks)
    await sendOptionsKeyboard(ctx, bot, 'Send again? 😀')
  } catch (err) {
    await ctx.reply('You got error')
    await sendOptionsKeyboard(ctx, bot, 'Try again? 😀')
  }
}
额外优化点
  • 所有调用Telegram API的方法最好都加await,避免出现异步顺序问题
  • 回调触发后优先调用ctx.answerCbQuery(),符合Telegram bot的开发规范,避免用户端出现按钮无响应的报错提示

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 14:06:02