很多新手在使用Telegram机器人时,发现别人的机器人底部有漂亮的按钮菜单,点击就能触发功能,而自己的机器人却只有纯文字回复。这是因为机器人缺少了内联键盘按钮或回复键盘按钮的配置。本文将手把手教你如何为Telegram机器人添加按钮,让你的机器人变得可交互。
检查准备工作:确认机器人Token与开发环境
在开始添加按钮之前,需要确保你已经拥有一个Telegram机器人,并且能正常接收和回复消息。如果还没创建机器人,或不清楚Token是什么,请先完成以下准备。
具体操作说明:
1. 打开Telegram,搜索 @BotFather并进入对话。
2. 输入 /mybots,选择你要添加按钮的机器人。
3. 点击 API Token按钮,复制显示的Token字符串(格式类似 123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11)。
4. 确保你有一个可以运行代码的环境,例如电脑上的Python、Node.js,或使用第三方平台(如Google Colab、VPS服务器)。本教程以Python为例,你需要安装 python-telegram-bot库,在终端执行 pip install python-telegram-bot。
注意事项/小提示:
- Token是机器人的唯一凭证,不要分享给任何人,否则别人可以控制你的机器人。
- 如果使用的是Python,建议使用
python-telegram-bot版本13.x或20.x,不同版本语法略有差异,本教程基于20.x版本。 - 如果不想写代码,可以使用第三方机器人管理平台(如Manybot、BotPress),但功能会受限。
备用方案:
- 如果无法安装Python库,可以尝试使用在线代码编辑器(如Replit)并安装依赖。
- 如果不想编程,直接跳到文末的“常见问题补充”查看使用BotFather直接添加按钮的方法(仅限回复键盘)。
安装并导入所需库
需要在代码中导入Telegram机器人库,才能调用按钮相关的类和方法。
具体操作说明:
1. 在你的Python脚本文件顶部,写入以下导入语句:
`python
from telegram import Update, InlineKeyboardButton, InlineKeyboardMarkup, ReplyKeyboardMarkup, KeyboardButton
from telegram.ext import Application, CommandHandler, CallbackQueryHandler, MessageHandler, filters
`
2. 其中 InlineKeyboardButton和 InlineKeyboardMarkup用于创建内联按钮(显示在消息下方),ReplyKeyboardMarkup和 KeyboardButton用于创建回复键盘按钮(替换输入框)。
3. 确保你的Python环境已成功安装 python-telegram-bot库,如果报错请重新执行安装命令。
注意事项/小提示:
- 不同版本的库导入路径可能不同,20.x版本推荐使用上述方式。
- 如果使用
telegram.ext模块,请确认版本为20.0以上,旧版本(13.x)使用Updater而非Application。
备用方案:
- 如果使用Node.js,需要安装
node-telegram-bot-api,并导入InlineKeyboardButton等模块。 - 如果使用PHP,可使用
telegram-bot/api库。
创建内联按钮(Inline Keyboard)
内联按钮是附加在消息下方的按钮,点击后触发回调数据,机器人可以根据回调数据做出响应。
具体操作说明:
1. 定义一个函数,用于生成按钮布局。例如创建一个包含两个按钮的菜单:
`python
async def start(update: Update, context: ContextTypes.DEFAULT_TYPE):
keyboard = [
[InlineKeyboardButton("按钮1", callback_data="btn1")],
[InlineKeyboardButton("按钮2", callback_data="btn2")]
]
reply_markup = InlineKeyboardMarkup(keyboard)
await update.message.reply_text("请选择一个操作:", reply_markup=reply_markup)
`
2. 在 main函数中注册命令处理器,让用户输入 /start时触发该函数:
`python
application.add_handler(CommandHandler("start", start))
`
3. 添加回调处理器,处理用户点击按钮后的逻辑:
`python
async def button_callback(update: Update, context: ContextTypes.DEFAULT_TYPE):
query = update.callback_query
await query.answer() # 必须调用,否则按钮会一直显示加载状态
if query.data == "btn1":
await query.edit_message_text(text="你点击了按钮1")
elif query.data == "btn2":
await query.edit_message_text(text="你点击了按钮2")
application.add_handler(CallbackQueryHandler(button_callback))
`
4. 运行机器人:application.run_polling()
注意事项/小提示:
callback_data是隐藏的数据,用户看不到,用于在后台区分按钮。长度不能超过64字节。- 必须调用
await query.answer(),否则按钮会显示“加载中”且不会响应。 - 可以使用
query.edit_message_text修改原消息内容,或query.message.reply_text发送新消息。
备用方案:
- 如果不想编辑原消息,可以使用
context.bot.send_message(chat_id=query.message.chat_id, text="新消息")发送独立消息。 - 按钮可以嵌套更多层,例如
[[btn1, btn2], [btn3]]表示第一行两个按钮,第二行一个按钮。
创建回复键盘按钮(Reply Keyboard)
回复键盘按钮会替换掉用户的输入框,显示为底部固定菜单,点击后直接发送按钮上的文字内容。
具体操作说明:
1. 定义一个函数,创建回复键盘:
`python
async def menu(update: Update, context: ContextTypes.DEFAULT_TYPE):
keyboard = [
[KeyboardButton("📸 拍照"), KeyboardButton("📝 笔记")],
[KeyboardButton("⚙️ 设置")]
]
reply_markup = ReplyKeyboardMarkup(keyboard, resize_keyboard=True, one_time_keyboard=False)
await update.message.reply_text("请选择功能:", reply_markup=reply_markup)
`
2. 注册命令处理器,例如用户输入 /menu时显示键盘:
`python
application.add_handler(CommandHandler("menu", menu))
`
3. 处理用户点击按钮后发送的文字消息(因为回复键盘本质上是发送文字):
`python
async def handle_message(update: Update, context: ContextTypes.DEFAULT_TYPE):
text = update.message.text
if text == "📸 拍照":
await update.message.reply_text("启动拍照功能...")
elif text == "📝 笔记":
await update.message.reply_text("打开笔记...")
# 其他处理
application.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, handle_message))
`
注意事项/小提示:
resize_keyboard=True会自动调整按钮大小以适应屏幕;one_time_keyboard=False表示键盘保持显示,若设为True则使用一次后消失。- 回复键盘的按钮文字必须与
handle_message中判断的文本完全一致,包括emoji。 - 如果不想让键盘一直显示,可以在某条消息中发送
ReplyKeyboardRemove()来移除键盘。
备用方案:
- 可以使用
KeyboardButton的request_contact=True或request_location=True让用户一键分享手机号或位置。 - 如果想让按钮更美观,可以在文字前加emoji,例如
"🔍 搜索"。
验证按钮功能是否正常
编写完代码并运行后,需要测试按钮是否按预期工作。
具体操作说明:
1. 在Telegram中打开你的机器人,发送 /start或 /menu命令。
2. 观察是否出现内联按钮或回复键盘。如果出现,点击按钮。
3. 检查机器人是否正确响应:内联按钮应该触发回调函数,回复键盘应该发送对应文字并触发消息处理器。
4. 如果按钮没有出现,检查代码中 reply_markup是否正确传递给了 reply_text或 send_message方法。
5. 查看运行代码的控制台是否有报错信息,常见错误包括:callback_data为空、未注册 CallbackQueryHandler、Token错误等。
注意事项/小提示:
- 内联按钮点击后,按钮下方的文字可能会短暂显示“加载中”,这是正常现象,只要最终能响应即可。
- 如果回复键盘没有显示,可能是因为之前发送过
ReplyKeyboardRemove(),可以重启机器人或手动输入/menu重新触发。 - 测试时建议使用另一个Telegram账号,避免与BotFather对话混淆。
备用方案:
- 如果按钮点击后无反应,可以尝试在
button_callback函数中增加print(f"收到回调: {query.data}")来调试。 - 如果回复键盘的文字无法匹配,可以在
handle_message中打印update.message.text查看实际收到的内容。
常见问题补充
问:内联按钮和回复键盘按钮有什么区别?什么时候用哪个?
答:内联按钮显示在消息下方,不占用输入框,适合做多选项菜单或跳转链接;回复键盘按钮替换输入框,适合做固定功能入口。建议:需要用户快速选择且不改变输入框时用内联按钮;需要持续显示常用功能时用回复键盘。
问:我可以在一个消息中同时使用内联按钮和回复键盘吗?
答:技术上可以,但通常不推荐,因为用户体验混乱。你可以先发送一条带内联按钮的消息,然后单独发送一条带回复键盘的消息,但消息是独立的。
问:按钮可以打开网页链接吗?
答:可以。使用 InlineKeyboardButton时,将参数改为 url而非 callback_data,例如:InlineKeyboardButton("访问官网", url="https://example.com")。注意Telegram客户端会提示用户即将离开。
问:如何让按钮显示多行多列?
答:在定义 keyboard列表时,每个子列表代表一行。例如 [[A, B], [C, D]]会显示两行,每行两个按钮。你可以自由组合行数和列数。
问:点击内联按钮后,如何发送新消息而不是修改原消息?
答:使用 await context.bot.send_message(chat_id=query.message.chat_id, text="新消息")或 await query.message.reply_text("新消息"),不要使用 query.edit_message_text。
问:如何删除或隐藏回复键盘?
答:发送一条消息时,将 reply_markup设置为 ReplyKeyboardRemove(),例如:await update.message.reply_text("键盘已隐藏", reply_markup=ReplyKeyboardRemove())。
总结:为Telegram机器人添加按钮的核心在于正确使用
InlineKeyboardMarkup(内联按钮)或ReplyKeyboardMarkup(回复键盘),并通过回调处理或消息匹配来响应用户点击,掌握这两类按钮的创建与处理逻辑,即可让机器人具备丰富的交互能力。