Чтобы ограничить ввод числового значения только тогда, когда бот этого требует, можно использовать состояние бота для управления процессом ввода. Для этого удобно использовать библиотеку `telebot`, которая поддерживает состояния через библиотеку `telebot.advanced`. Вам нужно настроить состояний для отслеживания текущего контекста общения с пользователем.
Вот пример, как можно организовать ввод суммы денег только после нажатия на кнопку "купить голду":
```python
from telebot import TeleBot, types
from telebot import aiogram
from telebot.storage import StateMemoryStorage
from states import State
bot = TeleBot('YOUR_BOT_API_TOKEN')
# Определяем состояния
class UserState(State):
AWAITING_AMOUNT = State()
# Словарь для хранения состояний пользователей
user_states = {}
@bot.message_handler(commands=['start'])
def start(message):
menu = types.ReplyKeyboardMarkup(resize_keyboard=True).add('купить голду')
bot.send_message(message.chat.id, 'Привет! Это бот по продаже голды. Для навигации используй кнопки.', reply_markup=menu)
@bot.message_handler(func=lambda message: message.text == 'купить голду')
def buy_gold(message):
# Устанавливаем состояние ожидания суммы
user_states[message.from_user.id] = UserState.AWAITING_AMOUNT
back = types.ReplyKeyboardMarkup(resize_keyboard=True).add('главное меню')
bot.send_message(message.chat.id, 'Введите сумму в рублях, на которую вы хотите купить голду:', reply_markup=back)
@bot.message_handler(func=lambda message: user_states.get(message.from_user.id) == UserState.AWAITING_AMOUNT)
def get_amount(message):
# Проверяем, что введено числовое значение
if message.text.isdigit():
amount = int(message.text)
user_states[message.from_user.id] = None # Сбрасываем состояние
payboard = types.InlineKeyboardMarkup()
sber = types.InlineKeyboardButton(text='Сбербанк', callback_data='sber')
tinkoff = types.InlineKeyboardButton(text='Тинькофф', callback_data='tinkoff')
alfa = types.InlineKeyboardButton(text='Альфа-банк', callback_data='alfa')
payboard.add(sber, tinkoff, alfa)
text_pay = (
f'Сумма: {amount}₽\n'
f'Вы получаете {amount * 2} голды\n\n'
f'Выберите способ оплаты:\n'
)
bot.send_message(message.chat.id, text_pay, reply_markup=payboard)
else:
bot.send_message(message.chat.id, 'Пожалуйста, введите числовое значение.')
@bot.message_handler(func=lambda message: message.text == 'главное меню')
def main_menu(message):
menu = types.ReplyKeyboardMarkup(resize_keyboard=True).add('купить голду')
bot.send_message(message.chat.id, 'Вы в главном меню.', reply_markup=menu)
# Запуск бота
bot.polling()
```
### Объяснение кода:
1. **Состояния:** Мы используем класс `UserState` для определения состояний, что позволяет отслеживать, в состоянии какого действия находится пользователь.
2. **Обработка стартовой команды:** При старте бота пользователю предлагается меню, и состояние не установлено.
3. **Кнопка "купить голду":** При нажатии на кнопку бот устанавливает текущее состояние пользователя в `AWAITING_AMOUNT`, что сигнализирует о том, что теперь бот ожидает ввода суммы.
4. **Обработка ввода суммы:** В `get_amount` функция проверяет, находится ли пользователь в состоянии `AWAITING_AMOUNT` и является ли ввод числом. Если это так, она создает сообщение, отображающее сумму и количество голды, и сбрасывает состояние.
5. **Ошибка ввода:** Если введенное значение не является числом, бот попросит пользователя ввести числовое значение.
Таким образом, бот будет запрашивать ввод суммы только в нужный момент и минимизирует вероятность неожиданных вводов.