Есть ли альтернативный метод "register_next_step_handler" из telebot в pyrogram-e?

Начал писать юзербота, и столкнулся с небольшой проблемой - не могу найти в документации pyrogram метод, который есть в библиотеке pytelegrambotapi (метод - register_next_step_handler). Вопрос - есть ли данный метод в библиотеке pyrogram и если есть - приведите пожалуйста пример использования.


Ответы (2 шт):

Автор решения: Павел Осипенко

В фреймворке pyrogram данного функционала я тоже не нашел.

Посмотрел как это реальизовано у других. Если очень приближенно и если я все правильно понял, то суть в том, что при вызове метода register_next_step_handler() мы временно регистрируем новый хендлер, которому передаем наш текущий message из которого берется id чата. И при следующем событии с данным chat_id (то есть отслеживаем именно этот чат) сообщение обрабатывается именно хендлером, который потом удаляется из списка всех имеющихся хендлеров. Как-то так. Может ошибаюсь. Я надеюсь, что в следующих релизах pyrogram добавят такую возможность.

В своем же боте (на pyrogram), я реализовал это таким "костылем": Сохраняю в глобальную переменную (назовем ее wait_for_input) значания chat_id, message_id и какой-нибудь маркер (например тот же callback_data), чтоб потом можно было вызвать нужую функцию (если предполагается разный отзыв на разные кнопки). В обрабтчике сообщений @bot.on_message() в первую очередь проверяю не пуста ли эта глобальная переменная. Если не пуста и сообщение из нужного мне чата, тогда принимаю данные, делаю с ними что надо и обнуляю переменную. Понятно, что если сообщение из другого чата, то переменная остается и будет ждать пока придет сообщение с нужного.

Пример:

from pyrogram import Client, filters
from pyrogram.types import InlineKeyboardMarkup, InlineKeyboardButton

# Do not forget create config.ini file with `api_id` and `api_hash` fields.
bot = Client("stupid_bot", bot_token='1418066303:AAEE_BtYTRN6sTcPFM5_nZLB0GEEscxpkUM')

names = list()
wait_for_input = None

button_add = InlineKeyboardButton('Добавить имя', callback_data='add')
button_remove = InlineKeyboardButton('Удалить имя', callback_data='remove')
button_show_all = InlineKeyboardButton('Посмотреть список имен', callback_data='show_all')
main_inline_markup = InlineKeyboardMarkup([[button_add, button_remove], [button_show_all]])


@bot.on_message(~filters.bot)
def answer(_, message):
    global wait_for_input

    text = "Может познакомимся?"

    if wait_for_input:
        prev_chat_id, callback, = wait_for_input
        if prev_chat_id == message.chat.id:
            if callback == 'add':
                names.append(message.text)
                text = f'Привет **{message.text}**'
            else:
                try:
                    names.remove(message.text)
                    text = f'Имя **{message.text}** было удалено из списка.'
                except ValueError:
                    text = 'Нет такого имени в списке.'
            wait_for_input = None

    message.reply_text(text=text, reply_markup=main_inline_markup)


@bot.on_callback_query()
def text_handler(_, callback_query):
    global wait_for_input

    if callback_query.data == 'add':
        wait_for_input = (callback_query.message.chat.id, callback_query.data)
        callback_query.edit_message_text("Отлично, как тебя зовут?")

    elif callback_query.data == 'remove':
        wait_for_input = (callback_query.message.chat.id, callback_query.data)
        callback_query.edit_message_text("Напиши имя, которое надо удалить.")

    elif callback_query.data == 'show_all':
        callback_query.edit_message_text(
            "\n - {}".format('\n -'.join(names)) if names else 'Список пуст.',
            reply_markup=main_inline_markup
        )


bot.run()

В этом примере многие моменты упущены (обработка ошибок, одновременный ввод данных несколькими пользователями и многое многое другое). Он написан, как говорится, "на коленке" исключительно для пояснения описанной идеи.

→ Ссылка
Автор решения: Aron1cx

В библиотеке Pyrogram отсутствует встроенная функциональность для обработки шагов в диалогах. Однако есть дополнительная библиотека под названием Pyrostep, предназначенную специально для этой цели.

Установка данной библиотеки: pip install pyrostep.

Приведенный ниже код демонстрирует использование Pyrogram с Pyrostep для реализации последовательных шагов в диалоге:

from pyrogram import Client, filters
import pyrostep

app = Client('название_сессии')
pyrostep.listen(app)

@app.on_message(filters.command(['start']) & filters.private)
async def step1(client, message):
    await message.reply(
      "отправьте ваше имя:"
    )
    pyrostep.register_next_step(
        message.from_user.id,
        step2
    )

async def step2(client, message):
    await message.reply(
        f"Ваше имя: `{message.text}`"
    )

app.run()

Pyrostep предоставляет дополнительные функции, и более подробную информацию можно найти в репозитории Pyrostep по ссылке pyrostep.

→ Ссылка