如何在python-telegram-bot中调用方法而不转到ConversationHandler



如何解决这个问题?我从用户那里获得信息,例如,电子邮件地址,但如果那个地址是错误的,我向用户显示一个错误消息,我希望用户重定向到再次获得输入的电子邮件地址并显示给用户请再次输入电子邮件地址,或者在这段代码中,我想在用户输入错误的电子邮件地址后重新运行gender方法但是我如何从电子邮件方法调用gender方法?输出是用户应该输入ConversationHandler触发的内容并运行gender方法再次获取电子邮件地址

import re

from telegram import __version__ as TG_VER

try:
from telegram import __version_info__
except ImportError:
__version_info__ = (0, 0, 0, 0, 0)

if __version_info__ < (20, 0, 0, "alpha", 1):
raise RuntimeError(
f"This example is not compatible with your current PTB version {TG_VER}. To view the "
f"{TG_VER} version of this example, "
f"visit https://docs.python-telegram-bot.org/en/v{TG_VER}/examples.html"
)
from telegram import ReplyKeyboardMarkup, ReplyKeyboardRemove, Update
from telegram.ext import (
Application,
CommandHandler,
ContextTypes,
ConversationHandler,
MessageHandler,
filters,
)

GENDER, EMAIL = range(2)

async def start(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int:
reply_keyboard = [["Boy", "Girl", "Other"]]
await update.message.reply_text(
"Hi! My name is Professor Bot. I will hold a conversation with you. "
"Are you a boy or a girl?",
reply_markup=ReplyKeyboardMarkup(
reply_keyboard, one_time_keyboard=True, input_field_placeholder="Boy or Girl?"
),
)
return GENDER

async def gender(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int:
user = update.message.from_user
await update.message.reply_text(
"Please Enter your email:",
reply_markup=ReplyKeyboardRemove(),
)

return EMAIL

async def email(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int:
if update.message.text != "" and re.match(r'([A-Za-z0-9]+[.-_])*[A-Za-z0-9]+@[A-Za-z0-9-]+(.[A-Z|a-z]{2,})+', update.message.text):
await update.message.reply_text(
"Thanks for your registration",
reply_markup=ReplyKeyboardRemove(),
)
else:
await update.message.reply_text(
"Your Email address was wrong!",
reply_markup=ReplyKeyboardRemove(),
)
return GENDER

return ConversationHandler.END

async def cancel(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int:
await update.message.reply_text(
"Bye! I hope we can talk again some day.", reply_markup=ReplyKeyboardRemove()
)
return ConversationHandler.END

def main() -> None:
application = Application.builder().token("***************").build()

# Add conversation handler with the states GENDER, PHOTO, LOCATION and BIO
conv_handler = ConversationHandler(
entry_points=[CommandHandler("start", start)],
states={
GENDER: [MessageHandler(filters.TEXT, gender)],
EMAIL: [MessageHandler(filters.TEXT & ~filters.COMMAND, email)],
},
fallbacks=[CommandHandler("cancel", cancel)],
)

application.add_handler(conv_handler)

# Run the bot until the user presses Ctrl-C
application.run_polling()


if __name__ == "__main__":
main()

我要显示给用户你的邮箱地址错了!然后请输入您的电子邮件:实际上,我想重新运行性别方法,而无需等待用户输入的东西或触发方法中的ConversationHandler

我需要一个类似的东西在另一个地方。假设我想从数据库控制用户的状态,并在数据库中保存步骤,所以我需要在对话中上下移动,所有的事情都发生在一个方法中。查看这个结构

async def register(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int:
if user.user_status == 'start':
if user.step == 0:
//Show Accpet rules
// if it accepet
//go to step 1
elif user.step == 1:
//get name and family
//goes to step 2
elif user.step == 2:
// check name and family
// if it was correct
// save in DB
// get mobile number
// if it was not correct
// show error message 
// back to step 1 and ask again name and family
elif user.step == 3:
// check mobile number 
// if it was correct
// save in DB
//get email
// if it was not correct
//show error message 
// back to step 2 and ask again mobile number
// get email
....
elif user.step == 4:
...
elif user.step == 5:
await update.message.reply_text(
"you successfull register",
reply_markup=await _reply_keyboard('GoHome'),parse_mode='HTML'
)
return Register

更新:

我做了一个真实的例子来表明我的想法和我的问题。用户应该输入一些东西,直到ConversationHandler触发,这是一个大问题,试试这个代码:
import re
from telegram import __version__ as TG_VER
try:
from telegram import __version_info__
except ImportError:
__version_info__ = (0, 0, 0, 0, 0)
if __version_info__ < (20, 0, 0, "alpha", 1):
raise RuntimeError(
f"This example is not compatible with your current PTB version {TG_VER}. To view the "
f"{TG_VER} version of this example, "
f"visit https://docs.python-telegram-bot.org/en/v{TG_VER}/examples.html"
)
from telegram import ReplyKeyboardMarkup, ReplyKeyboardRemove, Update
from telegram.ext import (
Application,
CommandHandler,
ContextTypes,
ConversationHandler,
MessageHandler,
filters,
)
step = 0
prev_step = 0
START,RULES,STEPS = range(3)
async def start(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int:
reply_keyboard = [["Yes", "No"]]
await update.message.reply_text(
"Hi! My name is Professor Bot. I will hold a conversation with you. "
"Are you accept rules?",
reply_markup=ReplyKeyboardMarkup(
reply_keyboard, one_time_keyboard=True, input_field_placeholder="Yes or No?"
),
)
return STEPS
async def steps(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int:
global step
global prev_step
if step == 0:
print(step,prev_step)
if update.message.text == "Yes" or prev_step == 1:
step=1
prev_step=0
await update.message.reply_text(
"Please enter your email address:",
reply_markup=ReplyKeyboardRemove(),
)
else:
await update.message.reply_text(
"You should accept rules to continue!",
reply_markup=ReplyKeyboardRemove(),
)
return START
elif step == 1:
prev_step = 1
if update.message.text != "" and re.match(r'([A-Za-z0-9]+[.-_])*[A-Za-z0-9]+@[A-Za-z0-9-]+(.[A-Z|a-z]{2,})+', update.message.text):
await update.message.reply_text(
"Please enter your name:",
reply_markup=ReplyKeyboardRemove(),
)
step = 2
else:
step = 0
await update.message.reply_text(
"Your Email address was wrong!",
reply_markup=ReplyKeyboardRemove(),
)
return STEPS
async def cancel(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int:
await update.message.reply_text(
"Bye! I hope we can talk again some day.", reply_markup=ReplyKeyboardRemove()
)
return ConversationHandler.END
def main() -> None:
application = Application.builder().token("*****").build()
# Add conversation handler with the states GENDER, PHOTO, LOCATION and BIO
conv_handler = ConversationHandler(
entry_points=[CommandHandler("start", start)],
states={
START: [MessageHandler(filters.TEXT, start)],
RULES: [MessageHandler(filters.TEXT, steps)],
STEPS: [MessageHandler(filters.TEXT & ~filters.COMMAND, steps)],
},
fallbacks=[CommandHandler("cancel", cancel)],
)
application.add_handler(conv_handler)
# Run the bot until the user presses Ctrl-C
application.run_polling()

if __name__ == "__main__":
main()

当用户没有提供有效的电子邮件地址时,在if子句中修改email函数。我建议

您的电子邮件地址错误!请再写一遍

有了这个,你可以回到同样的状态,你是:return EMAIL再次进入函数。

如果回答成功,return ConversationHandler.END

我找到了一种方法,我不认为这是正确的方法或标准,但它有效:

import re
from telegram import __version__ as TG_VER
try:
from telegram import __version_info__
except ImportError:
__version_info__ = (0, 0, 0, 0, 0)
if __version_info__ < (20, 0, 0, "alpha", 1):
raise RuntimeError(
f"This example is not compatible with your current PTB version {TG_VER}. To view the "
f"{TG_VER} version of this example, "
f"visit https://docs.python-telegram-bot.org/en/v{TG_VER}/examples.html"
)
from telegram import ReplyKeyboardMarkup, ReplyKeyboardRemove, Update
from telegram.ext import (
Application,
CommandHandler,
ContextTypes,
ConversationHandler,
MessageHandler,
filters,
)
step = 0
prev_step = 0
START,RULES,STEPS = range(3)
async def start(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int:
reply_keyboard = [["Yes", "No"]]
print("(start) Hi! My name is Professor Bot. I will hold a conversation with you....")
await update.message.reply_text(
"Hi! My name is Professor Bot. I will hold a conversation with you. "
"Are you accept rules?",
reply_markup=ReplyKeyboardMarkup(
reply_keyboard, one_time_keyboard=True, input_field_placeholder="Yes or No?"
),
)
print("(start) return STEPS")
return STEPS
async def steps(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int:
global step
global prev_step
print(f"(steps) BEGIN -- Step:{step}",f"PreStep:{prev_step}")
if step == 0:
print(update.message.text)
if update.message.text == "Yes" or prev_step == 1:
step=1
prev_step=0
print("Please enter your First email address:")
await update.message.reply_text(
"Please enter your First email address:",
reply_markup=ReplyKeyboardRemove(),
)
else:
print("You should accept rules to continue!")
await update.message.reply_text(
"You should accept rules to continue!",
reply_markup=ReplyKeyboardRemove(),
)
await start(update,context)
elif step == 1:
print(update.message.text)
if update.message.text != "" and re.match(r'([A-Za-z0-9]+[.-_])*[A-Za-z0-9]+@[A-Za-z0-9-]+(.[A-Z|a-z]{2,})+', update.message.text) or prev_step == 2:
print("Please enter your Second email:")
await update.message.reply_text(
"Please enter your Second email:",
reply_markup=ReplyKeyboardRemove(),
)
step = 2
prev_step = 1
else:
prev_step = 1
step = 0
print("Your First Email address was wrong!")
await update.message.reply_text(
"Your First Email address was wrong!",
reply_markup=ReplyKeyboardRemove(),
)
await steps(update,context)
elif step == 2:
print(update.message.text)
if update.message.text != "" and re.match(r'([A-Za-z0-9]+[.-_])*[A-Za-z0-9]+@[A-Za-z0-9-]+(.[A-Z|a-z]{2,})+', update.message.text):
print("Please enter your Third Email:")
await update.message.reply_text(
"Please enter your Third Email:",
reply_markup=ReplyKeyboardRemove(),
)
step = 3
prev_step = 2
else:
step = 1
prev_step = 2
print("Your Second Email address was wrong!")
await update.message.reply_text(
"Your Second Email address was wrong!",
reply_markup=ReplyKeyboardRemove(),
)
await steps(update,context)

print(f"(steps) END -- GoStep:{step}",f"PreStep:{prev_step}","### return STEPS")
print("-------------------------------------------------n")
return STEPS
async def cancel(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int:
await update.message.reply_text(
"Bye! I hope we can talk again some day.", reply_markup=ReplyKeyboardRemove()
)
return ConversationHandler.END
def main() -> None:
application = Application.builder().token("*****").build()
conv_handler = ConversationHandler(
entry_points=[CommandHandler("start", start)],
states={
START: [MessageHandler(filters.TEXT, start)],
RULES: [MessageHandler(filters.TEXT, steps)],
STEPS: [MessageHandler(filters.TEXT & ~filters.COMMAND, steps)],
},
fallbacks=[CommandHandler("cancel", cancel)],
)
application.add_handler(conv_handler)
# Run the bot until the user presses Ctrl-C
application.run_polling()

if __name__ == "__main__":
main()

相关内容

  • 没有找到相关文章