Телеграм бот на Python - как реализовать одновременное общение с разными пользователями
Создаю бот с такой логикой:
- бот задает пользователю несколько вопросов
- записывает ответ в единое текстовое сообщение
- пересылает мне сообщение в отдельный чат в телеграм
Проблема: при одновременных ответах нескольких пользователей, информация перемешивается. Те может быть ответ на вопрос 1 пользователя, потом сразу другого, ответ на вопрос 2 первого и тд.
bot = telebot.TeleBot(TOKEN)
def klava(kuda, n_knopok, name_knopok, name_calldata, opisanie):
keyboard = types.InlineKeyboardMarkup()
for i in range(n_knopok):
i_button = types.InlineKeyboardButton(text=name_knopok[i],
callback_data=name_calldata[i])
keyboard.add(i_button)
bot.send_message(kuda, opisanie,reply_markup=keyboard)
infa = 'Анкета_'
@bot.message_handler(commands=['start'])
def send_welcome(message):
klava(message.chat.id, 2, ['Дальше', 'Не актуально'], ['next', 'stop'], 'текст вступление.')
@bot.callback_query_handler(func=lambda call:call.data in ['next', 'stop'] )
def callback_worker(call):
if call.data =='next':
bot.send_message(call.message.chat.id, 'Напиши, пожалуйста, свое имя и ник в телеграм')
bot.edit_message_text(chat_id=call.message.chat.id, message_id=call.message.message_id, text='текст вступление')
elif call.data =='stop':
bot.send_message(call.message.chat.id, 'Мне очень жаль. Возвращайся, когда будет время. Мы будем очень рады. Отличного дня!')
@bot.message_handler(content_types=['document'])
def get_document_messages(message):
global TOKEN
forward_message (TOKEN, ссылка на канал, message.chat.id, message.id)
i=1
@bot.message_handler(content_types=['text'])
def get_text_messages(message):
global infa
global i
infa = infa + '_' +message.text
if message.text != 0 :
klava(message.chat.id, 1, ['Дальше'], [i], 'Убедись, что ответил/ла на вопрос и перейдем дальше')
return i
@bot.callback_query_handler(func=lambda call: call.data in ['1', '2', '3','4'])
def callback_worker(call):
global i
text =['вопрос 1', 'вопрос 2', 'вопрос 3']
bot.edit_message_text(chat_id=call.message.chat.id,
message_id=call.message.message_id, text='Убедись, что ответил/ла на вопрос и перейдем дальше')
if i<4:
bot.send_message(call.message.chat.id, text[i-1])
else:
klava(call.message.chat.id, 3, ['вар1', 'вар2', 'вар3'], ['вар1', 'вар2', 'вар3'], 'вопрос 4')
i=0
i = i+1
и тд. другие вопросы
последний вопрос:
def callback_worker(call):
if call.data == 'ответ1':
bot.edit_message_text(chat_id=call.message.chat.id, message_id=call.message.message_id, text='Записал твой ответ')
global infa
bot.send_message(call.message.chat.id,'ответ на анкету')
bot.send_message(ссылка на чат, infa)
infa = 'Анкета_'
elif call.data == 'ответ2':
bot.send_message(call.message.chat.id,'негативный ответ')
infa = infa + 'не подходит'
bot.send_message(ссылка на чат, infa)
infa = 'Анкета_'
bot.polling(none_stop=True)
Ответы (2 шт):
Один из вариантов решения создать базу данных, где для каждого user'a будет своя запись и прогресс общения хранить в такой бд по user id. Рекомендую SQLAlchemy
Первое что нужно сделать - избавиться от глобальных переменных, да и считается их использование плохой практикой (особенно в огромных проектах).
По сути, результат одного пользователя просто перезаписывается другим потоком в одну и ту же переменную, и вот, собственно и такой результат. Решений 2:
- Как привел Vernadsky - использовать базу данных. Для простых проектов вполне будет достаточно и SQLite. Для каждого пользователя, скажем так, создается своя запись с колонками, куда и записывается результат. Достаточно будет познакомиться с базовыми
CRUD(CREATE,READ,UPDATE,DELETE) операциями, то есть подключить базу проще, чем написать основную логику для бота:) - Если не хотите вдаваться в использования баз данных, можно сделать чуть проще - использовать словарь. Ключом выступает идентификатор пользователя, а значение - то что хотите записать.
Пример:
users = {}
...
value = 'Ваше значение'
users.update({message.chat.id: value})
То есть у каждого пользователя есть скажем так, ячейка памяти, куда можно записать результат, и уже по надобности вами извлекать.
Или еще как вариант, можно использовать метод bot.register_next_step_handler, на просторах интернета и ruSO, полно примеров с этим методом.