Python3.9使用Telebot开发Telegram新闻机器人如何实现交互按钮菜单
Python 3.9 + Telebot 交互式新闻菜单完整实现
前置准备
- 安装兼容Python 3.9的Telebot稳定版本:
pip install pyTelegramBotAPI==4.14.0 - 从@BotFather获取机器人Token,提前关闭群组隐私模式,确保可正常接收按钮回调事件
完整可运行代码
以下代码实现了多层级交互菜单逻辑,包含主菜单、分类列表、新闻详情三级跳转,全程无刷屏,所有交互通过编辑原消息完成:
import telebot from telebot import types # 替换为你自己的机器人Token BOT_TOKEN = "YOUR_BOT_TOKEN_HERE" bot = telebot.TeleBot(BOT_TOKEN) # 模拟新闻数据源,实际使用可替换为你的爬虫/API接口返回内容 NEWS_DATA = { "tech": [ {"id": 1, "title": "Python 3.13 性能提升30%", "content": "官方测试数据显示,3.13版本启用JIT编译后,基准测试性能较3.12提升约30%,通用计算场景响应速度明显加快。"}, {"id": 2, "title": "Telegram Bot API 新增付费媒体接口", "content": "最新版Bot API支持机器人发送付费媒体内容,创作者可直接通过机器人设置付费订阅规则,无需跳转第三方平台。"} ], "finance": [ {"id": 3, "title": "A股三大指数集体收涨", "content": "今日沪指涨1.2%,深成指涨1.8%,创业板指涨2.1%,半导体、新能源板块领涨,两市成交额突破1.2万亿。"}, {"id": 4, "title": "多国央行宣布降息", "content": "本周已有3个新兴市场国家宣布下调基准利率25个基点,市场预期全球降息周期将在三季度全面开启。"} ], "sport": [ {"id": 5, "title": "国足世预赛1-1战平泰国", "content": "世预赛亚洲区36强赛最后一轮,国足客场1-1战平泰国,以成绩最好的小组第二身份晋级18强赛。"}, {"id": 6, "title": "NBA总决赛G3凯尔特人胜独行侠", "content": "总决赛第三场凯尔特人客场106-99击败独行侠,大比分2-1领先,杰伦·布朗砍下30分当选全场最佳。"} ] } CATEGORY_NAME_MAP = {"tech": "科技新闻", "finance": "财经新闻", "sport": "体育新闻"} # 生成主菜单内嵌按钮 def build_main_menu_keyboard(): keyboard = types.InlineKeyboardMarkup(row_width=2) btn_tech = types.InlineKeyboardButton("📱 科技新闻", callback_data="cat_tech") btn_finance = types.InlineKeyboardButton("💰 财经新闻", callback_data="cat_finance") btn_sport = types.InlineKeyboardButton("⚽ 体育新闻", callback_data="cat_sport") btn_latest = types.InlineKeyboardButton("🔥 最新推送", callback_data="latest") btn_about = types.InlineKeyboardButton("ℹ️ 关于机器人", callback_data="about") keyboard.add(btn_tech, btn_finance, btn_sport, btn_latest, btn_about) return keyboard # 生成分类新闻列表按钮 def build_category_keyboard(category_key): keyboard = types.InlineKeyboardMarkup(row_width=1) for news_item in NEWS_DATA[category_key]: keyboard.add(types.InlineKeyboardButton( text=news_item["title"], callback_data=f"news_{category_key}_{news_item['id']}" )) keyboard.add(types.InlineKeyboardButton("⬅️ 返回主菜单", callback_data="main_menu")) return keyboard # 生成新闻详情页功能按钮 def build_news_detail_keyboard(category_key): keyboard = types.InlineKeyboardMarkup(row_width=2) btn_back_cat = types.InlineKeyboardButton("⬅️ 返回分类", callback_data=f"cat_{category_key}") btn_back_main = types.InlineKeyboardButton("🏠 返回主菜单", callback_data="main_menu") keyboard.add(btn_back_cat, btn_back_main) return keyboard # 处理/start启动指令 @bot.message_handler(commands=['start']) def send_welcome(message): bot.send_message( chat_id=message.chat.id, text="👋 欢迎使用新闻机器人,请选择你想浏览的内容分类:", reply_markup=build_main_menu_keyboard() ) # 统一处理所有按钮点击回调 @bot.callback_query_handler(func=lambda call: True) def handle_button_click(call): # 必须调用该方法响应回调,否则客户端会一直显示加载状态 bot.answer_callback_query(call.id) cb_data = call.data # 回到主菜单逻辑 if cb_data == "main_menu": bot.edit_message_text( chat_id=call.message.chat.id, message_id=call.message.message_id, text="👋 欢迎使用新闻机器人,请选择你想浏览的内容分类:", reply_markup=build_main_menu_keyboard() ) return # 进入分类列表逻辑 if cb_data.startswith("cat_"): cat_key = cb_data.split("_")[1] cat_name = CATEGORY_NAME_MAP[cat_key] bot.edit_message_text( chat_id=call.message.chat.id, message_id=call.message.message_id, text=f"📂 当前分类:{cat_name}\n请选择你要查看的新闻:", reply_markup=build_category_keyboard(cat_key) ) return # 打开新闻详情逻辑 if cb_data.startswith("news_"): _, cat_key, news_id = cb_data.split("_") news_id = int(news_id) target_news = next(item for item in NEWS_DATA[cat_key] if item["id"] == news_id) content = f"📰 *{target_news['title']}*\n\n{target_news['content']}" bot.edit_message_text( chat_id=call.message.chat.id, message_id=call.message.message_id, text=content, parse_mode="Markdown", reply_markup=build_news_detail_keyboard(cat_key) ) return # 最新推送逻辑 if cb_data == "latest": latest_item = NEWS_DATA["tech"][0] content = f"🔥 *最新推送*\n\n*{latest_item['title']}*\n{latest_item['content']}" bot.edit_message_text( chat_id=call.message.chat.id, message_id=call.message.message_id, text=content, parse_mode="Markdown", reply_markup=build_main_menu_keyboard() ) return # 关于页逻辑 if cb_data == "about": about_content = "ℹ️ *关于本机器人*\n基于Python 3.9 + Telebot开发的新闻交互机器人,支持分类浏览、多级菜单导航。" bot.edit_message_text( chat_id=call.message.chat.id, message_id=call.message.message_id, text=about_content, parse_mode="Markdown", reply_markup=build_main_menu_keyboard() ) return if __name__ == "__main__": print("机器人启动成功") bot.infinity_polling()
常见问题排查
- 按钮消息发送失败:检查是否误用
ReplyKeyboardMarkup,消息内嵌的交互按钮必须使用InlineKeyboardMarkup类生成,作为reply_markup参数传入消息发送方法 - 按钮点击后持续加载:必须在回调处理逻辑第一行调用
bot.answer_callback_query(call.id)响应Telegram的回调请求 - 回调匹配失效:检查
callback_data是否重复、长度是否超过64字节限制,不要在callback_data中存储大段文本,仅保留路由标识和数据ID即可 - 群组内按钮无响应:前往@BotFather找到对应机器人,进入Bot Settings -> Group Privacy选项,设置为Turn off,允许机器人接收群内消息和回调事件
内容的提问来源于stack exchange,提问作者qraxiss
相关产品推荐
相关产品推荐

