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

基于python-telegram-bot实现按钮兼具用户消息发送与回调触发功能

实现Telegram按钮同时触发回调+模拟用户发送消息(python-telegram-bot)

可以实现你的需求,下面提供两种适配不同场景的解决方案,基于python-telegram-bot框架:

方案一:用ReplyKeyboardButtons实现原生用户视角消息(推荐)

ReplyKeyboardButtons点击后会自动以用户身份发送按钮文本到聊天框,同时我们可以通过存储消息关联关系,触发对应回调逻辑,完美匹配你的需求:

步骤1:发送带关联配置的按钮消息

当管理员给用户推送带按钮的消息时,将消息ID、按钮文本与回调函数的映射关系存入chat_data,确保后续能关联到原消息:

from telegram import ReplyKeyboardMarkup, ReplyKeyboardRemove
from telegram.ext import CommandHandler, MessageHandler, Filters

def send_button_msg(update, context):
    chat_id = update.effective_chat.id
    # 原消息内容
    content = "请选择回复选项:"
    # 定义按钮文本与回调标识的映射
    btn_config = [
        {"text": "同意", "callback": "handle_agree"},
        {"text": "拒绝", "callback": "handle_refuse"}
    ]
    # 构建键盘
    keyboard = [[btn["text"]] for btn in btn_config]
    reply_markup = ReplyKeyboardMarkup(keyboard, one_time_keyboard=True)
    # 发送消息并获取原消息ID
    sent_msg = context.bot.send_message(chat_id, content, reply_markup=reply_markup)
    msg_id = sent_msg.message_id
    # 存储关联信息到chat_data
    context.chat_data[msg_id] = {
        "btn_map": {b["text"]: b["callback"] for b in btn_config},
        "original_msg_id": msg_id
    }

步骤2:处理用户发送的按钮文本

捕获用户发送的文本,匹配chat_data中的按钮映射,执行对应回调逻辑并关联原消息:

# 预定义回调函数
def handle_agree(update, context, original_msg_id):
    # 这里写同意操作的逻辑,比如关联原消息ID处理业务
    update.message.reply_text(f"已处理您对消息[{original_msg_id}]的同意请求")

def handle_refuse(update, context, original_msg_id):
    update.message.reply_text(f"已处理您对消息[{original_msg_id}]的拒绝请求")

# 消息处理器
def process_btn_reply(update, context):
    user_text = update.message.text
    # 遍历存储的消息配置,匹配按钮文本
    for msg_id, config in list(context.chat_data.items()):
        if user_text in config["btn_map"]:
            callback_func = config["btn_map"][user_text]
            original_msg_id = config["original_msg_id"]
            # 执行对应回调
            globals()[callback_func](update, context, original_msg_id)
            # 清理已处理的配置(避免重复匹配)
            del context.chat_data[msg_id]
            # 移除键盘(可选)
            context.bot.send_message(update.effective_chat.id, "回复已记录", reply_markup=ReplyKeyboardRemove())
            return
    # 非按钮文本的处理
    update.message.reply_text("请通过按钮回复")

步骤3:注册处理器

def main():
    updater = Updater("YOUR_BOT_TOKEN")
    dp = updater.dispatcher
    dp.add_handler(CommandHandler("send_btn", send_button_msg))
    dp.add_handler(MessageHandler(Filters.text & ~Filters.command, process_btn_reply))
    updater.start_polling()
    updater.idle()

if __name__ == "__main__":
    main()

方案二:用InlineKeyboardButton模拟用户消息效果

如果需要保留InlineKeyboard的回调特性,同时模拟用户发送消息的视觉效果,可以在回调函数中让机器人发送一条带用户昵称前缀的消息,再执行回调逻辑:

from telegram import InlineKeyboardButton, InlineKeyboardMarkup
from telegram.ext import CallbackQueryHandler

def send_inline_btn(update, context):
    chat_id = update.effective_chat.id
    content = "请选择回复选项:"
    # 发送初始消息
    sent_msg = context.bot.send_message(chat_id, content)
    msg_id = sent_msg.message_id
    # 构建Inline按钮,data包含回调标识和原消息ID
    keyboard = [
        [InlineKeyboardButton("同意", data=f"agree:{msg_id}")],
        [InlineKeyboardButton("拒绝", data=f"refuse:{msg_id}")]
    ]
    reply_markup = InlineKeyboardMarkup(keyboard)
    # 编辑消息添加按钮
    context.bot.edit_message_text(content, chat_id, msg_id, reply_markup=reply_markup)

def process_inline_callback(update, context):
    query = update.callback_query
    query.answer()
    # 解析回调数据
    callback_tag, original_msg_id = query.data.split(":")
    btn_text = query.text
    user_name = update.effective_user.first_name
    # 模拟用户发送消息的视觉效果
    context.bot.send_message(update.effective_chat.id, f"{user_name}:{btn_text}")
    # 执行回调逻辑
    if callback_tag == "agree":
        handle_agree(update, context, original_msg_id)
    elif callback_tag == "refuse":
        handle_refuse(update, context, original_msg_id)
    # 移除按钮(可选)
    query.edit_message_reply_markup(reply_markup=None)

# 注册处理器
dp.add_handler(CommandHandler("send_inline", send_inline_btn))
dp.add_handler(CallbackQueryHandler(process_inline_callback))

关键说明

  • 方案一完全满足“用户视角消息气泡+回调触发+关联原消息”的需求,是最优解;
  • 方案二更适合依赖InlineKeyboard特性的场景,但消息实际发送者仍是机器人;
  • 两种方案都通过chat_data或按钮data字段关联原消息ID,支持用户跨消息顺序回复。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 03:04:56