Учебник | Python | Discord.py

Добавление индикатора набора текста к вашему боту Discord.py

Как сделать действия вашего бота более естественными, если он набирает текст перед отправкой сообщений

Еще одно из серии улучшений для нашего бота Discord.py, на этот раз мы собираемся добавить индикаторы набора текста.

Индикаторы набора текста стали основой современных приложений чата, позволяя нам видеть, когда кто-то собирается что-то отправить. Нет ничего более раздражающего, чем эти проклятые пользователи Android и их зеленые пузыри чата, которые не отображаются, когда они набирают ответное сообщение! Давайте сделаем наших ботов лучше этих людей.

Никогда раньше не работали с Discord.py? Ознакомьтесь с моим руководством по созданию простого бота здесь:



Предоставить боту возможность печатать перед отправкой ответа несложно. Фактически он основан на следующей очень простой строке кода:

async with ctx.typing():
    # Long Calculation

Код ломается довольно просто. async указывает python выполнять команду асинхронно, что означает, что другие команды все еще могут выполняться, пока выполняется эта. Далее идет ключевое слово with. Это создает диспетчер контекста для ctx.typing(). ctx сообщает python, где отображать индикатор набора текста. В этом случае мы создадим команду, которая имитирует длительную задачу, набирая ее во время выполнения задачи. Давайте посмотрим на это в действии:

Довольно аккуратно, да? Давайте создадим эту typing команду:

Наша команда начинается так же, как и все другие команды, которые мы определили до сих пор. У нас есть декоратор и заголовок функции. Функция принимает контекст запроса ctx в качестве аргумента. В новой части мы используем метод typing объекта контекста для создания обработчика контекста. Обработчик контекста создается, когда мы используем ключевое слово with. Все, что происходит в обработчике контекста, будет выполняться, пока бот печатает.

Чтобы продемонстрировать, как это работает, мы просто добавили sleep на 2 секунды. Важно отметить, что мы используем sleep из модуля asyncio. В этой версии бот может обрабатывать другие команды, набирая здесь. sleep из модуля time не позволит боту обрабатывать другие команды.

Вне обработчика контекста with мы отправляем наш результат в ctx. Это придает ему видимость набора текста, пока что-то вычисляется.

Но у меня нет долгих расчетов!

Не волнуйтесь, вам не нужны долгие вычисления, чтобы использовать диспетчер контекста набора текста. Мы можем вернуться к нашей команде Hello World и добавить индикатор ввода перед ответом. Это будет выглядеть так, будто бот печатал «Hello World!» Это заставит бота почувствовать себя более живым и придаст ему дополнительные мелкие детали, которые заставят его чувствовать себя намного более отполированным и профессиональным.

Поздравляю! Теперь вместо того, чтобы просто ответить на команду, бот будет печатать полсекунды, прежде чем ответить!

Но настоящие люди не печатают слишком много времени!

Я слышу тебя. Давайте сделаем это еще более реальным. Мы можем сделать это с помощью встроенного random модуля Python.

Давайте рассмотрим наши требования. Мы хотим, чтобы бот печатал произвольное время в разумных пределах. У этого количества времени должно быть приличное количество вариаций. Мы бы не хотели, чтобы он каждый раз просто выбирал от 0,5 до 1,5 секунд.

Исходя из этих требований, нам нужна функция, которая генерирует числа с плавающей запятой между указанным диапазоном. Модуль random имеет это с функцией uniform. Он берет два числа и выбирает между ними число с плавающей запятой, причем все числа в диапазоне равновероятны. Давайте посмотрим на это в действии:

>>> import random
>>> random.uniform(0.5, 2)
[1] 1.475443943500942

Каждый раз, когда вы запускаете его, вы будете получать другое число, поэтому не беспокойтесь, если ваш результат отличается от моего. Давайте создадим это случайное число в нашем блоке with, а затем используем asyncio.sleep, чтобы ввести это количество секунд, прежде чем ответить, сколько секунд было введено. Мы просто используем небольшое форматирование строки, чтобы добавить переменную в ответ.

Попробуйте, вы заметите, что бот будет печатать немного разное количество раз при каждом ответе.

Вывод

Добавить индикаторы набора текста к вашему боту довольно просто. Просто используйте ключевое слово with и ctx.typing, чтобы создать обработчик контекста для вашей задачи набора текста. Жаждете чего-то более красивого? Используйте модуль random, чтобы добавить элемент случайности к тому, как долго бот набирает каждый раз.

Далее будет интереснее форматировать текст. Пока что у бота были только простые текстовые ответы. Следующее, что нужно решить, - это использовать встроенные и эмодзи, как обычные, так и в Discord.

Полный код