Почему бот на команду отвечает совсем не так, как нужно

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

Бот на команду /menu отвечает всегда сообщением "❌ Вы уже были зарегистрированы в боте!", хотя должен открывать вроде как главное меню для продавца... Либо я написал очень косячный код, либо фиг знает... )

Код:

    @bot.message_handler(commands=['start'])
def start1(message):
    global db
    global sql
    db = sqlite3.connect('database.db', check_same_thread=False)
    sql = db.cursor()
    sql.execute("""CREATE TABLE IF NOT EXISTS goods (
    goods1 TEXT,
    description1 TEXT,
    price1 INT,
    goods2 TEXT,
    description2 TEXT,
    price2 INT,
    goods3 TEXT,
    description3 TEXT,
    price3 INT
    )""")
    db.commit()
    sql.execute("""CREATE TABLE IF NOT EXISTS user (
    id INT,
    name TEXT,
    date_reg INT,
    rating INT,
    balance INT,
    status_seller TEXT
    )""")
    db.commit()
    global info
    info = sql.execute("SELECT * FROM user")
    if info.fetchone() is None:
        choice_menu = types.ReplyKeyboardMarkup(resize_keyboard=False, one_time_keyboard=True)
        choice1 = types.KeyboardButton('💳 Покупатель')
        choice2 = types.KeyboardButton('Продавец 🖥')
        choice_menu.add(choice1, choice2)
        bot.send_message(message.chat.id, text=f'👋 Здравствуй. Выбери, кем тебя регистрировать:', reply_markup=choice_menu)


@bot.message_handler(content_types=['text'])
def start2(message):
    info = sql.execute("SELECT * FROM user WHERE id = ?", (message.chat.id, ))
    if message.text == '💳 Покупатель' and info.fetchone() is None:
        delete_btn = types.ReplyKeyboardRemove()
        datereg = datetime.datetime.now()
        user_id = message.chat.id
        user_name = message.from_user.username
        sql.execute("INSERT INTO user VALUES (?, ?, ?, ?, ?, ?);",
                    (user_id, user_name, datereg, 1, 0, 'No'))
        db.commit()
        bot.send_message(message.chat.id, text='✅ Вы успешно зарегистрированы в боте как покупатель!', reply_markup=delete_btn)
    elif message.text == 'Продавец 🖥' and info.fetchone() is None:
        delete_btn = types.ReplyKeyboardRemove()
        datereg = datetime.datetime.now()
        user_id = message.chat.id
        user_name = message.from_user.username
        sql.execute("INSERT INTO user VALUES (?, ?, ?, ?, ?, ?);",
                    (user_id, user_name, datereg, 1, 0, 'Yes'))
        sql.execute("INSERT INTO goods VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?);",
                    ('Нету', 'Нету', 'Не указано', 'Нету', 'Нету', 'Не указано', 'Нету', 'Нету', 'Не указано'))
        global seller_user
        seller_user = ("SELECT id FROM user WHERE status_seller = ?", ('Yes', ))
        db.commit()
        bot.send_message(message.chat.id, text='✅ Вы успешно зарегистрированы в боте как продавец!', reply_markup=delete_btn)
    else:
        delete_btn = types.ReplyKeyboardRemove()
        bot.send_message(message.chat.id, text='❌ Вы уже были зарегистрированы в боте!', reply_markup=delete_btn)


@bot.message_handler(commands=['menu'])
def menu(message):
    global info
    info = sql.execute("SELECT * FROM user WHERE id = ?", (message.chat.id, ))
    if info.fetchone() is not None and info.fetchone()[5] == 'Yes':
        main_menu = types.InlineKeyboardMarkup()
        main_btn1 = types.InlineKeyboardButton('📂 Моя анкета 📂', callback_data='main_btn1')
        main_btn2 = types.InlineKeyboardButton('🛒 Мои товары 🛒', callback_data='main_btn2')
        main_btn3 = types.InlineKeyboardButton('👨🏼‍💻 Другие продавцы 👨🏼‍💻', callback_data='main_btn3')
        main_menu.add(main_btn1)
        main_menu.add(main_btn2)
        main_menu.add(main_btn3)
        bot.send_message(message.chat.id, text='Главное меню', reply_markup=main_menu)
    else:
        bot.send_message(message.chat.id, text='❌ Вы не являетесь зарегистрированным продавцом!')


bot.polling()

Ответы

▲ 4

Вам нужно поместить любой handler (хэндлер) команды, например menu, ДО хэндлера простого текста.

import telebot

TOKEN = '<ВАШ ТОКЕН ЗДЕСЬ>'
bot = telebot.TeleBot(TOKEN)

@bot.message_handler(commands=['start'])
def start_message(message):
    # Вы можете здесь убрать следующую строку и поместить свой код здесь
    bot.send_message(message.chat.id,"Привет, что надо?")

@bot.message_handler(commands=['menu']) # обратите внимание: хэндлер команды идёт ДО хэндлера текста
def menu(message):
    # Вы можете здесь убрать следующую строку и поместить свой код здесь
    bot.send_message(message.chat.id, "Меню")   

