Python Telegram Bot v13.15注册脚本AttributeError问题求助
Python Telegram Bot v13.15 注册功能 AttributeError 问题解决
问题描述
使用Python Telegram Bot v13.15编写注册功能,需求为收集用户姓名和年龄(不满18岁无法注册),运行时触发AttributeError: 'CallbackContext' object has no attribute 'message'错误。
原代码
from telegram.ext import Updater, CommandHandler, conversationhandler from telegram.ext import ( CommandHandler, CallbackContext, ConversationHandler, MessageHandler, Filters, Updater, CallbackQueryHandler ) from key import API_KEY REGISTRATION,FIRST,AGE=range(3) def start(bot,update)->int: print('user started the bot') user = update.message.from_user bot.sendphoto(chatid=update.message.chatid, photo = 'https://icon-library.com/images/bot-icon/bot-icon-5.jpg',caption='Hello {} this is econ bot '.format(user.first_name)) return REGISTRATION def register(bot, update): bot.sendmessage(chatid=update.message.chatid, text="Welcome! Please enter your name") return FIRST # (1) def first(bot, update): # (2) user = update.message.from_user name = update.message.text user.data.user.id = name # (3) reply = "Thanks for registering {}!\n Enter your age".format(name) # (4) bot.sendmessage(chatid=update.message.chatid, text=reply) return AGE # (5) def age(bot, update): # (6) age = int(update.message.text) user = update.message.from_user if age < 18: # (7) bot.sendmessage(chatid=update.message.chat.id, text="Sorry you are too young to register") else: user.data.user.obj = age bot.sendmessage(chatid=update.message.chat.id, text="Registration successful!") return ConversationHandler.END # (8) updater = Updater (token=API_KEY, use_context=True) dispatcher = updater.dispatcher def main(): conv_handler = ConversationHandler( entry_points=[CommandHandler("start", start)], states={ REGISTRATION:[MessageHandler(Filters.text,register)], FIRST: [MessageHandler(Filters.text, first)], AGE: [MessageHandler(Filters.text, age)]}, fallbacks=[CommandHandler("start", start)] ) # (11) dispatcher.add_handler(conv_handler) updater.start_polling() updater.idle() if __name__ == '__main__': main()
报错信息
No error handlers are registered, logging exception. Traceback (most recent call last): File "C:\Users\bello\AppData\Local\Programs\Python\Python37\lib\site-packages\telegram\ext\dispatcher.py", line 557, in process_update handler.handle_update(update, self, check, context) File "C:\Users\bello\AppData\Local\Programs\Python\Python37\lib\site-packages\telegram\ext\conversationhandler.py", line 627, in handle_update new_state = handler.handle_update(update, dispatcher, check_result, context) File "C:\Users\bello\AppData\Local\Programs\Python\Python37\lib\site-packages\telegram\ext\handler.py", line 199, in handle_update return self.callback(update, context) File "c:/Users/bello/Desktop/telegram bot/improved test bot1/evolve.py", line 14, in start user = update.message.from_user AttributeError: 'CallbackContext' object has no attribute 'message'
错误原因及修复方案
1. 回调函数参数顺序错误
当使用use_context=True初始化Updater时,回调函数的参数顺序必须为(update, context),而非原代码的(bot, update)。此时bot对象需通过context.bot获取,update才是包含消息数据的核心对象。
2. 方法名与参数名拼写错误
- Telegram Bot API方法采用驼峰命名:需用
sendPhoto替代sendphoto,sendMessage替代sendmessage - 聊天ID参数应为
chat_id而非chatid
3. 用户数据存储逻辑错误
不能通过user.data.user.id这类无效路径存储数据,应使用框架提供的context.user_data字典来保存用户的姓名、年龄等会话数据。
修复后的完整代码
from telegram.ext import ( Updater, CommandHandler, CallbackContext, ConversationHandler, MessageHandler, Filters ) from key import API_KEY REGISTRATION, FIRST, AGE = range(3) def start(update, context) -> int: print('user started the bot') user = update.message.from_user context.bot.sendPhoto( chat_id=update.message.chat_id, photo='https://icon-library.com/images/bot-icon/bot-icon-5.jpg', caption=f'Hello {user.first_name}, this is econ bot!' ) return REGISTRATION def register(update, context): context.bot.sendMessage( chat_id=update.message.chat_id, text="Welcome! Please enter your name" ) return FIRST def first(update, context): user = update.message.from_user name = update.message.text.strip() # 存储用户姓名到会话数据 context.user_data['name'] = name reply = f"Thanks for registering {name}!\nEnter your age" context.bot.sendMessage(chat_id=update.message.chat_id, text=reply) return AGE def age(update, context): try: age = int(update.message.text.strip()) if age < 18: context.bot.sendMessage( chat_id=update.message.chat_id, text="Sorry you are too young to register" ) else: context.user_data['age'] = age context.bot.sendMessage( chat_id=update.message.chat_id, text="Registration successful!" ) except ValueError: # 处理非数字的年龄输入 context.bot.sendMessage( chat_id=update.message.chat_id, text="Please enter a valid number for your age." ) return AGE # 让用户重新输入年龄 return ConversationHandler.END def main(): updater = Updater(token=API_KEY, use_context=True) dispatcher = updater.dispatcher conv_handler = ConversationHandler( entry_points=[CommandHandler("start", start)], states={ REGISTRATION: [MessageHandler(Filters.text, register)], FIRST: [MessageHandler(Filters.text & ~Filters.command, first)], AGE: [MessageHandler(Filters.text & ~Filters.command, age)] }, fallbacks=[CommandHandler("start", start)] ) dispatcher.add_handler(conv_handler) updater.start_polling() updater.idle() if __name__ == '__main__': main()
额外优化点
- 增加输入验证,处理年龄非数字的异常情况
- 过滤命令消息,避免用户输入命令打断注册流程
- 使用f-string替代format,提升代码可读性
内容的提问来源于stack exchange,提问作者Abel Hailu
相关产品推荐
相关产品推荐

