Comments 15
где ключи — это айдишники юзеров, а ключи — их состояния,
хотелось бы ясности
словарь states = {user_id: "state"}
, user_id: int, а стейт - строка, и далее в хендлере сверять с каждым возможным и вызываю соответствующую функцию, например if states[message.from_user.id] == "test": test(message)
, также можно создавать пустые класс как состояния, но тогда как по мне легче второй способ использовать.
А есть что-нибудь для телебота для меню выбора из большого списка или дерева?
Не совсем понял, для выбора из большого списка можно использовать инлайн клавиатуру, или если он очень большой обозначаешь каждое значение числом, вот так например 1) выбор 1
2) выбор 2
и дальше запрашиваешь у пользователя число.
А что вы подразумеваете под деревом я не понял, можете уточнить?
Большой список это когда листать приходится, вправо влево, или может как то получше, по 10 страниц вперед/назад не знаю. Может такое лучше как то через @ делать.
Дерево - то же самое но не список а дерево Ж)
Ну например надо выбрать 1 язык из 100.
Текстовое сообщение Выберите язык, и к нему прикреплена клавиатура с кнопками на которых названия языков написаны.
Все 100 вариантов сделать нельзя, у телеги есть глюк, если так много кнопок сделать то бот помрет, надо будет токен перевыпускать, но даже если бы можно было всё равно они не вместятся ни в какой экран. Обычно в таких случаях список делят на небольшие куски и внизу добавляют кнопки для навигации по кускам(страницам).
Такой себе вариант но хотя бы такой бы найти, готовый.
Есть еще "инлайн" боты, это когда в ты в строке сообщения начинаешь писать @имя_бота и дальше запрос. Типа @gifмем с котятами, и у тебя вылезает особое окно с результатами, возможно такой вариант можно будет адаптировать под выбор из большого списка.

Вот что-то подобное для списка:
import telebot
bot = telebot.TeleBot('YOUT_TOKEN')
# список языков
languages = ['русский', 'английский', 'немецкий', 'очень много языков', 'другие языки', 'ещё языки']
# я поставлю два на страницу, мне лень много перечеслять
@bot.message_handler(commands=['start'])
def start_command(message):
keyboard = get_keyboard(0, languages, 2) # первая страница с двумя языками
# меню где нужно выбрать
bot.send_message(message.chat.id, 'привет, выбери язык:', reply_markup=keyboard)
def get_keyboard(index, list_of_languages, languages_in_page):
languages_on_page = languages[index:index+languages_in_page]
print(languages_on_page)
print(index)
keyboard = telebot.types.InlineKeyboardMarkup(row_width=2) # замени взависимости от размера текста
for language in languages_on_page:
print(language)
keyboard.add(telebot.types.InlineKeyboardButton(text=language, callback_data=language+"_"+"language_choose"))
row = []
if index > 0:
row.append(telebot.types.InlineKeyboardButton(text='назад', callback_data='prev'+"_"+str(index-languages_in_page)))
if len(list_of_languages) > index + languages_in_page:
row.append(telebot.types.InlineKeyboardButton(text='далее', callback_data='next'+"_"+str(index+languages_in_page)))
keyboard.row(*row)
return keyboard
@bot.callback_query_handler(func=lambda call: 'next' in call.data)
def next_page(call: telebot.types.CallbackQuery) -> None:
bot.edit_message_reply_markup(call.message.chat.id, call.message.message_id, reply_markup=get_keyboard(int(call.data.split('_')[1]), languages, 2))
@bot.callback_query_handler(func=lambda call: 'prev' in call.data)
def next_page(call: telebot.types.CallbackQuery) -> None:
bot.edit_message_reply_markup(call.message.chat.id, call.message.message_id, reply_markup=get_keyboard(int(call.data.split('_')[1]), languages, 2))
@bot.callback_query_handler(func=lambda call: 'language_choose' in call.data)
def language_choose(call: telebot.types.CallbackQuery) -> None:
bot.send_message(call.message.chat.id, f'Вы выбрали язык: {call.data.split("_")[0]}')
bot.polling()
получается что-то такое:

насчёт инлайн ботов не уверен, я никогда не сталкивался и вообще не уверен что такое возможно в telebot.
А в чём проблема использовать aiogram?
Данный функционал доступен "из коробки" pytelegrambotapi. Пример использования можно посмотреть на github проекта pytelegrambotapi в папке examples - custom_states.py
https://github.com/eternnoir/pyTelegramBotAPI/blob/master/examples%2Fcustom_states.py
Контекст диалога в pytelegrambotapi