pyTelegramBotAPI: StateMemoryStorage not working correctly

  Kiến thức lập trình

I’m writting a task-tracker bot using telebot. In message_handler for a new task by using callback_data I check which button was pressed. I need a way to get message.text after the button was pressed and save it.

import telebot
from configobj import ConfigObj
from telebot import types
from telebot import custom_filters
from telebot.handler_backends import State, StatesGroup
from telebot.storage import StateMemoryStorage

# Чтение конфигурационного файла
config = ConfigObj('config.ini')

# Получение токена из конфигурационного файла
TOKEN = config['telegram']['token']

state_storage = StateMemoryStorage()

bot = telebot.TeleBot(TOKEN, state_storage=state_storage)


# Определение состояний
class TaskStates(StatesGroup):
    name = State()
    description = State()
    deadline = State()


@bot.message_handler(commands=['start'])
def handle_start(message):
    start_markup = types.ReplyKeyboardMarkup(row_width=1)
    new_button = types.KeyboardButton('Новая задача')
    exists_button = types.KeyboardButton('Существующая задача')
    report_button = types.KeyboardButton('Отчеты')
    start_markup.add(new_button, exists_button, report_button)

    bot.send_message(message.chat.id, 'Выбери команду', reply_markup=start_markup)


# Обработчик кнопки 'Новая задача'
@bot.message_handler(func=lambda message: message.text == 'Новая задача')
def handle_new_task(message):
    new_task_markup = types.InlineKeyboardMarkup(row_width=2)

    name_button = types.InlineKeyboardButton('Название', callback_data='name')
    description_button = types.InlineKeyboardButton('Описание', callback_data='description')
    deadline_button = types.InlineKeyboardButton('Сроки', callback_data='deadline')
    save_button = types.InlineKeyboardButton('Сохранить задачу', callback_data='save')
    back_button = types.InlineKeyboardButton('Назад', callback_data='back')

    new_task_markup.add(name_button, description_button, deadline_button, save_button, back_button)

    bot.send_message(message.chat.id, 'Введите данные:', reply_markup=new_task_markup)


@bot.callback_query_handler(func=lambda call: True)
def answer(call):
    match call.data:
        case 'name':
            bot.set_state(call.message.from_user.id, TaskStates.name, call.message.chat.id)
            bot.send_message(call.message.chat.id, f'Введите название {bot.get_state(call.message.from_user.id,
                                                                                     call.message.chat.id)}')

        case 'description':
            bot.set_state(call.message.from_user.id, TaskStates.description, call.message.chat.id)
            bot.send_message(call.message.chat.id, f'Введите описание {bot.get_state(call.message.from_user.id,
                                                                                     call.message.chat.id)}')

        case 'deadline':
            bot.set_state(call.message.from_user.id, TaskStates.deadline, call.message.chat.id)
            bot.send_message(call.message.chat.id, f'Введите сроки {bot.get_state(call.message.from_user.id,
                                                                                  call.message.chat.id)}')

        case 'save':
            bot.send_message(call.message.chat.id,f"Задача сохранена!")
            with bot.retrieve_data(call.message.from_user.id, call.message.chat.id) as data:
                print(data)

        case 'back':
            bot.send_message(call.message.chat.id, call.data)


@bot.message_handler(state=TaskStates.name)
def enter_task_name(message):
    with bot.retrieve_data(message.from_user.id, message.chat.id) as data:
        data['name'] = message.text
    print(message.text)


@bot.message_handler(state=TaskStates.description)
def enter_task_description(message):
    with bot.retrieve_data(message.from_user.id, message.chat.id) as data:
        data['description'] = message.text
        print(message.text)


@bot.message_handler(state=TaskStates.deadline)
def enter_task_deadline(message):
    with bot.retrieve_data(message.from_user.id, message.chat.id) as data:
        data['deadline'] = message.text
        print(message.text)


# Обработчик кнопки 'Существующая задача'
@bot.message_handler(func=lambda message: message.text == 'Существующая задача')
def handle_existing_task(message):
    bot.send_message(message.chat.id, 'Вы выбрали "Существующая задача". Пожалуйста, выберите задачу из списка.')


# Обработчик кнопки 'Отчеты'
@bot.message_handler(func=lambda message: message.text == 'Отчеты')
def handle_reports(message):
    bot.send_message(message.chat.id, 'Вы выбрали "Отчеты". Здесь будут ваши отчеты.')


@bot.message_handler(commands=['help'])
def main(message):
    bot.send_message(message.chat.id, 'Help Information')


bot.add_custom_filter(custom_filters.StateFilter(bot))

bot.polling(none_stop=True)

If any of name, description or deadline buttons was pressed, I set a corresponding state, but messasge handlers corresponding to that state are not working at all. bot.retrieve_data is always empty. How can I fix it?

New contributor

Антон Корж is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.

Theme wordpress giá rẻ Theme wordpress giá rẻ Thiết kế website

LEAVE A COMMENT