Функция вызывается дважды, текст отображается некорректно и чтоб кнопка заработала нужно её вызывать дважды в телеграм боте
Недавно я начал изучать создание ботов для Python. Я решил создать бота, отображающего данные, которые он принимает через API, и столкнулся со следующими проблемами: Все ошибки в коде я пометил комментарием и хешем:
- #1 вызывается дважды прежде чем вызывается #2.
- #3 В момент, когда сообщение message.text должно было вывести в Daily, он отображает Russia.
- #4 кнопка возврата должна быть вызвана один раз, а затем должна быть вызвана любая другая кнопка, чтобы сработала кнопка возврата.
@bot.message_handler(content_types=['text'])
def chose_country(message):
country = None
markup = types.ReplyKeyboardMarkup(resize_keyboard=True) # Create buttonboard
markup.add(ru, uk, by)
bot.send_message(message.chat.id, 'Choose a country:'.format(message.from_user), #ПОЧЕМУ ТО ВЫЗЫВАЕТСЯ ДВАЖДЫ
reply_markup=markup) #1
if 'Russia' in message.text:
country = 'ru'
elif 'Ukraine' in message.text:
country = 'ua'
elif 'Belarus' in message.text:
country = 'by'
if country is not None:
if country in country_list:
bot.register_next_step_handler(message, chose_mode, country) #2
def chose_mode(message, country):
markup = types.ReplyKeyboardMarkup(resize_keyboard=True)
markup.add(latest_info, all_info)
bot.send_message(message.chat.id,
'Choose to receive recent or general country information:'.format(message.from_user),
reply_markup=markup)
print(message.text) #ПОЧЕМУ ОН ВЫВОДИТ Russia ?? а не Daily #3
if 'Daily' in message.text:
markup = types.ReplyKeyboardMarkup(resize_keyboard=True) # Create buttonboard
markup.add(cnfrmd, rcvrd, crit, dths, bck)
bot.send_message(message.chat.id,
'Select the information you would like to know:'.format(message.from_user),
reply_markup=markup)
mode = 'daily'
bot.register_next_step_handler(message, chose_info, country, mode)
elif 'Total' in message.text:
print("daaaaa")
markup = types.ReplyKeyboardMarkup(resize_keyboard=True) # Create buttonboard
markup.add(cnfrmd, rcvrd, crit, dths, bck)
bot.send_message(message.chat.id,
'Select the information you would like to know:'.format(message.from_user),
reply_markup=markup)
mode = 'total'
bot.register_next_step_handler(message, chose_info, country, mode)
else:
bot.send_message(message.chat.id,
'Please try again:'.format(message.from_user))
bot.register_next_step_handler(message, chose_country)
def chose_info(message, country, mode):
try:
text = ApiConnector.get_data(country) # get json info about country
except:
bot.send_message(message.chat.id,
'An error occurred while getting data, please try again later... ?'.format(message.from_user))
print("Cannot connection to API")
if 'message' not in text:
if 'Back' in message.text:
bot.register_next_step_handler(message, chose_country) #4
Ответы (1 шт):
Ну по вашему коду вы так и запрограммировали.
- Первый раз вошли в
chose_country()- напечатали "'Choose a country:'", переменнаяcountryостаётся всё ещёNone(вы же ещё из функции даже не возвращались, и заранее вmessage.textвряд ли была страна), соответственно обработчик №2 в конце не устанавливается, а остаётся прежним. При втором заходе на входе уже страна, но сообщение (и клавиатура) у вас пишется в любом случае, хотя наконец в конце меняется обработчик на №2. - Сработал обработчик
chose_mode(), но клавиатура у вас была выведена обработчиком №1 (см. конец предыдущего пункта), где вы и выбрали Russia. - И здесь абсолютно то же самое. Обработчик пишет сообщение, выводит кнопки и почему-то тут же их проверяет. Естественно
message.textпросто не может им соответствовать, т.к. обработчик был вызван из предыдущей клавиатуры, а новую вы только в нём выводите.
Вот и происходит у вас везде - на первый заход выводятся сообщение и клавиатура, но вход её, естественно, не соответствует. На второй заход наконец вход соответствует тому, чего ожидает обработчик, но тоже самое сообщение и клавиатура в любом случае печатается снова, хотя обработчик переключается на следующий (который ожидает ввод совсем других слов).
Т.е. в общем случае вам, прежде чем переключаться на другой обработчик, необходимо вывести нужную клавиатуру, которая будет соответствовать новому обработчику.
def print_keyboard(message, text, *buttons):
markup = types.ReplyKeyboardMarkup(resize_keyboard=True) # Create buttonboard
markup.add(*buttons)
bot.send_message(message.chat.id, text, reply_markup=markup)
@bot.message_handler(content_types=['text'])
def chose_country(message):
country = None
if 'Russia' in message.text:
country = 'ru'
elif 'Ukraine' in message.text:
country = 'ua'
elif 'Belarus' in message.text:
country = 'by'
if country not in country_list:
print_keyboard(message, 'Choose a country:',
ru, uk, by)
else:
print_keyboard(message, 'Choose to receive recent or general country information:',
latest_info, all_info)
bot.register_next_step_handler(message, chose_mode, country) #2
def chose_mode(message, country):
if 'Daily' in message.text:
print_keyboard(message, 'Select the information you would like to know:',
cnfrmd, rcvrd, crit, dths, bck)
mode = 'daily'
bot.register_next_step_handler(message, chose_info, country, mode)
elif 'Total' in message.text:
print_keyboard(message, 'Select the information you would like to know:',
cnfrmd, rcvrd, crit, dths, bck)
mode = 'total'
bot.register_next_step_handler(message, chose_info, country, mode)
else:
bot.send_message(message.chat.id,
'Please try again:'.format(message.from_user))
print_keyboard(message, 'Choose a country:',
ru, uk, by)
bot.register_next_step_handler(message, chose_country)
def chose_info(message, country, mode):
try:
text = ApiConnector.get_data(country) # get json info about country
except:
bot.send_message(message.chat.id,
'An error occurred while getting data, please try again later... ?'.format(message.from_user))
print("Cannot connection to API")
if 'message' not in text:
if 'Back' in message.text:
print_keyboard(message, 'Choose a country:',
ru, uk, by)
bot.register_next_step_handler(message, chose_country) #4

