Как отправить сообщение пользователю в 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. Используйте описанный подход - это надёжно и масштабируемо.

    Часто задаваемые вопросы