что такое inline кнопка
Встроенные кнопки в Telegram Bot API — pyTelegramBotAPI
Добрый день уважаемые читатели, давайте рассмотрим, какие основные типы встроенных кнопок предлагают чат-боты telegram и в чем их особенности. Статья будет полезна всем, кто хочет разобраться в возможностях взаимодействия с пользователями telegram в версии bot API 2.0.
Для обзора возможностей нам понадобится установить 3 целых 2 десятых Python`a и пару ложек pyTelegramBotAPI. Особенности настройки и регистрации чат-бота мы рассматривать не будем, т.к. есть множество статей на эту тему.
И так, что же такое встроенные кнопки(клавиатура) в мессенджере Telegram? Это кнопки которые выводятся во внутренней области чата и привязываются к конкретному сообщению. Они жестко связаны с сообщением(если удалить сообщение, внутренние кнопки так же удаляются вместе с ним.). Они дают возможность динамически видоизменять его.
В данный момент есть три типа встроенных кнопок:
URL-кнопки
Для создания кнопки используется тип InlineKeyboardMarkup, давайте создадим кнопку «Наш сайт»:
Тут название говорит само за себя, это тип кнопок предназначен для перенаправления пользователя по ссылке, с соответствующим предупреждением. Кнопка имеет соответствующий ярлычок в правом верхнем углу, чтобы дать понять пользователю, что это ссылка.
Switch-кнопки
Этот тип кнопок предназначен для перенаправления пользователя в какой либо чат, с последующей активацией (встроенного) inline-режима общения с ботом. Данный режим можно активировать вручную: в чате, вводим: «@название бота», но switch-кнопки позволяют это сделать автоматически (помогая знакомиться с inline-режимом новичкам).
Для того что-бы создать подобный переключатель, необходимо указать аргумент switch_inline_query либо пустой, либо с каким-либо текстом.
Теперь, если мы нажмем на кнопку и выберем чат, вот что получится:
Шаг 1:
Нажимаем на кнопку.
Шаг 2:
Выбираем чат.
Шаг 3:
Активировался встроенный inline-режим.
Callback-кнопки
Ну и наконец самое интересное — это кнопки с обратной связью: позволяют динамически обновлять сообщение/встроенные кнопки (не засоряя при этом ленту), а так же отображать уведомление в верху чат-бота или модальном окне.
Например, их можно использовать для просмотра длинного сообщения, аналогично пагинации страниц на сайтах, или например сделать календарь. Я не стану изобретать велосипед, а через поиск по GitHub, найду готовую библиотеку calendar-telegram. Выполнив указанные инструкции, получаем готовый календарь, который можно динамически изменять по нажатию на соответствующие кнопки:
Так же можно добавить уведомление по нажатию на дату, для этого достаточно указать сообщение в ответе:
(Пример в десктопной версии)
(Пример в мобильной версии)
Если изменить show_alert на True, то мы получим модальное окно:
Заключение
По последним данным, в нашумевшем мессенджере Telegram регистрируются больше 600к пользователей ежедневно. Именно поэтому важно подхватить тренд и разобраться с его основными особенностями, т.к. различные методы взаимодействия с ботами существенно облегчает жизнь разработчиков и пользователей.
Урок 5. Клавиатуры и кнопки
В сегодняшнем уроке мы разберём шаблоны сообщений и инлайн-клавиатуры и научимся применять встроенные в aiogram методы для составления сложных клавиатур.
Весь код, использованный в уроке, как обычно доступен на GitHub
Для начала стоит понять, в чем основное различие ReplyKeyboardMarkup и InlineKeyboardMarkup :
ReplyKeyboardMarkup — это шаблоны сообщений. К примеру, ваш бот задаёт пользователю вопрос и предлагает варианты ответа. Пользователь может самостоятельно напечатать ответ, либо нажать на готовую кнопку. Такая клавиатура показывается вместо основной и не привязана ни к какому сообщению. В кнопки такой клавиатуры нельзя заложить никакой информации, нельзя запрограммировать для неё подобный если пользователь нажимает кнопку с текстом «abc» отправить текст «qwerty» алгоритм, отправлено будет только то, что написано на кнопке (есть два исключения, о которых ниже).
InlineKeyboardMarkup — это уже настоящая кастомная клавиатура. С её помощью мы можем выполнять более сложные действия. Она привязывается к сообщению, с которым была отправлена. В кнопки можно заложить любой текст размером от 1 до 64 байт (будьте осторожны, недобросовестные клиенты позволяют изменять эти данные). Инлайн кнопки позволяют скрыть в себе внутреннюю телеграм ссылку, ссылку на внешний ресурс, а также шорткат для инлайн запроса (об инлайн режиме в одном из следующих уроков).
Переходим к коду
Создадим отдельный модуль с клавиатурами, которые будем использовать в основной программе.
В первую очередь импортируем необходимые нам модули и создаём первую клавиатуру:
Создаём обработчик, который будет отправлять нам сообщение и наш шаблон (напомню, что отправить отдельно клавиатуру никак нельзя, она является параметром к сообщению).
Запускаем и проверяем:
Мы передали параметр в инициализатор и следом сразу добавили уже существующую кнопку. Отправляем новую версию клавиатуры:
Очевидно, так как у нас нет обработчика обычных сообщений, текст, отправляемый нажатием на эту кнопку, остаётся без ответа. При желании можно добавить функцию эхо из первого урока. А что ещё можно было заметить при использовании этой кнопки? Что она остаётся всё там же, даже если мы после нажатия хотели бы вернуться к привычной клавиатуре. Да, нажать одну кнопку, чтобы переключиться, не сложно. Но если клавиатура в принципе не подразумевает повторного нажатия прямо сейчас? И для этого тоже есть решение:
Эти параметры можно комбинировать. Вследствие чего мы получили маленькую клавиатуру, которая скрывается после одной отправки. Но пользователь может снова её открыть нажатием на соответствующую кнопку в поле ввода.
Добавляем больше кнопок
Отправляем все готовые кнопки и смотрим на результат:
Думаю, здесь достаточно наглядно видно работу методов добавления кнопок в разметку.
И последнее по этому виду клавиатур. ReplyKeyboardMarkup позволяет запросить у пользователя его контакт или локацию. Это те самые два исключения из правила, когда при нажатии кнопки будет отправлено не то, что написано на ней. Их можно отправлять как по одной, так и в составе более сложной клавиатуры. Добавим обе кнопки и посмотрим, что будет (обращу внимание читателя на то, что нельзя одной кнопкой запросить сразу и то и то):
При нажатии на каждую из этих кнопок клиент (приложение Телеграм) спросит, уверены ли вы, что хотите поделиться с ботом этими данными и при утвердительном ответе отправит их.
После каждой отправки ботом пользователю клавиатуры, последняя заменяет предыдущую. Поэтому пользователь всегда может открыть её, даже когда по контексту она не нужна. Для того, чтобы у пользователя в клиенте клавиатура убралась совсем, нужно отправить ему ReplyKeboardRemove :
Получив сообщение с такой клавиатурой, клиент уберёт шаблоны полностью.
Инлайн клавиатуры
Теперь перейдем к инлайн клавиатурам. Они имеют больше параметров, поэтому позволяют нам делать больше разных вещей. Самое популярное использование — как кнопка, являющаяся шорткатом для какого-то действия. То есть «если пользователь нажал кнопку X, сделать Y». И под Y можно понимать вообще что угодно, так как это уже не ограничивается даже API. Рассмотрим наглядно, для этого передадим в инициализатор значение callback_data :
Здесь мы делаем проверку прямо в хэндлере. Аргумент func ожидает функцию, которая принимает один параметр (туда передаётся апдейт), и хэндлер срабатывает, если возвращается истина. Этот аргумент можно использовать и в других хэндлерах, мы уже использовали его в уроке по FSM.
Внутри мы можем делать вообще что угодно, так как работаем с обычным питоном. Подача корма для кошки? Управление светом? Пределом является только ваша фантазия.
В этот раз установим ширину клавиатуры 2 и посмотрим, что будет.
Ну и так как методы добавления новых элементов мы уже разобрали, добавим сразу все доступные кнопки и отправим получившуюся клавиатуру, не забыв добавить хэндлер кнопок:
Пройдёмся по строчкам по порядку, чтобы не осталось вопросов:
Так как параметр клавиатуры row_width равен двум, то кнопки автоматически расставились соответствующе. Рассмотрим реакцию на кнопки по порядку: При нажатии первой срабатывает наш первый колбек, так как не важно, в какую клавиатуру добавлена кнопка, важно, какая у неё callback_data ☝️. Поэтому добавлять инлайн кнопку можно сколько угодно раз в любые инлайн клавиатуры.
И во всех случаях шлем сообщение пользователю:
На последок не забываем добавить обработку команы /help и запускаем:
Вот и всё!
В этом уроке мы разобрали как работать с клавиатурами в Телеграм
Инлайн-режим¶
Введение¶
В предыдущих главах бот и человек общались каждый сам за себя, однако в Telegram существует специальный режим, позволяющий пользователю отправить информацию от своего имени, но с помощью бота. Это называется инлайн-режим (Inline mode). Как это выглядит в реальной жизни:
Как видно на скриншоте выше, итоговое сообщение отправлено от имени пользователя, но предварительный список был предоставлен ботом @imdb. Подробное описание инлайн-режима с точки зрения пользователя можно найти на официальном сайте, а в этой главе мы напишем собственного простого инлайн-бота для упрощения поиска и отправки ссылок на любимые YouTube-видео.
Формат инлайн-запросов и ответов¶
Для ответа на запрос необходимо вызвать метод answerInlineQuery, куда следует передать массив объектов-результатов, и дополнительно различные флаги, о которых поговорим чуть позже. Типов объектов-результатов аж целых двадцать, однако многие из них являются вариациями друг друга. Так, например, InlineQueryResultPhoto содержит ссылку (URL) на изображение, а InlineQueryResultCachedPhoto — file_id уже загруженного в Telegram изображения. Более того, рекомендуется использовать объекты одного типа в инлайн-ответе, поскольку клиентские приложения некорректно отображают (или не отображают вовсе) смешанный контент.
Обратите внимание: в инлайн-режиме нельзя загружать новые медиафайлы в Telegram, только использовать уже имеющиеся в облаке, либо указывать URL из Интернета.
Одним из наиболее часто используемых типов объектов-результатов является InlineQueryResultArticle — просто текст. Рассмотрим основные элементы такого объекта внимательнее:
Цифрами на рисунке выше обозначены: 1 — заголовок объекта; 2 — описание; 3 — предпросмотр; 4 — ссылка, по которой перейдёт пользователь если нажмёт на (3). Всё, кроме (1) необязательно, но позволяет визуально разнообразить выдаваемые результаты. Но что отправится в чат, если нажать не на предпросмотр, а на то, что справа от него? Для этого существует тип InputMessageContent, представленный четырьмя подтипами: Текст, Геолокация, Достопримечательность (Venue) и Контакт. В самом простом случае, пользователь видит такой список ссылок, нажимает на один из элементов и получает текст, указанный в InputTextMessageContent.
Сложно? Но и это ещё не всё! InputMessageContent можно использовать и с другими типами инлайн-объектов, например, выдавать пользователю в ответ стикеры, а при нажатии отправлять ссылку на весь стикерпак. Или описание фильма при нажатии на обложку в инлайн-режиме. Экспериментируйте!
Пишем бота¶
От теории — к практике. Опишем суть будущего бота: пользователь в диалоге с ботом добавляет (или обновляет) ссылку на видео с YouTube и указывает собственное описание. Далее в любом другом чате он вызывает бота в инлайн-режиме, выбирает в списке одно из сохранённых ранее видео и отправляет его. Дополнительно можно ввести текст, по наличию которого результаты будут отфильтрованы. Разумеется, у каждого юзера должен быть свой собственный набор сохранённых ссылок.
Предупреждение об используемых технологиях
Поскольку главная цель этой главы — рассказать об инлайн-режиме, то сопуствующие детали, такие как реализация работы с базой данных и хранилищем FSM, будут сознательно упрощены и/или не упомянуты в тексте. Так, например, в качестве FSM будет использован MemoryStorage, а в роли СУБД подойдёт и SQLite. В реальности рекомендуется использовать персистентное хранилище FSM (напр. Redis) и более продвинутую СУБД (напр. PostgreSQL), а также отдельный поисковый движок (ElasticSearch, Sonic. ).
Хранение данных¶
Исходя из приведённого выше «техзадания», сделаем вывод, что каждое сохранённое видео можно описать тремя обязательными сущностями: Telegram ID пользователя, идентификатор YouTube-видео (извлекается из URL) и пользовательское описание. Первые два элемента образуют первичный ключ, что даёт ограничение уникальности для каждой пары «Telegram_ID + YouTube_ID». Описание таблицы в БД выглядит следующим образом:
Ранее мы договорились, что не будем особо рассматривать работу с БД, и сконцетрируемся на особенностях инлайн-режима, однако две функции всё же стоит рассмотреть для дальнейшего понимания. Первая — добавление ссылки с описанием в базу данных. Здесь можно применить один трюк, называемый «UPSERT», т.е. Insert or Update. Дело в том, что, сформировав SQL-запрос специальным образом, можно при вставке данных (Insert) в случае нарушения уникальности не выбрасывать ошибку, а неявно обновлять затронутую строку (Update). Посмотрите на следующий кусок кода. В нём мы пытаемся добавить новую строку в базу данных, однако если указанная пара «Telegram_ID + YouTube_ID» уже существует, то вместо вставки обновляется описание ( description ):
Switch-кнопки¶
Просмотр и удаление ссылок в личке с ботом делается элементарно, а добавление организуется с помощью простейшего конечного автомата (подробнее о механизме FSM можно узнать в предыдущей главе). Здесь стоит обратить внимание на последний шаг, когда идёт непосредственно добавление записи и подтверждение юзеру:
Обработка инлайн-запроса¶
Перейдём непосредственно к обработке запроса от юзера к боту в инлайн-режиме. В некоторых случаях удобно делать отдельный хэндлер на пустой запрос (когда длина текста в поле query объекта InlineQuery равно нулю) и показывать какой-нибудь «общий» ответ или приглашение перейти к боту, однако в нашем случае любой, даже пустой запрос, требует обращения к БД, поэтому объединим оба случая в одном хэндлере. Рассмотрим первый вариант: у пользователя нет сохранённых ссылок или он ввёл запрос, по которому ничего не нашлось. Смотрим код:
Автор этих строк однажды забыл указать флаг is_personal в его боте @my_id_bot, выставил кэш на 86400 секунд (1 сутки) и выслушал много возмущений от пользователей, отправлявших его ID вместо их собственных. Учитесь на чужих ошибках, не на своих.
Теперь рассмотрим второй случай: по запросу пользователя нашлись какие-то ссылки. Сформируем массив объектов-результатов типа InlineQueryResultArticle:
Итого полный текст инлайн-обработчика будет выглядеть следующим образом:
А вы знали, что, имея YouTube-хэш, можно легко получить различные превью к видео? Если нет, то добро пожаловать в этот чудесный пост на StackOverflow.
Switch туда и обратно¶
На этом с ботом всё, исходные тексты к главе смотрите в репозитории, доступным по нажатию на кнопку в правом верхнем углу. Но прежде, чем закончить с инлайн-режимом, надо рассмотреть ещё пару интересных особенностей.
Дополнительные материалы¶
Подгрузка результатов¶
Теперь давайте перепишем наш инлайн-хэндлер таким образом, чтобы при приближении к концу текущего списка запрашивать продолжение. Для этого в начале проверяем поле offset и ставим его равным единице, если оно пустое. Далее генерируем фейковый список результатов. Если на выходе ровно 50 объектов, то в ответе указываем next_offset равный текущему значению + 50. Если объектов меньше, то его делаем пустой строкой, чтобы Telegram больше не присылал запросы боту.
По мере листания инлайн-результатов, бот будет получать запросы и возвращать всё новые и новые результаты, пока не дойдёт до 195-го элемента, дальше запросы прекратятся.
Сбор статистики¶
Числа на кнопках означают вероятность получения события ChosenInlineResult при выборе пользователем какого-либо объекта в инлайн-режиме. Так, например, если выставлено значение 10%, то при каждом выборе объекта существует вероятность в десять процентов получить событие ChosenInlineResult в боте. Выставлять значение 100% Telegram не рекомендует из-за удвоения нагрузки на бота. Таким образом, для сколько-нибудь серьёзной аналитики подобная фича не подходит, но в умелых руках и за большой период времени может дать общее представление о наиболее полезных инлайн-результатах. Пример хэндлера на подобные события:
Inline-кнопки
В канале Telegram есть возможность добавить inline-кнопки. Такие кнопки будут отображаться не под полем ввода, а над.
Возможность добавить inline-кнопки есть только в Telegram, другие каналы такую функциональность не поддерживают.
Обычные кнопки располагаются под полем ввода текста («Написать сообщение. «). Количество кнопок в строке определяется автоматически, в зависимости от количества кнопок и объема текста в них. На одном экране может быть не более восьми кнопок:
Inline-кнопки располагаются над полем ввода текста:
Как использовать inline-кнопки?
Возьмем, к примеру, такой экран. Изначально кнопки на нем будут отображаться в Telegram как обычные кнопки:
Есть два способа превратить эти обычные кнопки в inline-кнопки.
Добавить на нужный экран кнопку со ссылкой
Чтобы обычные кнопки превратились в Inline-кнопки, добавьте на этот же экран хотя бы одну кнопку-ссылку. Например, вы можете ссылку на ваш сайт.
После этого нужно нажать Опубликовать, чтобы изменения пришли в канал. Дождитесь всплывающего сообщения о том, что сценарий был опубликован на канале Telegram.
Добавить «пустую» кнопку
Второй способ подойдет вам, если кнопка-ссылка не подходит для вашего сценария.
Нажмите Опубликовать и дождитесь сообщения о публикации в канал.
Обычные кнопки превратятся в Inline-кнопки, а кнопка, которая содержит только символ пробела, отображаться не будет.
Особенности канала Telegram
Есть некоторые особенности отображения кнопок, которые нужно учитывать.
Не всегда сразу же можно увидеть новый вариант кнопок. Иногда нужно пройти по другой ветке бота, затем послать /start и вернуться на экран с кнопками.
Если у вас есть два экрана, которые идут друг после друга, и на первом экране обычные кнопки, а на втором inline-кнопки, то при перехода на экран с Inline-кнопками, обычные кнопки не исчезнут.
К примеру, возьмем два таких экрана. На экране, выделенном синим, обычные кнопки. На экране, выделенном зеленым, Inline-кнопки.
После нажатия на кнопку «цены» бот перейдет на второй экран, на котором должны отображаться Inline-кнопки. Но из-за особенностей канала, обычные кнопки не исчезнут.
Вы можете пользоваться таким поведением, если для вас даже удобно отображать два вида кнопок. Либо, если для вас такое поведение неудобно, разделяйте экраны с обычными кнопками от экранов с Inline-кнопками другими экранами текста с интентами вместо кнопок, чтобы не было такой последовательности.
Как управлять Инлайн кнопками
@MenuBuilderBot позволяет вам прикреплять инлайн кнопки к сообщениям бота. Это руководство поможет вам работать с инлайн кнопками (клавиатурой). В руководстве описаны типы инлайн кнопок и способы их использования.
❖ Что такое Инлайн Кнопки (клавиатура)
На данный момент в @MenuBuilderBot есть 3 типа инлайн кнопок:
● URLs (ссылки)
● Всплывающее окно
● Команды
❖ Как добавить инлайн кнопки
1. Перейдите в «Редактор Постов» и создайте сообщение (так же как обычно) или используйте для этого уже готовое сообщение.
2. Зайдите в «Настройки сообщения» нажав на кнопку со звёздочкой («*»):
3. Нажмите одну из «➕ Инлайн Кнопка»
Разница между «➕ Инлайн Кнопка ➡️» и «➕ Инлайн Кнопка ⬇️» будет описана ниже.
4. Создайте сообщение из двух строк.
Из ДВУХ строк!
Первая строка всегда будет заголовком кнопки.
Вторая строка может иметь разные значения в зависимости от режима в котором создается инлайн кнопка.
Используйте кнопку с названием режима для переключения между режимами:
Режимы инлайн кнопок
Режим 1: URL или Share кнопка.
Вторая строка должна содержать корректный адрес (URL). Например:
Когда пользователь нажимает такую кнопку будет открыт указанный в кнопке URL:
Режим 2: Всплывающее окно.
Вторая и остальные строки дложны содержать текст (не более 200 символов) который будет показан во всплывающем окне. Например:
Когда пользователь нажимает такую кнопку, указанный в ней текст будет показан в таком всплывающем окне.
Режим 3: Команда.
Вторая строка должна содержать действующую команду назначенную какой-либо кнопке меню вашего бота (подробное руководство по командам по ссылке).
Кроме команд назначенных кнопкам, вы можете использовать команды:
/home
для обращения к Главному Меню вашего бота.
/start
будет работать как обычная команда /start отправленная боту.
Когда пользователь нажимает такую инлайн-кнопку, сообщения связанной кнопки будут показаны.
Теперь у вас есть инлайн кнопка!
❖ Как удалить инлайн кнопку
• Перейдите в вашем боте:
☞ Редактор Постов.
• Нажмите кнопку нижнего меню содержащую сообщение, инлайн кнопку которого вы хотите удалить.
• Нажмите инлайн кнопку со звездочкой ( * ), под этим сообщением, для попадания в его Настройки.
• Нажмите необходимую инлайн кнопку, чтобы удалить её.
Если вы уже находитесь в редакторе инлайн кнопок и все кнопки помечены крестиком, то можно просто нажать на кнопку которую нужно удалить.
В сообщении об удалении будут показаны данные удалённой кнопки. При необходимости их можно скопировать и создать кнопку заново, внеся нужные изменения при необходимости.
❖ Расположение инлайн кнопок
Новая инлайн кнопка может быть помещена в один ряд с последней созданной или на новой строке.
Когда создаёте вторую и последующие кнопки нажатие:
«➕ Инлайн Кнопка ➡️» (вправо) поместит новую кнопку в том же ряду, справа от последней.
«➕ Инлайн Кнопка ⬇️» (вниз) поместит новую кнопку на новую строку снизу.
Вы можете комбинировать кнопки чтобы создать нечто подобное:
Когда вы нажмёте «Выйти из настроек сообщения» все изменения будут сохранены.
После нажатия «Стоп редактор» вы увидите результат (таким, каким его увидит пользователь):
❖ Удаление инлайн меню и сообщений из истории чата
Сообщение с инлайн кнопками типа «Команда» можно удалять автоматически после того, как юзер кликнул на кнопку с командой. По умолчанию НЕ удаляется.
Функция сделана для того чтобы не смущать юзера неактуальными кнопками разбросанными в теле чата. Она позволяет автоматически удалять отработавшие меню (и сообщения к которым оно подцеплено), позволяя в последствии избежать нежелательных нажатий.
В общем случае сообщение это описывает, поясняет или содержит данные изменяемые кнопками его инлайн меню и не имеет смысла без самого меню. Технически можно удалить инлайн меню не удаляя сообщения, однако такое поведение не является востребованным, потому из двух вариантов был выбран тот который выбран. )
В некоторых случаях результат удаления бывает не предсказуемым, поэтому нужный вам режим чаще всего подбирается опытным путём.
Для настройки Удаления инлайн меню перейдите в вашем боте:
☞ 🔐Админ | ⚙️Настройки Бота
❖ Ошибки при работе с инлайн кнопками
ОШИБКА: Вы не пользовались ботом некоторое время и при нажатии на инлайн кнопку (или обычную нижнего меню) бот переносит вас в «Главное Меню».
ПРИЧИНА: Рабочая сессия бота завершается после 30 минут бездействия. При этом, в целях безопасности любые «закрытые» разделы бота (условием, капчей и д.р.) становятся недоступны. Попасть в них можно только снова пройдя весь путь через кнопку закрывающую вход. При этом если инлайн кнопка (или обычная кнопка нижнего меню) находится или ведет в такой «закрытый» раздел бот не позволит ей сработать пока вход в этот раздел юзером не будет снова осуществлен через кнопку фактически закрывающую вход.
ОШИБКА: Вы создали новую Inline-кнопку в режиме команды которая ведёт в глубь нижнего меню и она не показывает нужное сообщение.
ПРИЧИНА: Кнопка нижнего меню к которой обращается команда инлайн кнопки находится внутри «закрытой» зоны бота. Обращение к закрытой зоне извне не возможно. Это обеспечивает безопасность закрытых зон.