Как отправить сообщение пользователю в Telegram боте с SQLite при нажатии кнопки
При разработке Telegram-бота на Python с использованием библиотеки pyTelegramBotAPI и базы данных SQLite часто возникает задача: отправить уведомление конкретному пользователю, когда администратор нажимает кнопку «Принять» в групповом чате. Ниже разберём типичную ошибку и предложим рабочее решение.
Проблема: переменная root не определена
В исходном коде встречается конструкция root= ВОПРОС ЗДЕСЬ. Это означает, что разработчик не знает, какое значение присвоить переменной root для отправки сообщения пользователю. Ошибка возникает из-за того, что chat_id получателя не извлекается из базы данных или из callback-данных.
Решение: сохраняем user_id в SQLite и используем callback_data
Чтобы при нажатии кнопки «Принять» сообщение ушло конкретному пользователю, нужно:
- При вызове команды
/testсохранятьuser_idотправителя в базе данных вместе с уникальным идентификатором заявки. - Передавать этот
user_idчерезcallback_dataкнопки. - В обработчике callback извлекать
user_idи отправлять сообщение.
Практический пример кода
Создадим таблицу для хранения заявок:
CREATE TABLE orders (id INTEGER PRIMARY KEY AUTOINCREMENT, user_id INTEGER, payment_date TEXT, amount TEXT, status TEXT DEFAULT 'pending');При обработке команды /test сохраняем данные и формируем кнопки с user_id:
def get_name(message):
user_id = message.from_user.id
cursor.execute('INSERT INTO orders (user_id, payment_date, amount) VALUES (?, ?, ?)',
(user_id, message.text.split(',')[0].strip(), message.text.split(',')[1].strip()))
conn.commit()
markup = types.InlineKeyboardMarkup()
btn_accept = types.InlineKeyboardButton(text='✅ Принять', callback_data=f'accept_{user_id}')
btn_reject = types.InlineKeyboardButton(text='❌ Отклонить', callback_data=f'reject_{user_id}')
markup.add(btn_accept, btn_reject)
bot.send_message(chat_id=-4515258659, text=f'Новая заявка от {user_id}', reply_markup=markup)В обработчике callback извлекаем user_id и отправляем уведомление:
@bot.callback_query_handler(func=lambda call: call.data.startswith('accept_'))
def accept_order(call):
user_id = int(call.data.split('_')[1])
bot.send_message(chat_id=user_id, text='✅ Ваша оплата принята!')
bot.answer_callback_query(call.id, 'Уведомление отправлено')Распространённые ошибки и их исправление
Ошибка 1: chat_id - это число, а не строка
Убедитесь, что user_id передаётся как целое число. Если в callback_data используется строка, преобразуйте её через int().
Ошибка 2: бот не видит callback в группе
Проверьте, что бот является администратором группы и имеет права на чтение сообщений. Также убедитесь, что обработчик callback не перекрывается другими функциями.
Ошибка 3: дублирование обработчиков
В исходном коде дважды определён @bot.callback_query_handler. Объедините все условия в один обработчик, используя if-elif.
Заключение
Для отправки сообщения пользователю по ID из SQLite в Telegram боте необходимо передавать user_id через callback_data или хранить его в базе данных и извлекать при обработке callback. Используйте описанный подход - это надёжно и масштабируемо.