Вывести список врачей в виде кнопок в телеграм боте

Пытаюсь реализовать следующее: есть команда /doctors, которая выводит специальности врачей в виде кнопок, затем когда пользователь нажимает на специальность нужно вывести врачей этой специальности в виде кнопок. И на конец когда пользователь нажмет на врача вывести расписание его. Сам код выглядит так:

import logging
import oracledb
import base64
import json
from datetime import datetime
import telebot
from telebot import types

with open('config.json', 'r') as config_file:
    config = json.load(config_file)

token = config['telegram_bot_token']
db_user = config['db_user']
db_password = config['db_password']
db_dsn = config['db_dsn']
connection = oracledb.connect(user=db_user, password=db_password, dsn=db_dsn)

bot = telebot.TeleBot(token)

pool = oracledb.create_pool(user=db_user, password=db_password, dsn=db_dsn, min=2, max=10, increment=1)

def send_long_message(chat_id, text, chunk_size=4096):
    for i in range(0, len(text), chunk_size):
        bot.send_message(chat_id, text[i:i + chunk_size])

# Обработчик команды /doctors
@bot.message_handler(commands=['doctors'])
def show_specialties(message):
    try:
        with pool.acquire() as connection:
            with connection.cursor() as cursor:
                cursor.execute("select distinct l1.text from docdep dd, lu l1, lu l2 where dd.status = 1 and dd.depid in (18,36,37,38,39,41) and dd.specid = l1.keyid and dd.positionid = l2.keyid and lower(l2.text) like '%врач%' order by l1.text")
                results = cursor.fetchall()
                if results:
                    markup = types.InlineKeyboardMarkup()
                    for row in results:
                        specialty = row[0]
                        markup.add(types.InlineKeyboardButton(text=specialty, callback_data=f'spec_{specialty}'))
                    bot.send_message(message.chat.id, "Выберите специальность:", reply_markup=markup)
                else:
                    bot.reply_to(message, "Специальности не найдены.")
    except Exception as e:
        logging.error(f"Error occurred: {e}")
        bot.reply_to(message, "Произошла ошибка при обработке вашего запроса.")

# Функция для вывода списка врачей выбранной специальности в виде кнопок
def show_doctors_by_specialty(call, specialty):
    print(specialty)
    try:
        with pool.acquire() as connection:
            with connection.cursor() as cursor:
                cursor.execute("""
                    select dd.text
                    from docdep dd, lu l1, lu l2
                    where dd.status = 1
                    and dd.depid in (18, 36, 37, 38, 39, 41)
                    and dd.specid = l1.keyid
                    and dd.positionid = l2.keyid
                    and lower(l2.text) like '%врач%'
                    and l1.text = :specialty""", specialty=specialty)
                results = cursor.fetchall()
                if results:
                    markup = types.InlineKeyboardMarkup()
                    for row in results:
                        doctor_name = row[0]
                        print(f'doc_{specialty}_{doctor_name}')
                        markup.add(types.InlineKeyboardButton(text=doctor_name, callback_data=f'doc_{specialty}_{doctor_name}'))
                    bot.send_message(call.message.chat.id, f"Выберите врача по специальности '{specialty}':", reply_markup=markup)
                else:
                    bot.send_message(call.message.chat.id, f"Врачи по специальности '{specialty}' не найдены.")
    except Exception as e:
        logging.error(f"Error occurred: {e}")
        bot.send_message(call.message.chat.id, "Произошла ошибка при обработке вашего запроса.")

# Функция для вывода расписания выбранного врача
def show_schedule(call, specialty, doctor_name):
    try:
        with pool.acquire() as connection:
            with connection.cursor() as cursor:
                cursor.execute("""
                    select
                    (select min(r.dat) from rnumb where rdayid=r.rdayid) as date1,
                    (select max(r.dat1) from rnumb where rdayid=r.rdayid) as date2,
                    l.text as potok
                    from rnumb r, lu l 
                    where r.docdepid in (select keyid from docdep dd where dd.text like '%' || :doctor_name || '%')
                    and trunc(r.dat) between sysdate-1 and (sysdate+5) 
                    and nvl(r.patientid,0)=0 
                    and r.dirid = l.keyid
                    """, doctor_name=doctor_name)
                results = cursor.fetchall()
                if results:
                    response = f"Расписание для врача '{doctor_name}' по специальности '{specialty}':\n\n"
                    for result in results:
                        date1 = result[0].strftime("%d:%m:%Y %H:%M") if result[0] else "N/A"
                        date2 = result[1].strftime("%d:%m:%Y %H:%M") if result[1] else "N/A"
                        potok = result[2] if result[2] else "N/A"
                        response += f"С {date1} по {date2}, поток: {potok}\n\n"
                    send_long_message(call.message.chat.id, response)
                else:
                    bot.send_message(call.message.chat.id, f"Расписание для врача '{doctor_name}' по специальности '{specialty}' не найдено.")
    except Exception as e:
        logging.error(f"Error occurred: {e}")
        bot.send_message(call.message.chat.id, "Произошла ошибка при обработке вашего запроса.")

# Обработчик нажатий кнопок специальностей
@bot.callback_query_handler(func=lambda call: call.data.startswith('spec_'))
def handle_specialty_callback(call):
    specialty = call.data.split('_')[1]  # Получаем выбранную специальность из callback_data
    print(specialty)
    show_doctors_by_specialty(call, specialty)

# Обработчик нажатий кнопок врачей
@bot.callback_query_handler(func=lambda call: call.data.startswith('doc_'))
def handle_doctor_callback(call):
    data_parts = call.data.split('_')
    specialty = data_parts[1]
    doctor_name = data_parts[2]
    show_schedule(call, specialty, doctor_name)

# Обработчик команды /start или /help для начала работы бота
@bot.message_handler(commands=['start', 'help'])
def handle_start(message):
    show_specialties(message)

bot.polling(none_stop=True)

Специальности выводятся в виде кнопок, но если нажму на какую-то специальность, выходит ошибка в консоли:

ERROR:root:Error occurred: A request to the Telegram API was unsuccessful. Error code: 400. Description: Bad Request: BUTTON_DATA_INVALID


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