@KR1PP

PyTelegramBotAPI Бот начинает некорректно работать при работе нескольких человек (многопоточность). Как исправить?

Здравствуйте! При одновременном использовании бота разными людьми, он работает поочередно.
С начала обрабатывает запрос одного, а второму выдает ошибку.
При нажатии на Inline кнопку бот работает у всех, а при отправке файлов/фотографий/текста в чат с ботом он перестает грамотно работать.
Задача бота: сбор текста/фото/файлов и пересылка в другой чат.
Основная проблема в том, что бот работает только с одним человеком, игнорируя других. И так поочереди

import telebot
from telebot import types
import time

token = ''
bot = telebot.TeleBot(token)
chatid = ''

title = ''
curr_task = ''
messages = []
task = ''


@bot.message_handler(commands=["start"])
def main(message):
    time.sleep(0.5)
    bot.send_message(message.chat.id,
                     "[{}](tg://user?id={}), Здравствуй! Данный бот создан для сбора сложных задач, "
                     "которые определенный человек будет разбирать на вебинарах"
                     .format(message.from_user.first_name, message.from_user.id), disable_web_page_preview=True,
                     parse_mode="Markdown")
    time.sleep(0.5)
    menu(message)


@bot.callback_query_handler(func=lambda call: True)
def ans(call):
    global title, curr_task

    if call.data == 'yes_send_same':
        time.sleep(0.5)
        bot.send_message(call.message.chat.id, text='Напомню, у Тебя выбрано задание №' + curr_task)
        bot.send_message(call.message.chat.id, text="Отправляй задачу!\n"
                                                    "Формат: *ФОТО* или *ТЕКСТ*",
                         parse_mode='Markdown')
        time.sleep(0.5)
        bot.delete_message(call.message.chat.id, call.message.id)
        title = '#задание{} ⬇'.format(curr_task)

    elif call.data == 'no_send_another':
        bot.delete_message(call.message.chat.id, call.message.id)
        time.sleep(0.5)
        menu(call.message)

    elif call.data == 'yes_send_file':
        title = 'file'
        bot.delete_message(call.message.chat.id, call.message.id)
        time.sleep(0.5)
        bot.send_message(call.message.chat.id, text='Прикрепляй файл!')

    elif call.data == 'no_send_file':
        bot.delete_message(call.message.chat.id, call.message.id)
        time.sleep(0.5)
        send(call.message)

    elif call.data == 'yes_send_new_file':
        bot.delete_message(call.message.chat.id, call.message.id)
        time.sleep(0.5)
        bot.send_message(call.message.chat.id, text='Прикрепляй ещё файл!')

    elif call.data == 'no_send_new_file':
        bot.delete_message(call.message.chat.id, call.message.id)
        time.sleep(0.5)
        send(call.message)

    else:
        curr_task = str(call.data).replace("_", "-")
        time.sleep(0.5)
        bot.send_message(call.message.chat.id,
                         text='Ты выбрал задание №{}\n\n'
                              '_Если выбрано не то задание, нажми повторно на нужное в сообщении выше_'
                         .format(curr_task),
                         parse_mode='Markdown')
        time.sleep(0.5)
        if call.data == '19_21':
            bot.send_message(call.message.chat.id,
                             text='‼*ВАЖНО*‼\n'
                                  'Отправляй все три номера (19-21) *по отдельности*, если сообщения будут в *текстовом формате*\n'
                                  'Если будет формат *фото*, можешь отправлять *как по отдельности, так и группой(несколько сразу)*\n\n'
                                  '_МАКСИМАЛЬНОЕ КОЛИЧЕСТВО ФОТОГРАФИЙ ПРИ ОТПРАВКЕ ГРУППОЙ - 3. ОСТАЛЬНЫЕ ОТПРАВЛЯТЬСЯ КОЛЕ НЕ БУДУТ_',
                             parse_mode='Markdown')
            time.sleep(0.5)
        bot.send_message(call.message.chat.id, text="Отправляй задачу!" + '\n' + "Формат: *ФОТО* или *ТЕКСТ*",
                         parse_mode='Markdown')
        time.sleep(0.5)
        title = '#задание{} ⬇'.format(curr_task)


