Добрый день.
Задача:
При нажатии инлайн-кнопки "Начать" появляется сообщение: "Нажмите /reg для начала регистрации".
Нажатие reg передаёт отлавливает CommandHandler и передаёт управление функции reg_handler
Для пользователя появляется сообщение: "Укажите Ваше имя"
Пользователь указывает имя и нажимает Enter.
От Бота должно прийти сообщение: "Выбирите свой пол, чтобы продолжить:", но ничего не происходит.
Только при повторном вводе комманды: "/reg" выводится сообщение: "Выбирите свой пол, чтобы продолжить:" И так далее.
По задумке комманда : /reg должна только лишь запустить диалог, но по сути переход от функции к функции происходит не как реакция/следующий шаг на ввод пользователем, а вводом комманды: "/reg". Где я накосячил, что сделал не так?
Питон версии 3.8.3
python-telegram-bot==12.2.0
Ниже привожу весь код.
Спасибо.
NAME, GENDER, AGE = range(3)
# Идентификаторы кнопок
CALLBACK_BUTTON1_LEFT = "callback_button1_left"
CALLBACK_BUTTON2_RIGHT = "callback_button2_right"
CALLBACK_BUTTON3_MORE = "callback_button3_more"
REG = "reg"
TITLES = {
CALLBACK_BUTTON1_LEFT: "Новое сообщение",
CALLBACK_BUTTON2_RIGHT: "Отредактировать",
CALLBACK_BUTTON3_MORE: "Регистрация пользователя",
REG: "Начать",
}
def get_base_inline_keyboard():
"""Получить клавиатуру сообщений"""
keyboard = [
[
InlineKeyboardButton(TITLES[CALLBACK_BUTTON1_LEFT], callback_data=CALLBACK_BUTTON1_LEFT),
InlineKeyboardButton(TITLES[CALLBACK_BUTTON2_RIGHT], callback_data=CALLBACK_BUTTON2_RIGHT),
],
[
InlineKeyboardButton(TITLES[CALLBACK_BUTTON3_MORE], callback_data=CALLBACK_BUTTON3_MORE),
],
]
return InlineKeyboardMarkup(keyboard)
def get_keyboard_2():
"""Получить клавиатуру сообщений_2"""
keyboard = [
[
InlineKeyboardButton(TITLES[REG], callback_data=REG),
],
]
return InlineKeyboardMarkup(keyboard)
def log_errors(f): # Декоратор для отлова ошибок
def inner(*args, **kwargs):
try:
return f(*args, **kwargs)
except Exception as e:
error_message = f'Произошла ошибка: {e}'
print(error_message)
raise e
return inner
@log_errors
def do_start(update: Update, context: CallbackContext):
chat_id = update.message.chat_id
p, _ = Profile.objects.get_or_create(
# _ - булевый флаг, кот означает профиль создан только что или нет! p - объект профиля, кот взят из базы
external_id=chat_id,
defaults={
'name': update.message.from_user.username,
}
)
update.message.reply_text(
text=f'Отправь мне что-нибуть',
reply_markup=get_base_inline_keyboard(),
)
@log_errors
def do_help(update: Update, context: CallbackContext):
chat_id = update.message.chat_id
p, _ = Profile.objects.get_or_create(
# _ - булевый флаг, кот означает профиль создан только что или нет! p - объект профиля, кот взят из базы
external_id=chat_id,
defaults={
'name': update.message.from_user.username,
}
)
update.message.reply_text(
text=f'Этот Бот помогает найти попутчика в путешествие',
reply_markup=get_base_inline_keyboard(),
)
@log_errors
def do_about(update: Update, context: CallbackContext):
chat_id = update.message.chat_id
p, _ = Profile.objects.get_or_create(
# _ - булевый флаг, кот означает профиль создан только что или нет! p - объект профиля, кот взят из базы
external_id=chat_id,
defaults={
'name': update.message.from_user.username,
}
)
update.message.reply_text(
text=f'Мы группа энтузиастов и заядлых путешественников',
reply_markup=get_base_inline_keyboard(),
)
@log_errors
def keyboard_callback_handler(update: Update, context: CallbackContext):
"""Обработчик всех кнопок всех событий"""
query = update.callback_query # Идентификатор кнопки
data = query.data
chat_id = update.effective_message.chat_id
p, _ = Profile.objects.get_or_create(
# _ - булевый флаг, кот означает профиль создан только что или нет! p - объект профиля, кот взят из базы
external_id=chat_id,
defaults={
'name': update.effective_message.from_user.username,
}
)
if data == CALLBACK_BUTTON1_LEFT:
update.effective_message.reply_text(
text=f'Вы нажали на кнопку слева',
reply_markup=get_base_inline_keyboard(),
)
elif data == CALLBACK_BUTTON2_RIGHT:
update.effective_message.reply_text(
text=f'Вы нажали на кнопку справа',
reply_markup=get_base_inline_keyboard(),
)
elif data == CALLBACK_BUTTON3_MORE:
update.effective_message.reply_text(
text=f'Регистрация анкеты пользователя',
reply_markup=get_keyboard_2(),
)
elif data == REG:
update.effective_message.reply_text(
text=f'Нажмите /reg для начала регистрации',
reply_markup=get_base_reply_keyboard(),
parse_mode='Markdown',
)
@log_errors
def reg_handler(update: Update, context: CallbackContext):
update.message.reply_text(f'''Укажите Ваше имя
''')
return NAME
@log_errors
def name_handler(update: Update, context: CallbackContext):
context.user_data[NAME] = update.effective_message.text
update.effective_message.reply_text(f'''Выбирите свой пол, чтобы продолжить:
''')
return GENDER
@log_errors
def age_handler(update: Update, context: CallbackContext):
context.user_data[GENDER] = update.effective_message.text
update.effective_message.reply_text(f'''введите свой возраст:
''')
return AGE
@log_errors
def finish_handler(update: Update, context: CallbackContext):
context.user_data[AGE] = update.effective_message.text
update.effective_message.reply_text(f'''Все данные успешно сохранены''')
return ConversationHandler.END
@log_errors
def cancel_handler(update: Update, context: CallbackContext):
update.effective_message.reply_text(f'''Отмена''')
return ConversationHandler.END
@log_errors
def do_count(update: Update, context: CallbackContext):
chat_id = update.effective_message.chat_id
p, _ = Profile.objects.get_or_create(
# _ - булевый флаг, кот означает профиль создан только что или нет! p - объект профиля, кот взят из базы
external_id=chat_id,
defaults={
'name': update.effective_message.from_user.username,
}
)
count = Message.objects.filter(profile=p).count()
update.effective_message.reply_text(
text=f'У вас {count} сообщений',
)
reply_text = f"Ваш ID = {chat_id}\nMessage ID = {m.pk}\n{text}"
update.effective_message.reply_text(
text=reply_text,
)
@log_errors
def do_echo(update: Update, context: CallbackContext):
chat_id = update.effective_message.chat_id
text = update.effective_message.text
p, _ = Profile.objects.get_or_create(
# _ - булевый флаг, кот означает профиль создан только что или нет! p - объект профиля, кот взят из базы
external_id=chat_id,
defaults={
'name': update.effective_message.from_user.username,
}
)
m = Message(
profile=p,
text=text,
)
m.save()
if text == BUTTON1_HELP:
return do_help(update=update, context=CallbackContext)
elif text == BUTTON2_ABOUT:
return do_about(update=update, context=CallbackContext)
class Command(BaseCommand):
help = 'Телеграм-бот'
def handle(self, *args, **options):
request = Request(
connect_timeout=0.5,
read_timeout=1.0,
)
bot = Bot(
request=request,
token=settings.TOKEN,
)
print(bot.get_me()) # Расспечатаем инфу о боте
# 2-обработчик
updater = Updater(
bot=bot,
use_context=True,
)
conv_handler = ConversationHandler(
entry_points=[
CommandHandler('reg', reg_handler, pass_user_data=True),
],
states={
NAME: [
MessageHandler(Filters.all, name_handler, pass_user_data=True),
],
GENDER: [
MessageHandler(Filters.all, age_handler, pass_user_data=True),
],
AGE: [
MessageHandler(Filters.all, finish_handler, pass_user_data=True),
],
},
fallbacks=[
CommandHandler('cancel', cancel_handler),
],
)
message_handler = MessageHandler(Filters.text, do_echo)
updater.dispatcher.add_handler(message_handler)
message_handler2 = CommandHandler('count', do_count)
updater.dispatcher.add_handler(message_handler2)
start_handler = CommandHandler('start', do_start)
updater.dispatcher.add_handler(start_handler)
buttons_handler = CallbackQueryHandler(callback=keyboard_callback_handler, )
updater.dispatcher.add_handler(buttons_handler)
help_handler = CommandHandler('help', do_help)
updater.dispatcher.add_handler(help_handler)
about_handler = CommandHandler('about', do_about)
updater.dispatcher.add_handler(about_handler)
updater.dispatcher.add_handler(conv_handler)
updater.start_polling()
updater.idle()