Вывести список врачей в виде кнопок в телеграм боте
Пытаюсь реализовать следующее: есть команда /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