Вопрос связанный с библиотекой telebot

Рейтинг: 1Ответов: 1Опубликовано: 20.02.2023

Есть ТГ бот план которого я придумал, чтобы начать обучаться программированию.

На данном этапе у меня уже есть кнопка подтвердить заказ, я хочу её переделать в InLine кнопку, чтобы она выводилось вместе с сообщением корзины, но когда её прописываю, вылетает ошибка.

Помогите прописать эту кнопку пожалуйста.

И сам уже настолько запутался в коде, что не могу понять, что не так с корзиной, она выводит два раза сообщение об её состоянии.

import telebot
import sqlite3
from telebot.types import ReplyKeyboardMarkup, KeyboardButton, InlineKeyboardMarkup, InlineKeyboardButton, InputMediaPhoto

API_TOKEN = 'tokenbot'
bot = telebot.TeleBot(API_TOKEN)
bottom_menu = ReplyKeyboardMarkup(resize_keyboard=True, one_time_keyboard=False)
catalog_button = KeyboardButton("Каталог свечей 🕯️")
basket_button = KeyboardButton("Корзина 🗑️")
bottom_menu.row(catalog_button, basket_button)
conn = sqlite3.connect('candles.db')
cur = conn.cursor()
cur.execute('CREATE TABLE IF NOT EXISTS cart (id INTEGER PRIMARY KEY, user_id INTEGER, name TEXT, price REAL, quantity INTEGER)')
@bot.message_handler(commands=['help','start'])
def send_welcome(message):
    bot.reply_to(message, "Добро пожаловать в телеграмм-магазин свечей ARTEG 🕯️\nПриятных покупок 🙃")
    bot.send_video(message.chat.id, 'https://i.imgur.com/EZuE61u.gif', None, 'Text')
    bot.send_message(message.chat.id, 'Пожалуйста используйте клавиатуру для навигации по магазину.', reply_markup=bottom_menu)
@bot.message_handler(func=lambda message: message.text == 'Каталог свечей 🕯️')
def catalog_candles(message):
    markup = InlineKeyboardMarkup()
    with sqlite3.connect('candles.db') as conn:
        cur = conn.cursor()
        # get all candles from the database
        cur.execute('SELECT id, name FROM candles')
        rows = cur.fetchall()
        for row in rows:
            button_text = row[1]
            button_callback = str(row[0])
            button = InlineKeyboardButton(button_text, callback_data=button_callback)
            markup.add(button)
    bot.send_message(message.chat.id, 'Каталог свечей 🕯️:', reply_markup=markup)

@bot.callback_query_handler(func=lambda call: True)
def handle_callback_query(call):
    conn = sqlite3.connect('candles.db')
    cur = conn.cursor()
    if call.data.startswith('add_to_cart_'):
        id = int(call.data.split('_')[-1])
        cur.execute('SELECT name, price FROM candles WHERE id = ?', (id,))
        row = cur.fetchone()
        name = row[0]
        price = row[1]
        cur.execute('SELECT quantity FROM cart WHERE name = ?', (name,))
        row = cur.fetchone()
        if row is None:
            user_id = call.message.chat.id
            cur.execute('INSERT INTO cart (user_id, name, price, quantity) VALUES (?, ?, ?, 1)', (user_id, name, price))

        else:
            quantity = row[0] + 1
            cur.execute('UPDATE cart SET quantity = ? WHERE name = ?', (quantity, name))
        conn.commit()
        cur.close()
        conn.close()
        bot.answer_callback_query(call.id, text=f"{name} добавлен в корзину 🛒")
    else:
        id = int(call.data)
        cur.execute('SELECT name, description, price, image_url FROM candles WHERE id = ?', (id,))
        row = cur.fetchone()
        name = row[0]
        description = row[1]
        price = row[2]
        image_url = row[3]
        message_text = f"{name}\n\n{description}\n\nPrice: ₽{price:.2f}"
        markup = InlineKeyboardMarkup()
        add_to_cart_button = InlineKeyboardButton("Добавить в корзину 🛒", callback_data=f"add_to_cart_{id}")
        markup.add(add_to_cart_button)
        bot.send_photo(call.message.chat.id, photo=image_url, caption=message_text, reply_markup=markup)
        cur.close()
        conn.close()
        bot.answer_callback_query(call.id)
