Telebot. Как сделать так чтобы нажимая на кнопку, пользователь мог вводить еще сообщения которые срабатывали бы только в выбранной кнопке

Хочу сделать так чтобы пользователь выбирал кнопку и мог дальше писать данные, которые потом отрабатывал определенный код. В моем случае когда пользователь выбирает кнопку сразу же срабатывает код который должен срабатывается после написания данных в выбранной кнопке. Понятия не имею как это сделать((

Укороченый код:

bot.message_handler(commands=['start'])
def first_message(message):
    bot.send_message(message.chat.id, f"Привет {message.from_user.first_name}. Этот бот считает прогресс дневной нормы калорий и белка(может и не считает)")
    markup = ReplyKeyboardMarkup(row_width=2)
    for button_name in FUNC_BUTTON:
        item_button = KeyboardButton(button_name)
        markup.add(item_button)
    bot.send_message(message.chat.id, "Кнопочку нажмите", reply_markup=markup)

@bot.message_handler(func= lambda call:True)
def send_kall_status(message):
    if message.text == "Записать че сьел":
        # тот самый код который должен ожидать информацию от пользователя
    elif message.text == "Посмотреть че сьел":
        pass

Полный код:

import os
from telebot import TeleBot
from dotenv import load_dotenv
from db_postgres import BotDB
from telebot.types import ReplyKeyboardMarkup, KeyboardButton
load_dotenv()

BotDB = BotDB()
bot = TeleBot(os.getenv('API_KEY'))

class Data:
    state = 'none'
    all_calories = 0
    protein = 0
    writen_calories = 0
FUNC_BUTTON = ["Посмотреть че сьел", "Записать че сьел"]

data = Data()

def calc_info(message):
    message_kall_info = message.text
    if message_kall_info.isdigit() == True:
        if data.state == 'kallories':
            data.writen_calories = int(message_kall_info)
            data.all_calories += data.writen_calories
            bot.send_message(message.chat.id, "Введите количество белка")
            data.state = 'protein'
        elif data.state == 'protein':
            count_protein = int(message_kall_info)
            data.protein += count_protein
            # bot.send_message(message.chat.id, f"Калории: {data.all_calories}, Белок: {data.protein}")

            # asdas = cursor.execute("SELECT * FROM bzu_info")
            # print(asdas)
    else:
        data.state = "none"
        bot.send_message(message.chat.id, "Вы ввели не цифрууууууууууууууууууууууу")


@bot.message_handler(commands=['start'])
def first_message(message):
    if (not BotDB.user_exsistis(message.from_user.id)):
        BotDB.add_user(message.from_user.id, message.from_user.first_name)
    else:
        BotDB.user_update_last_time(message.from_user.id)
    bot.send_message(message.chat.id, f"Привет {message.from_user.first_name}. Этот бот считает прогресс дневной нормы калорий и белка(может и не считает)")
    markup = ReplyKeyboardMarkup(row_width=2)
    for button_name in FUNC_BUTTON:
        item_button = KeyboardButton(button_name)
        markup.add(item_button)
    bot.send_message(message.chat.id, "Кнопочку нажмите", reply_markup=markup)

@bot.message_handler(func= lambda call:True)
def send_kall_status(message):
    if message.text == "Записать че сьел":
        if data.state == 'none':
            data.state = 'kallories'
            calc_info(message)
        elif data.state == 'protein':
            calc_info(message)
            data.state = 'none'
            BotDB.add_bzu_info(message.from_user.id, data.protein, data.all_calories)
            user_bzu_info = BotDB.get_bzu_info(message.from_user.id)

            bot.send_message(message.chat.id, f"Количество калории: {user_bzu_info[1]}, Количество белка: {user_bzu_info[0]}")
    elif message.text == "Посмотреть че сьел":
        pass
bot.infinity_polling()

Ответы (1 шт):

Автор решения: dofi4ka

Вы же после сообщения "Записать че сьел" сразу же передаёте его в calc_info

@bot.message_handler(func= lambda call:True)
def send_kall_status(message):
    if message.text == "Записать че сьел":  
        if data.state == 'none':
            data.state = 'kallories'
            calc_info(message)  # message.text == "Записать че сьел"

Можно зарегистрировать хендлер который среагирует на следующее сообщение юзера и передаст его в функцию calc_info

@bot.message_handler(func= lambda call:True)
def send_kall_status(message):
    if message.text == "Записать че сьел":  
        if data.state == 'none':
            data.state = 'kallories'
            answer_msg = bot.send_message(message.chat.id,'Отправьте количество калорий')
            bot.register_next_step_handler(answer_msg, calc_info)

UPD: Для того чтобы пользователь мог два раза ввести данные в вашем случае можно просто в функции calc_info после ввода калорий зарегистрировать еще один next step handler на саму себя же

def calc_info(message):
    message_kall_info = message.text
    if message_kall_info.isdigit() == True:
        if data.state == 'kallories':
            ...
            data.state = 'protein'
            answer_msg = bot.send_message(message.chat.id, "Введите количество белка")
            bot.register_next_step_handler(answer_msg, calc_info)
        elif data.state == 'protein':
            ...
    else:
        ...

Но это не самая лучшая практика, можно случайно создать вечный цикл, поэтому лучше всего будет сделать две отдельные функции (тогда и смысл в data.state отпадает):

def calc_info_kkal(message):
    message_kall_info = message.text
    if message_kall_info.isdigit() == True:
        data.writen_calories = int(message_kall_info)
        data.all_calories += data.writen_calories
        answer_msg = bot.send_message(message.chat.id, "Введите количество белка")
        bot.register_next_step_handler(answer_msg, calc_info)

def calc_info_protein(message):
    message_kall_info = message.text
    if message_kall_info.isdigit() == True:
        count_protein = int(message_kall_info)
        data.protein += count_protein

        BotDB.add_bzu_info(message.from_user.id, data.protein, data.all_calories)
        user_bzu_info = BotDB.get_bzu_info(message.from_user.id)

        bot.send_message(message.chat.id, f"Количество калории: {user_bzu_info[1]}, Количество белка: {user_bzu_info[0]}")

@bot.message_handler(func= lambda call:True)
def send_kall_status(message):
    if message.text == "Записать че сьел":  
        data.state = 'kallories'
        answer_msg = bot.send_message(message.chat.id,'Отправьте количество калорий')
        bot.register_next_step_handler(answer_msg, calc_info)

P.S. Использовать глобальную переменную data не самый лучший вариант, представьте если вашим ботом будет пользоваться несколько человек и на всех их только одна глобальная переменная :)

→ Ссылка