Почему callback-функция не выполняется повторно во второй раз?

Почему функция не повторяется? <br/> Я хочу, чтобы при нажатии на кнопку в главном меню выполнялось действие, бот отправлял сообщение с кнопкой для возврата, и при повторном нажатии это работало корректно. Однако при первом нажатии всё функционирует хорошо, а при повторном возникает серьезная ошибка. <br/> Вот мой код: <br/> import telebot <br/> import webbrowser <br/> from telebot import types <br/> <br/> bot = telebot.TeleBot('токен') <br/> photo = open('./BMWe34.jpg', 'rb') <br/> # Обработка команды старт <br/> @bot.message_handler(commands=['start']) <br/> def start(message): <br/> # Добавляются кнопки <br/> markup = types.InlineKeyboardMarkup() <br/> btn1 = types.InlineKeyboardButton('Биография', callback_data='Биография') <br/> btn2 = types.InlineKeyboardButton('Ассортимент товаров', callback_data='Ассортимент') <br/> markup.row(btn1, btn2) <br/> # Бот выводит фото + текст <br/> bot.send_photo(message.chat.id, photo, caption='Бот для пискоебатела2005', reply_markup=markup) <br/> @bot.callback_query_handler(func=lambda callback: True) <br/> def callDef(callback): <br/> # Обработка кнопки биография <br/> if callback.data == 'Биография': <br/> markup = types.InlineKeyboardMarkup() <br/> btn = types.InlineKeyboardButton('Главное меню', callback_data='menu') <br/> markup.add(btn) <br/> bot.send_message(callback.message.chat.id, 'Биография Пушкина', reply_markup=markup) <br/> bot.delete_message(callback.message.chat.id, callback.message.message_id) <br/> # Обработка кнопки ассортимент <br/> elif callback.data == 'Ассортимент': <br/> markup = types.InlineKeyboardMarkup() <br/> books = types.InlineKeyboardButton('кНиги', callback_data='booksDef') <br/> picture = types.InlineKeyboardButton('Картины', callback_data='
  • 20 января 2025 г. 11:04
Ответы на вопрос 3
Ваша проблема может заключаться в том, что вы удаляете сообщение с кнопками после первого нажатия, а затем отправляете новое сообщение с новой кнопкой "Главное меню". Это может вызвать путаницу с идентификатором сообщения, на которое бот пытается ответить.

Вы используете следующую строку для удаления сообщения:

```python
bot.delete_message(callback.message.chat.id, callback.message.message_id)
```

После удаления сообщения с кнопками вы не обновляете состояние интерфейса, и при следующем нажатии на кнопку бот может не обрабатывать событие правильно, поскольку ссылка на `callback.message` больше не существует.

Вот некоторые рекомендации для исправления проблемы:

1. **Не удаляйте исходное сообщение**: Вместо удаления исходного сообщения попробуйте просто редактировать его с помощью `bot.edit_message_text()`. Это поможет избежать путаницы с идентификаторами сообщений.

2. **Повторно отправляйте меню**: Если вам нужно показать основное меню повторно после нажатия кнопки, просто отправьте новое сообщение с текущими кнопками.

3. **Обновите код**: Я приведу пример вашего кода с исправлениями. Вместо удаления сообщения с кнопками вы будете редактировать сообщение:

```python
import telebot
from telebot import types

bot = telebot.TeleBot('токен')

@bot.message_handler(commands=['start'])
def start(message):
    # Добавляются кнопки
    markup = types.InlineKeyboardMarkup()
    btn1 = types.InlineKeyboardButton('Биография', callback_data='Биография')
    btn2 = types.InlineKeyboardButton('Ассортимент товаров', callback_data='Ассортимент')
    markup.row(btn1, btn2)

    # Бот выводит текст с кнопками
    bot.send_message(message.chat.id, 'Бот для пискоебатела2005', reply_markup=markup)

@bot.callback_query_handler(func=lambda callback: True)
def callDef(callback):
    # Обработка кнопки биография
    if callback.data == 'Биография':
        markup = types.InlineKeyboardMarkup()
        btn = types.InlineKeyboardButton('Главное меню', callback_data='menu')
        markup.add(btn)

        # Редактируем предыдущее сообщение
        bot.edit_message_text(chat_id=callback.message.chat.id, message_id=callback.message.message_id,
                              text='Биография Пушкина', reply_markup=markup)
    
    # Обработка кнопки ассортимент
    elif callback.data == 'Ассортимент':
        markup = types.InlineKeyboardMarkup()
        books = types.InlineKeyboardButton('Книги', callback_data='booksDef')
        picture = types.InlineKeyboardButton('Картины', callback_data='picturesDef')
        markup.add(books, picture)

        # Редактируем предыдущее сообщение
        bot.edit_message_text(chat_id=callback.message.chat.id, message_id=callback.message.message_id,
                              text='Что вас интересует?', reply_markup=markup)

    # Обработка кнопки главное меню
    elif callback.data == 'menu':
        start(callback.message)  # Возвращаем в главное меню

# Запускаем бота
bot.polling()
```

В этом коде происходит следующее:
- Когда пользователь нажимает на кнопку, сообщение редактируется, а не удаляется.
- Показание кнопки "Главное меню" обрабатывается с помощью отдельного вызова функции `start(callback.message)`, что обеспечивает возврат в главное меню.

Теперь при нажатии на кнопки ваше меню будет запускаться повторно без ошибок.
Есть маааааленькая проблемка. Ты забыл/не знал, как работают файлы. А именно, у них есть такая штука как "текущая позиция", по которой выполняется чтение-запись. В итоге: 
1. Ты открываешь файл в начале кода. Его текущая позиция - в начале файла.
2. Ты делаешь отправку файла. Бот читает содержимое файла до конца для отправки. Теперь текущая позиция - в конце файла.
3. Ты снова пытаешься отправить тот же файл. Бот не может прочитать содержимое файла, потому что текущая позиция - в конце, читать в конце уже нечего. А в начало бот сам не "перематывает", он же без понятия, что у тебя за файл.

Просто открывай файл каждый раз при отправке (и не забудь закрыть, оператор with в помощь), а не один раз в начале скрипта.
Либо, если прямо очень-очень хочется держать файл открытым, каждый раз перед отправкой "перемотай" файл на начало методом seek().
Вашу писанину оформленную не по правилам не смотрел - но вот вопрос с похожей проблемой: 
Что делать если выдает ошибку 400 для телеграм бота на python?
Похожие вопросы