@bot.callback_query_handler(func=lambda call: call.data.startswith('add_to_cart_'))
def handle_add_to_cart(call):
    conn = sqlite3.connect('candles.db')
    cur = conn.cursor()
    id = int(call.data.split('_')[-1])
    user_id = call.message.chat.id
    cur.execute('SELECT name, price FROM candles WHERE id = ?', (id,))
    row = cur.fetchone()
    name = row[0]
    price = row[1]
    cur.execute('SELECT quantity FROM cart WHERE user_id = ? AND name = ? AND id = ?', (call.message.chat.id, name, id))
    row = cur.fetchone()
    if row is None:
        cur.execute('INSERT INTO cart (user_id, name, price, quantity) VALUES (?, ?, ?, 1)', (user_id, name, price))


    else:
        quantity = row[0] + 1
        cur.execute('UPDATE cart SET quantity = ? WHERE user_id = ? AND name = ? AND id = ?', (quantity, user_id, name, id))
    conn.commit()
    cur.close()
    conn.close()
    bot.answer_callback_query(call.id, text=f"{name} added to cart")
@bot.message_handler(func=lambda message: message.text == 'Корзина 🗑️')
def handle_basket_button(message):
    conn = sqlite3.connect('candles.db')
    cur = conn.cursor()
    user_id = message.chat.id
    cur.execute('SELECT name, price, quantity FROM cart WHERE user_id = ?', (user_id,))
    rows = cur.fetchall()
    message_text = 'Ваша корзина:\n\n'
    total_price = 0
    for row in rows:
        name = row[0]
        price = row[1]
        quantity = row[2]
        total_price += price * quantity
        message_text += f"{name} - ₽{price:.2f} x {quantity}\n"
    message_text += f"\nИтого: ₽{total_price:.2f}"
    # Create a confirmation button
    confirm_button = KeyboardButton("Подтвердить заказ ✅")
    confirm_menu = ReplyKeyboardMarkup(resize_keyboard=True, one_time_keyboard=True)
    confirm_menu.add(confirm_button)
    # Send the message with the confirmation button
    bot.send_message(message.chat.id, message_text, reply_markup=confirm_menu)

    # Set the state of the user to "awaiting_confirmation"
    bot.register_next_step_handler(message, awaiting_confirmation, total_price)

    bot.send_message(message.chat.id, message_text)
    cur.close()
    conn.close()

def awaiting_confirmation(message, total_price):
    # Save the order and user input to the database
    conn = sqlite3.connect('candles.db')
    cur = conn.cursor()
    order = message.text
    cur.execute('INSERT INTO orders (`order`, total_price) VALUES (?, ?)', (order, total_price))
    conn.commit()
    cur.close()
    conn.close()

    # Clear the cart
    clear_cart()

    # Send a confirmation message
    bot.send_message(message.chat.id, f"Ваш заказ на сумму ₽{total_price:.2f} подтвержден ✅")

    # Add back the main menu buttons
    global bottom_menu
    bottom_menu = ReplyKeyboardMarkup(resize_keyboard=True, one_time_keyboard=False)
    catalog_button = KeyboardButton("Каталог свечей 🕯️")
    basket_button = KeyboardButton("Корзина 🗑️")
    bottom_menu.row(catalog_button, basket_button)
    bot.send_message(message.chat.id, "Возвращаемся в главное меню", reply_markup=bottom_menu)

def clear_cart():
    conn = sqlite3.connect('candles.db')
    cur = conn.cursor()
    cur.execute('DELETE FROM cart')
    conn.commit()
    cur.close()
    conn.close()




bot.polling()

Ответы

▲ 2Принят

Вот так Вы должны объявлять саму кнопку:

confirm_menu = types.InlineKeyboardMarkup()
confirm_button = types.InlineKeyboardButton("Подтвердить заказ ✅", callback_data="1")
confirm_menu.add(confirm_button)

И нужно создать обработчик (ещё добавьте глобальную переменную message_text, чтобы можно было отправить сообщение)

@bot.callback_query_handler(func=lambda call: True)
def callback_handler(call):
    if call.data == "1":
        bot.send_message(call.message.chat.id, message_text, reply_markup=confirm_menu)