Бот не меняет сообщение Telebot, как решить?

Есть такой код:
def accept(call):
try:

    message = call.message.text.split('\n')

    id_user = message[2].split(':')
    id_user = id_user[1].replace(' ', '')

    bot.send_message(id_user, '❤️ Ваша заявка *была принята*!', parse_mode="Markdown")
    database.user_update_merchant_id(id_user, 2)

    bot.edit_message_text(chat_id=admin, message_id=call.message.message_id, text= f'❤️ Пользователь @{str(call.message.chat.username)} принят', parse_mode="Markdown")
    bot.edit_message_text(chat_id=support, message_id=call.message.message_id, text= f'❤️ Пользователь @{str(call.message.chat.username)} принят', parse_mode="Markdown")
    bot.answer_callback_query(callback_query_id=call.id, show_alert=False, text=" Вы приняли пользователя")
except Exception as e:
    print(e)


При нажатии кнопки принять админом или саппортом, выполняется accept(call) и человеку отправляется сообщение:

bot.send_message(id_user, '❤️ Ваша заявка *была принята*!', parse_mode="Markdown")


После чего сообщение с кнопкой принять должно меняться на

bot.edit_message_text(chat_id=admin, message_id=call.message.message_id, text= f'❤️ Пользователь @{str(call.message.chat.username)} принят', parse_mode="Markdown")


у админа все работает прекрасно сообщение меняется, но у саппорта ничего не меняется и выдается ошибка

A request to the Telegram API was unsuccessful. Error code: 400. Description: Bad Request: message to edit not found


Кто знает что делать? Так же хотелось бы узнать что делать чтобы вместо
@{str(call.message.chat.username)}
писался username человека которого приняли, а то там пишется username того кто принял.
  • Вопрос задан
  • 779 просмотров
Решения вопроса 1
SoreMix
@SoreMix
yellow
у админа все работает прекрасно сообщение меняется, но у саппорта ничего не меняется и выдается ошибка


У вас два метода,которые изменяют сообщение. Первый для сапорта, второй для администратора. В чате у одного нет сообщения второго и наоборот

Логично было бы заменить
bot.edit_message_text(chat_id=admin, message_id=call.message.message_id, text= f'❤️ Пользователь @{str(call.message.chat.username)} принят', parse_mode="Markdown")
bot.edit_message_text(chat_id=support, message_id=call.message.message_id, text= f'❤️ Пользователь @{str(call.message.chat.username)} принят', parse_mode="Markdown")

на
bot.edit_message_text(chat_id=call.message.chat.id, message_id=call.message.message_id, text= f'❤️ Пользователь @{str(call.message.chat.username)} принят', parse_mode="Markdown")


Так же хотелось бы узнать что делать чтобы вместо @{str(call.message.chat.username)} писался username человека которого приняли, а то там пишется username того кто принял

Тут тоже все логично, обращаетесь к чату, из которого пришло нажатие, и получаете данные из этого же чата. Если хотите упоминать пользователя - сразу передавайте его имя либо в сообщении, к которому прикреплена кнопка, либо в callback_data поместите. Я так понял callback_data никак не занята, так что это лучший вариант

Но можно и вызвать метод getChat, передать в него id чата и получить из него имя пользователя. Но зачем, если можно имя сразу передать через inline кнопку

upd: а, ну я понял, что подразумевалось при использовании двух методов. Нужно во всех чатах обновить информацию. Здесь ошибка появляется из-за того, что ID сообщений не совпадает в двух чатах. Можно пофиксить как нибудь через добавление ID сообщений в кнопку через редактирование, но способ странный конечно. Сейчас напишу что нибудь.

Окей, допустим у нас есть два id чата - admin и support, занесем их в список. И создадим еще список, где будем хранить наши id сообщений. Главная идея в том, чтобы добавить в callback_data наши ID чата и ID поддержки вместе с их уникальными ID сообщений. Дальше я просто выложу код и прокоментирую.
@bot.message_handler(commands=['start'])
def send_start(message):

    # начальная клавиатура
    markup = types.InlineKeyboardMarkup()
    markup.add(types.InlineKeyboardButton('Принять пользователя', callback_data='dummy'))

    # два списка, один с ID чатов сапорта и админа, второй для ID сообщений
    chats = [admin, support]
    message_ids = []

    # Для каждого из наших старших юзеров отправляем сообщение, в котором есть имя человека для одобрения и наша клавиатура.
    # во время отправки сообщений мы сохраняем их ID и добавляем в наш список message_ids
    for chat in chats:
        msg = bot.send_message(chat, 'Пользователь: 1234', reply_markup=markup)
        message_ids.append(msg.message_id)

    # здесь склеиваем наш chat_id и message_id и формируем из них строку вида "chatid_messageid:chatid2_messageid2"
    # у меня cb_data получается "XXXXXXX_1264:YYYYYYYY_1265", где 1264 & 1265 - id сообщений, а XXXX & YYY - ID чатов людей из списка chats
    cb_data = ':'.join(f'{chat_id}_{message_id}' for chat_id, message_id in zip(chats, message_ids))
    markup = types.InlineKeyboardMarkup()
    markup.add(types.InlineKeyboardButton('Принять пользователя', callback_data=cb_data))

    # еще раз склеиваем наши списки, и редактируем в них клавиатуру
    for chat_id, message_id in zip(chats, message_ids):
        bot.edit_message_text('test', chat_id, message_id, reply_markup=markup)


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

Дальше все просто, в функции с обработкой заявок разбиваем нашу колбек дату на ид чатов и ид сообщений, и в цикле их редактируем.

@bot.callback_query_handler(func= lambda call: True)
def accept(call):

    messages_info = call.data.split(':')
    for message_info in messages_info:
        chat_id, message_id = message_info.split('_')
        bot.edit_message_text(chat_id=chat_id, message_id=message_id, text= f'❤️ Пользователь @{str(call.message.chat.username)} принят', parse_mode="Markdown")


Не тестил, но думаю работать будет. Надеюсь понятно что я имел ввиду
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы