pyTelegramBotAPI register_next_step_handler с inline клавиатурой
К примеру имеется бот со списком покупок и функциями добавления (1 шаг) и удаления (2 шага) продукта. Я его реализовал на обычной клавиатуре, но как передать и обработать в шагах inline клавиатуру?
bot.py:
import telebot
from telebot import types
bot = telebot.TeleBot('your_token')
user_dict = {}
class LIST:
def __init__(self, msg):
self.msg = msg
self.del_pr = None
@bot.message_handler(commands=["list"])
def list(message):
markup = types.ReplyKeyboardMarkup(one_time_keyboard=True, resize_keyboard=True)
bt1 = types.KeyboardButton('Добавить')
bt2 = types.KeyboardButton('Удалить')
bt3 = types.KeyboardButton('Отмена')
markup.add(bt1, bt2, bt3)
msg = bot.send_message(message.chat.id, 'Список покупок:\n\nКартошка\nМорковка\nСелёдка\n\nЧто хотите сделать?',
reply_markup=markup)
bot.register_next_step_handler(msg, switch)
def switch(message):
try:
chat_id = message.chat.id
user_dict[chat_id] = LIST(message.text)
if message.text == 'Добавить':
markup = types.ReplyKeyboardMarkup(one_time_keyboard=True, resize_keyboard=True)
bt1 = types.KeyboardButton('Отмена')
markup.add(bt1)
msg = bot.send_message(chat_id, f'Введите название продукта',
reply_markup=markup)
bot.register_next_step_handler(msg, add_pr)
elif message.text == 'Удалить':
markup = types.ReplyKeyboardMarkup(one_time_keyboard=True, resize_keyboard=True)
bt1 = types.KeyboardButton('Отмена')
markup.add(bt1)
msg = bot.send_message(chat_id, f'Введите название продукта',
reply_markup=markup)
bot.register_next_step_handler(msg, del_pr)
else:
markup = types.ReplyKeyboardRemove(selective=False)
bot.send_message(chat_id, 'Отмена!', reply_markup=markup)
except Exception as e:
print(str(e))
def add_pr(message):
try:
chat_id = message.chat.id
user_dict[chat_id] = LIST(message.text)
markup = types.ReplyKeyboardRemove(selective=False)
if message.text != 'Отмена':
bot.send_message(chat_id, f'Условно добавил {message.text}\n/list', reply_markup=markup)
else:
bot.send_message(chat_id, 'Отмена!', reply_markup=markup)
except Exception as e:
print(str(e))
def del_pr(message):
try:
chat_id = message.chat.id
user = user_dict[chat_id]
user.del_pr = message.text
if message.text != 'Отмена':
markup = types.ReplyKeyboardMarkup(one_time_keyboard=True, resize_keyboard=True)
bt1 = types.KeyboardButton('Да')
bt2 = types.KeyboardButton('Нет')
markup.add(bt1, bt2)
msg = bot.send_message(chat_id, f'Вы уверены, что хотите удалить {message.text}?', reply_markup=markup)
bot.register_next_step_handler(msg, really)
else:
markup = types.ReplyKeyboardRemove(selective=False)
bot.send_message(chat_id, 'Отмена!', reply_markup=markup)
except Exception as e:
print(str(e))
def really(message):
try:
chat_id = message.chat.id
user = user_dict[chat_id]
markup = types.ReplyKeyboardRemove(selective=False)
if message.text == 'Да':
bot.send_message(chat_id, f'Условно удалил {user.del_pr}\n/list', reply_markup=markup)
else:
bot.send_message(chat_id, 'Отмена!', reply_markup=markup)
except Exception as e:
print(str(e))
bot.enable_save_next_step_handlers(delay=2)
bot.load_next_step_handlers()
bot.polling()
Ответы (2 шт):
Автор решения: ih8sn0w
→ Ссылка
Всё просто, замените:
bot.register_next_step_handler(msg, switch)
На:
bot.register_next_step_handler(msg.msg, switch)
Или на:
bot.register_next_step_handler(message.message, switch)
Таким образом, можно получить ответ от inline кнопки и передать его в:
register_next_step_handler
Строчку: chat_id = message.chat.id, можете удалить.
Автор решения: Daily
→ Ссылка
В телеботе появились стейты. Они легче в коде, а также лучше по скорости. Они сохраняются или в файле, или же в памяти.
Смотрите пример: https://github.com/eternnoir/pyTelegramBotAPI/blob/master/examples/custom_states.py