python-telegram-bot开发时add_wallet误读/start不等待用户新输入如何修复
问题根源
- 你在
start函数中检测到用户不存在时直接同步调用了add_wallet,此时update对象还对应着用户发送的/start指令消息,所以update.message.text直接读取到的是/start内容,不会等待用户后续输入。 - 未使用会话状态管理逻辑,无法标记用户当前处于"待输入钱包地址"的状态,机器人无法识别后续用户输入应该对应钱包录入逻辑。
修复方案
使用python-telegram-bot内置的ConversationHandler实现会话状态管理,修改后的完整代码如下:
from __future__ import unicode_literals from telegram.ext import Updater, CommandHandler, MessageHandler, Filters, ConversationHandler from telegram.ext import CallbackQueryHandler, CallbackContext from telegram import InlineKeyboardButton, InlineKeyboardMarkup, ReplyKeyboardMarkup from telegram import Update from telegram import Bot import telegram import os import datetime import sqlite3 import traceback import re import data # 定义会话状态:等待用户输入钱包地址 WAITING_FOR_ADDRESS = 1 def start(update, context): chatid = update.message.chat_id if data.user_exist(chatid): update.message.reply_text('Choose wallet', reply_markup=wallet_handler(chatid, update, context)) # 已有用户直接结束会话 return ConversationHandler.END else: update.message.reply_text('Add wallet\n请输入钱包地址:') # 返回状态,告知会话处理器接下来该用户的消息交给对应状态的处理函数 return WAITING_FOR_ADDRESS def wallet_handler(chatid, update, context): kb = [] for w in data.fetch_wallet(chatid): s = w[0:10] kb.append([InlineKeyboardButton(s, callback_data=w)]) kb.append([InlineKeyboardButton('Add Wallet', callback_data='add')]) kb.append([InlineKeyboardButton('Delete Wallet', callback_data='delete')]) return InlineKeyboardMarkup(kb) def handle_wallet_input(update, context): chatid = update.message.chat_id # 修正正则:去掉多余的开头斜杠,支持大小写,适配标准以太坊地址长度 regex = re.compile(r'^(?:0x)[A-Fa-f0-9]{15,42}$') address = update.message.text print(address) if re.fullmatch(regex, address): # 校验通过,写入数据库 data.add_wallet(chatid, address) # 这里替换成你自己的数据库写入逻辑 update.message.reply_text('钱包地址添加成功!') print('okay') else: update.message.reply_text('钱包地址格式错误,请重新输入:') # 格式不对的话保持当前状态,让用户继续输入 return WAITING_FOR_ADDRESS # 处理完成结束会话 return ConversationHandler.END # 可选:添加取消命令处理 def cancel(update, context): update.message.reply_text('操作已取消') return ConversationHandler.END def main(): updater = Updater('token', use_context=True) disp = updater.dispatcher # 定义会话处理器 conv_handler = ConversationHandler( entry_points=[CommandHandler('start', start)], states={ WAITING_FOR_ADDRESS: [MessageHandler(Filters.text & ~Filters.command, handle_wallet_input)] }, fallbacks=[CommandHandler('cancel', cancel)] ) disp.add_handler(conv_handler) # 其他handler(比如按钮回调的handler)继续在这里添加 updater.start_polling() updater.idle() if __name__=='__main__': main()
其他注意点
- 你原代码中的正则表达式开头多写了一个
/,会导致所有地址都匹配失败,已在修复代码中修正。 - 以太坊标准地址长度为42位(含0x前缀),原正则限制15位不符合实际使用需求,已调整为长度区间适配。
- 处理钱包地址输入的函数中记得补充你自己的数据库写入逻辑,把地址存入你的
data模块对应的表中。
内容的提问来源于stack exchange,提问作者giacomomaraglino
相关产品推荐
相关产品推荐

