Python开发Telegram Bot:ConversationHandler与Filters模块异常
问题原因
你的代码基于python-telegram-bot v12及更早版本编写,但当前安装的大概率是v13+版本。新版本对模块结构、API做了大幅调整,导致旧代码里的Filters、ConversationHandler等导入和用法直接失效,重装库也解决不了版本不兼容的问题。
解决方案
两种修复方式任选其一:
方式一:降级到兼容的旧版本
卸载当前版本,安装最后一个v12稳定版,无需修改代码即可直接运行:
pip uninstall python-telegram-bot -y pip install python-telegram-bot==12.8.1
注意:旧版本不再维护,后续可能无法适配Telegram新API功能。
方式二:修改代码适配v13+版本
以下是适配后的完整代码,同时修复了原代码中save_phone_number函数未完成的bug:
import telegram from telegram import InlineKeyboardButton, InlineKeyboardMarkup from telegram.ext import ( Application, CommandHandler, MessageHandler, CallbackQueryHandler, ConversationHandler, filters ) # 预测试可选日期 DATES = ["May 1", "May 15", "May 29"] # 口语测试可选日期 SPEAKING_DAYS = ["Monday", "Tuesday", "Wednesday"] # 可选时间段 TIME_SLOTS = ["10:00am - 10:12am", "10:12am - 10:24am", "10:24am - 10:36am", "10:36am - 10:48am", "10:48am - 11:00am", "11:00am - 11:12am", "11:12am - 11:24am", "11:24am - 11:36am", "11:36am - 11:48am", "11:48am - 12:00pm", "2:00pm - 2:12pm", "2:12pm - 2:24pm"] # 神经元预测试中心群组ID NEURON_GROUP_ID = "NEURON_GROUP_ID" # Bot令牌 TOKEN = "YOUR_BOT_TOKEN_HERE" # 对话状态定义 DATE, TEST_TYPE, NAME, PHONE_NUMBER, SPEAKING_DAY, TIME_SLOT = range(6) async def start(update, context): """启动对话,让用户选择日期""" reply_markup = InlineKeyboardMarkup(build_dates_keyboard()) await update.message.reply_text('欢迎来到神经元预测试中心!请从下方选择测试日期:', reply_markup=reply_markup) return DATE def build_dates_keyboard(): """构建日期选择键盘""" keyboard = [[InlineKeyboardButton(date, callback_data=date)] for date in DATES] return keyboard async def select_date(update, context): """保存选中的日期,让用户选择测试类型""" query = update.callback_query await query.answer() context.user_data['date'] = query.data keyboard = InlineKeyboardMarkup(build_test_type_keyboard()) await query.edit_message_text(text=f'已选择日期:{context.user_data["date"]}。请选择测试类型:', reply_markup=keyboard) return TEST_TYPE def build_test_type_keyboard(): """构建测试类型选择键盘""" keyboard = [[InlineKeyboardButton("雅思预测试", callback_data="IELTS Pretest"), InlineKeyboardButton("CEFR预测试", callback_data="CEFR Pretest")]] return keyboard async def select_test_type(update, context): """保存选中的测试类型,让用户输入姓名""" query = update.callback_query await query.answer() context.user_data['test_type'] = query.data await query.edit_message_text(text=f'已选择测试类型:{context.user_data["test_type"]}。请输入你的全名:') return NAME async def save_name(update, context): """保存姓名,让用户输入手机号""" context.user_data['name'] = update.message.text await update.message.reply_text('请输入你的手机号码:') return PHONE_NUMBER async def save_phone_number(update, context): """保存手机号,让用户选择口语测试日期""" context.user_data['phone_number'] = update.message.text await update.message.reply_text('请选择口语测试日期(Monday/Tuesday/Wednesday):') return SPEAKING_DAY async def select_speaking_day(update, context): """保存口语测试日期,让用户选择时间段""" context.user_data['speaking_day'] = update.message.text keyboard = InlineKeyboardMarkup(build_time_slots_keyboard()) await update.message.reply_text('请选择测试时间段:', reply_markup=keyboard) return TIME_SLOT def build_time_slots_keyboard(): """构建时间段选择键盘""" keyboard = [[InlineKeyboardButton(slot, callback_data=slot)] for slot in TIME_SLOTS] return keyboard async def select_time_slot(update, context): """保存时间段,发送注册信息到群组,结束对话""" query = update.callback_query await query.answer() context.user_data['time_slot'] = query.data registration_info = get_registration_info(context.user_data) await context.bot.send_message(chat_id=NEURON_GROUP_ID, text=registration_info) await query.edit_message_text(text='感谢选择神经元预测试中心!你的注册已完成,期待你的到来!') return ConversationHandler.END def get_registration_info(user_data): """格式化注册信息""" info = "新注册信息:\n" info += f"测试日期: {user_data['date']}\n" info += f"测试类型: {user_data['test_type']}\n" info += f"姓名: {user_data['name']}\n" info += f"手机号: {user_data['phone_number']}\n" info += f"口语测试日期: {user_data['speaking_day']}\n" info += f"测试时间段: {user_data['time_slot']}\n" return info async def cancel(update, context): """取消对话""" await update.message.reply_text('对话已取消,再见!') return ConversationHandler.END def main(): """启动Bot""" application = Application.builder().token(TOKEN).build() conv_handler = ConversationHandler( entry_points=[CommandHandler('start', start)], states={ DATE: [CallbackQueryHandler(select_date)], TEST_TYPE: [CallbackQueryHandler(select_test_type)], NAME: [MessageHandler(filters.TEXT & ~filters.COMMAND, save_name)], PHONE_NUMBER: [MessageHandler(filters.TEXT & ~filters.COMMAND, save_phone_number)], SPEAKING_DAY: [MessageHandler(filters.TEXT & ~filters.COMMAND, select_speaking_day)], TIME_SLOT: [CallbackQueryHandler(select_time_slot)] }, fallbacks=[CommandHandler('cancel', cancel)] ) application.add_handler(conv_handler) application.run_polling() if __name__ == '__main__': main()
核心修改点:
- 替换旧版
Updater为v13+的核心入口类Application Filters改为小写的filters,调整导入路径- 所有消息处理函数添加
async关键字,调用API时加await(新版本全面异步) - 补全
save_phone_number函数的逻辑,修复变量赋值错误 - 用f-string替代
format简化字符串拼接 - 移除过时的
use_context=True参数
若选择方式二,确保安装最新版库:
pip install python-telegram-bot --upgrade
内容的提问来源于stack exchange,提问作者Rakhmatillo Rayimjonov
相关产品推荐
相关产品推荐