@bot.message_handler(content_types=["document"])
def send_task_file(message):
    global messages, task
    if title == 'file':
        messages.append(message)
        time.sleep(0.5)
        if len(messages) == 3:
            time.sleep(0.5)
            send(message)
        else:
            time.sleep(0.5)
            send_new_file(message)


@bot.message_handler(content_types=["text", "photo"])
def echo_message(message):
    global messages, task, photos_19_21, title
    if title != 'file' and title == '#задание19-21 ⬇' and title != '':
        messages.append(message)
        time.sleep(0.5)
        if len(messages) == 3:
            task = title
            send(message)
    elif title != '' and title != 'file' and title != '#задание19-21 ⬇':
        messages.append(message)
        time.sleep(0.5)
        task = title
        send_file(message)
    else:
        time.sleep(0.5)
        bot.send_message(message.chat.id, text='Не пытайся меня сломать  \n\n'
                                               '_Возможно Ты привысил ограничение по количеству фотографий / нажми на кнопку еще раз / выбери задание_',
                         parse_mode='Markdown')


def send(message):
    global messages, task, title
    title = ''
    bot.send_message(chat_id=chatid,
                     text=task)
    for i in range(len(messages)):
        bot.forward_message(chat_id=chatid,
                            from_chat_id=messages[i].chat.id,
                            message_id=messages[i].id)
    time.sleep(0.5)
    send_next(message)
    messages = []


def menu(message):
    task_menu = types.InlineKeyboardMarkup(row_width=4)
    task_menu.add(*[types.InlineKeyboardButton(text='№{}'.format(i),
                                               callback_data='{}'.format(i)) for i in range(1, 19)])
    tasks19_21 = types.InlineKeyboardButton(text='№19-21',
                                            callback_data='19_21')
    task_menu.add(tasks19_21)
    task_menu.add(*[types.InlineKeyboardButton(text='№{}'.format(i),
                                               callback_data='{}'.format(i)) for i in range(22, 28)])

    bot.send_message(chat_id=message.chat.id,
                     text='Перед тем, как отправить задачу, выбери её номер в ЕГЭ, нажав на одну из кнопок ниже',
                     reply_markup=task_menu)


def send_next(message):
    global title
    title = ''
    bot.send_message(chat_id=message.chat.id,
                     text='Спасибо! Твоя задача уже отправлена')
    send_next_menu = types.InlineKeyboardMarkup(row_width=1)
    yes = types.InlineKeyboardButton(text='Да, хочу!',
                                     callback_data='yes_send_same')
    no = types.InlineKeyboardButton(text='Нет, хочу выбрать другой номер!',
                                    callback_data='no_send_another')
    send_next_menu.add(yes, no)

    bot.send_message(chat_id=message.chat.id,
                     text='Хочешь отправить ещё одну задачу по этому же номеру?',
                     reply_markup=send_next_menu)


def send_file(message):
    global title
    title = ''
    send_file_menu = types.InlineKeyboardMarkup(row_width=2)
    yes_file = types.InlineKeyboardButton(text='Да', callback_data='yes_send_file')
    no_file = types.InlineKeyboardButton(text='Нет', callback_data='no_send_file')

    send_file_menu.add(yes_file, no_file)

    bot.send_message(chat_id=message.chat.id,
                     text='Прилагается файл к задаче?', reply_markup=send_file_menu)


def send_new_file(message):
    send_new_file_menu = types.InlineKeyboardMarkup(row_width=2)
    yes_file = types.InlineKeyboardButton(text='Да', callback_data='yes_send_new_file')
    no_file = types.InlineKeyboardButton(text='Нет', callback_data='no_send_new_file')

    send_new_file_menu.add(yes_file, no_file)

    bot.send_message(chat_id=message.chat.id,
                     text='Есть ещё файл?', reply_markup=send_new_file_menu)


bot.polling(none_stop=True)


Как это исправить и что надо добавить в бота, чтобы он работал корректно с несколькими людьми одновременно?
  • Вопрос задан
  • 338 просмотров
Пригласить эксперта
Ответы на вопрос 2
@artem210908
async def вроде бы есть
но я не знаю будет ли работает в PyTeleBotAPI
Ответ написан
@IKIQ
Использовать один из вариантов реализации FSM
Например создать класс User и для каждого пользователя создавать свой объект, сохраняя в нем все действия конкретного пользователя
Или подключить базу данных
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы