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

如何让Telegram Bot仅点击按钮才依次展示内容,避免循环一次性全发

实现分步展示消息的解决方案

核心思路

  • 提前过滤所有符合条件的职位,不要在循环里直接发送消息
  • 给每个用户维护独立的浏览状态:待展示职位列表、当前浏览的索引位置
  • 新增「下一条」回调按钮,通过按钮点击事件触发下一条消息的发送,替代原有的一次性循环发送逻辑

代码实现示例

首先定义用户状态存储结构(生产环境可替换为Redis、数据库等持久化存储):

# 存储每个用户的职位浏览状态,key为用户chat_id,value为{'jobs': 匹配的职位列表, 'index': 当前浏览索引}
user_job_state = {}

替换原有循环发送的逻辑:

# 第一步:先过滤出所有符合条件的职位
matched_jobs = []
for job in jobs:
    # 原有条件存在运算符优先级问题,已为性别判断增加括号修正逻辑
    if int(job[6]) <= int(user.dpr) and int(job[7]) <= int(user.profil) and (job[4] == user.sex or job[5] == user.sex):
        matched_jobs.append(job)

# 存储用户状态
chat_id = message.chat.id
user_job_state[chat_id] = {
    'jobs': matched_jobs,
    'index': 0
}

# 第二步:发送第一条职位(如果有匹配结果)
if not matched_jobs:
    bot.send_message(chat_id, "暂无符合条件的职位")
else:
    # 生成带跳转按钮和下一条按钮的键盘
    def gen_first_markup(job):
        markup = InlineKeyboardMarkup()
        markup.row_width = 1
        markup.add(InlineKeyboardButton(text='לאתר מתגייסים', url=job[3]))
        # 只有不止一个职位的时候才加下一条按钮
        if len(matched_jobs) > 1:
            markup.add(InlineKeyboardButton(text='下一个职位', callback_data='next_job'))
        return markup
    
    first_job = matched_jobs[0]
    bot.send_message(chat_id, f"<b>{first_job[1]}</b>\n{first_job[2]}", 
                    reply_markup=gen_first_markup(first_job), 
                    parse_mode='HTML')

新增「下一个职位」回调事件处理逻辑:

# 处理「下一个职位」的回调事件
@bot.callback_query_handler(func=lambda call: call.data == 'next_job')
def handle_next_job(call):
    chat_id = call.message.chat.id
    # 检查用户有没有待浏览的职位
    if chat_id not in user_job_state:
        bot.answer_callback_query(call.id, "请先触发职位查询")
        return
    
    state = user_job_state[chat_id]
    next_index = state['index'] + 1
    total = len(state['jobs'])
    
    # 已经到最后一条
    if next_index >= total:
        bot.answer_callback_query(call.id, "已经是最后一个职位了")
        return
    
    # 更新索引
    state['index'] = next_index
    current_job = state['jobs'][next_index]
    
    # 生成当前职位的键盘
    def gen_current_markup():
        markup = InlineKeyboardMarkup()
        markup.row_width = 1
        markup.add(InlineKeyboardButton(text='לאתר מתגייסים', url=current_job[3]))
        # 还有下一条才加下一条按钮
        if next_index < total - 1:
            markup.add(InlineKeyboardButton(text='下一个职位', callback_data='next_job'))
        return markup
    
    # 发送新的职位消息
    bot.send_message(chat_id, f"<b>{current_job[1]}</b>\n{current_job[2]}",
                    reply_markup=gen_current_markup(),
                    parse_mode='HTML')
    # 回应对调请求
    bot.answer_callback_query(call.id)

注意事项

  • 原代码的筛选逻辑存在运算符优先级问题,and优先级高于or,会导致性别筛选逻辑不符合预期,示例代码中已经为性别判断条件增加了括号修正逻辑
  • 如果需要支持多用户同时使用,不要用全局变量存储状态,生产环境建议使用Redis、数据库等持久化存储用户浏览状态
  • 如果需要支持用户退出后重新进入还能接着看,可以把状态存储到用户表对应的字段里
  • 回调数据如果需要区分不同的查询场景,可以在callback_data里加额外标识,避免和其他回调事件冲突

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 16:45:03