@bot.message_handler() # в самом конце идёт хэндлер текста
def message(message):
    bot.send_message(message.chat.id, "Привет")

# ВНИМАНИЕ: если вы будете помещать здесь какие-то хэндлеры команд ещё, то разместите их до хэндлера текста, иначе не будет работать.

bot.polling()

Это работает для меня, я проверял, да ещё с разными случаями. Это работает.

Причина в том, что если помещать хэндлер простого текста до хэндлеров команд, будет выполняться только первый хэндлер, так как для message_handler что /menu, что простой текст - всё одного типа. А два хэндлера одного и того же типа, одного и того же хэндлера так не работают.

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

Конкретно в вашем случае можно сделать так:

@bot.message_handler(commands=['start'])
def start1(message):
    global db
    global sql
    db = sqlite3.connect('database.db', check_same_thread=False)
    sql = db.cursor()
    sql.execute("""CREATE TABLE IF NOT EXISTS goods (
    goods1 TEXT,
    description1 TEXT,
    price1 INT,
    goods2 TEXT,
    description2 TEXT,
    price2 INT,
    goods3 TEXT,
    description3 TEXT,
    price3 INT
    )""")
    db.commit()
    sql.execute("""CREATE TABLE IF NOT EXISTS user (
    id INT,
    name TEXT,
    date_reg INT,
    rating INT,
    balance INT,
    status_seller TEXT
    )""")
    db.commit()
    global info
    info = sql.execute("SELECT * FROM user")
    if info.fetchone() is None:
        choice_menu = types.ReplyKeyboardMarkup(resize_keyboard=False, one_time_keyboard=True)
        choice1 = types.KeyboardButton('💳 Покупатель')
        choice2 = types.KeyboardButton('Продавец 🖥')
        choice_menu.add(choice1, choice2)
        bot.send_message(message.chat.id, text=f'👋 Здравствуй. Выбери, кем тебя регистрировать:', reply_markup=choice_menu)

@bot.message_handler(commands=['menu'])
def menu(message):
    global info
    info = sql.execute("SELECT * FROM user WHERE id = ?", (message.chat.id, ))
    if info.fetchone() is not None and info.fetchone()[5] == 'Yes':
        main_menu = types.InlineKeyboardMarkup()
        main_btn1 = types.InlineKeyboardButton('📂 Моя анкета 📂', callback_data='main_btn1')
        main_btn2 = types.InlineKeyboardButton('🛒 Мои товары 🛒', callback_data='main_btn2')
        main_btn3 = types.InlineKeyboardButton('👨🏼‍💻 Другие продавцы 👨🏼‍💻', callback_data='main_btn3')
        main_menu.add(main_btn1)
        main_menu.add(main_btn2)
        main_menu.add(main_btn3)
        bot.send_message(message.chat.id, text='Главное меню', reply_markup=main_menu)
    else:
        bot.send_message(message.chat.id, text='❌ Вы не являетесь зарегистрированным продавцом!')


@bot.message_handler(content_types=['text'])
def start2(message):
    info = sql.execute("SELECT * FROM user WHERE id = ?", (message.chat.id, ))
    if message.text == '💳 Покупатель' and info.fetchone() is None:
        delete_btn = types.ReplyKeyboardRemove()
        datereg = datetime.datetime.now()
        user_id = message.chat.id
        user_name = message.from_user.username
        sql.execute("INSERT INTO user VALUES (?, ?, ?, ?, ?, ?);",
                    (user_id, user_name, datereg, 1, 0, 'No'))
        db.commit()
        bot.send_message(message.chat.id, text='✅ Вы успешно зарегистрированы в боте как покупатель!', reply_markup=delete_btn)
    elif message.text == 'Продавец 🖥' and info.fetchone() is None:
        delete_btn = types.ReplyKeyboardRemove()
        datereg = datetime.datetime.now()
        user_id = message.chat.id
        user_name = message.from_user.username
        sql.execute("INSERT INTO user VALUES (?, ?, ?, ?, ?, ?);",
                    (user_id, user_name, datereg, 1, 0, 'Yes'))
        sql.execute("INSERT INTO goods VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?);",
                    ('Нету', 'Нету', 'Не указано', 'Нету', 'Нету', 'Не указано', 'Нету', 'Нету', 'Не указано'))
        global seller_user
        seller_user = ("SELECT id FROM user WHERE status_seller = ?", ('Yes', ))
        db.commit()
        bot.send_message(message.chat.id, text='✅ Вы успешно зарегистрированы в боте как продавец!', reply_markup=delete_btn)
    else:
        delete_btn = types.ReplyKeyboardRemove()
        bot.send_message(message.chat.id, text='❌ Вы уже были зарегистрированы в боте!', reply_markup=delete_btn)


bot.polling()

Я просто поменял местами функции start2 и menu. В дальнейшем, рекомендую называть функции осмысленно.