telegram bot что такое inline mode
Introducing Inline Bots
Bots became an integral part of Telegram for many users, but communication with them wasn’t always easy. You had to send them messages in separate chats or add them to your groups. Today we are introducing a quicker way to contact bots.
With the new inline mode, bots become omnipresent and can be used as a tool in any of your chats, groups or channels – it doesn’t matter, whether the bot is a member or not. Inline bots can help you with dozens of different tasks, like quickly sending relevant GIFs, pictures from the Web, YouTube videos, Wikipedia articles, etc.
We’ve created several sample bots for you to try out: @gif, @vid, @pic, @bing, @wiki, @imdb and @bold. To see them in action, simply type one of their @usernames in the message field in any chat, then type some keywords. The bot will offer you relevant content.
Tap on an item to instantly send it to the chat. This way you can share stuff from bots without any hassle. Inline bots don’t see any messages in your chats – they only receive what you type after their username in the input field.
Tap on ‘via @username’ to send a new request to the bot. Recently used inline bots will also show up in the suggestion box when you type @ in the input field in any chat.
Like pretty much everything else at Telegram, inline bots are part of an open platform, available for free to every developer in the world starting today. Hundreds of new inline bots are sure to arrive once developers start supporting the new mode.
If you are a developer, take a look at our Introduction to Inline Bots. Also, feel free to subscribe to our official @BotNews channel to stay up to date on platform news.
The Telegram Team,
January 4, 2016
Встраиваемые боты (Inline)
⚠️ Важно!
Код, приведённый здесь, актуален для первой версии Bot API. Пожалуйста, откройте урок 8, чтобы узнать о важных изменениях.
Введение
4 января 2016 года разработчики Telegram выпустили большое дополнение к существующему BotAPI, заключающееся в появлении встраиваемых ботов.
К сожалению, не все до конца понимают, в чем их особенность. А вот в чем: если раньше для того, чтобы получить какую-либо информацию от бота и перекинуть её собеседнику нужно было открывать диалог с ботом, писать всякие команды, а потом пересылать ответ в нужный чат, то теперь всё стало быстрее и проще (для некоторых ситуаций): просто открываете нужный чат, вызываете бота, введя его ник в поле ввода сообщения, ставите пробел и пишете свой запрос. Бот отвечает на эти запросы в виде всплывающих подсказок, число и содержание которых зависит от того, что вы написали боту и от заложенного в него алгоритма. Если одна из подсказок удовлетворяет вашему запросу, нажимаете на неё и некоторое сообщение отправляется в тот чат, в котором вы находитесь.
Например, если вы хотите отправить своему собеседнику ссылку на статью о Telegram из русскоязычной Википедии, то достаточно ввести в поле ввода @wiki ru Telegram и подождать пару секунд. Результат представлен на рисунке:
Рис. 1. Как выглядят результаты запросов от встраиваемых ботов
Соответственно, если вы нажмете на одну из этих подсказок, то ссылка на соответствующую статью будет отправлена в текущий чат. Собственно, всё!
Помимо ссылок, при помощи Inline API можно отправлять фотографии, GIF-анимации, видеоанимации в формате Mpeg-4 и ссылки на видеозаписи, которые можно будет смотреть прямо в приложении.
Простой инлайн-бот
Ну а теперь приступим к созданию нашего первого встраиваемого бота. Вообще говоря, никто не мешает добавить существующему Inline-возможности, но дабы не усложнять код, напишем отдельного.
Что же он будет уметь? Пусть на вход боту будут подаваться 2 числа, а он в подсказках будет предлагать основные математические действия: сложение, вычитание, умножение и деление. Да, пример надуманный, но как нельзя лучше показывает особенности Inline API. В начале, зарегистрируем бота у @BotFather (или воспользуемся имеющимся) для него вызовем команду /setinline.
Внимание: после ввода этой команды и выбора бота нужно ввести подсказку, появляющуюся в поле ввода при вызове нашего бота в дальнейшем, иначе фокус не удастся.
Создадим файл исходного кода и добавим туда необходимые импорты и объект самого бота:
Мы условились, что на вход будут подаваться 2 числа, поэтому нам нужно построить регулярное выражение, которое будет реагировать на корректный ввод. Оно очень простое:
digits_pattern = re.compile(r’^1+ 1+$’, re.MULTILINE)
Вооружившись этими знаниями и имея на руках два присланных пользователем числа, давайте создадим 4 объекта, каждый из которых отвечает за свою математическую операцию (на самом деле 5, т.к. учтем деление на ноль):
И можно запускать! Введём в любом чате, кроме секретного, ник нашего бота и два числа. Смотрим на подсказку:
Рис. 2. Результат работы бота
Дизайн и подсказки
В принципе, правильно, но как-то не наглядно. Да и не очень понятно для нового пользователя, как, что и зачем.
А давайте учтем ситуацию, когда пользователь ввёл только ник бота, и покажем ему подсказку:
Уже лучше, но всё равно не очень наглядно. А давайте добавим превью для каждой подсказки, чтобы слева была иконка соответствующей операции, и, заодно, сделаем превью при делении на ноль кликабельным, отправляя пользователя на эту страницу Википедии.
Во-первых, закачаем на какой-нибудь бесплатный хостинг иконки с нашими математическими операциями (сгенерировал в Metro Studio, размер каждой 48х48 px):
Теперь наши результаты выглядят куда симпатичнее:
Инлайн-боты
Помимо отправки команд боту напрямую, пользователи могут использовать вашего бота через инлайн-запросы. Если режим инлайн запросов включён, пользователи смогут обращаться к вашему боту, написав его юзернейм и ключевое слово в поле отправки сообщений в любом чате, группе или канале. Таким образом происходит запрос к боту без непосредственной отправки ему сообщений.
Чтобы включить эту возможность, отправьте команду /setinline пользователю @BotFather и укажите текст-подсказку, который будет отображаться в поле ввода при наборе пользователем имени вашего бота.
Результаты инлайн-запросов
Встроенные боты могут отображать любые данные, доступные в Telegram (19 штук): фильмы, аудиозаписи, стикеры и т. д.
Приложения Telegram могут отображать встроенные результаты как с горизонтальной, так и с вертикальной прокруткой, в зависимости от типа результата.
Как только пользователь нажмёт на предложенный результат, он сразу же отправится в чат, а поле ввода будет очищено.
Переключение между инлайн-режимом и чатом
Ваш бот может отобразить кнопку перехода в личный чат над результатами запроса или вместо них. После перехода и выполнения настроек возможен переход обратно в тот чат, откуда пришёл пользователь с помощью встроенной клавиатуры и метода switch_inline_query
Пример
@youtube — Предлагает войти в аккаунт YouTube, чтобы отобразить персонализированные результаты.
Геоориентированные сервисы
Пример
@foursquare — этот бот будет запрашивать местоположение пользователя для поиска мест поблизости.
Вирусное распространение
Сообщения, отправленные с помощью вашего бота, будут содержать пометку с его именем пользователя рядом с именем отправителя.
Когда пользователь нажимает на юзернейм бота в заголовке сообщения, оно автоматически копируется в поле ввода сообщения. Ввод символа @ в поле ввода сообщения вызовет список недавно использованных ботов.
Сбор статистики
Обратите внимание: в популярных ботах эта функция может вызвать существенную нагрузку из-за кэширования (см. параметр cache_time в answerInlineQuery). Чтобы избежать этого, рекомендуется устанавливать настройку вероятности в 1/10, 1/100 или 1/1000 от результатов.
Примеры инлайн-ботов
Вот небольшой список ботов, работающих в инлайн-режиме. Попробуйте:
Сайт про Telegram на русском (неофициальный).
Здесь собраны приложения на базе MTProto, переведена некоторая документация с официального сайта, а также работает Webogram.
Инлайн-режим¶
Введение¶
В предыдущих главах бот и человек общались каждый сам за себя, однако в 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 Bots
Beyond sending commands in private messages or groups, users can interact with your bot via inline queries. If inline queries are enabled, users can call your bot by typing its username and a query in the text input field in any chat. The query is sent to your bot in an update. This way, people can request content from your bot in any of their chats, groups, or channels without sending any messages at all.
To enable this option, send the /setinline command to @BotFather and provide the placeholder text that the user will see in the input field after typing your bot’s name.
See the Bot API Manual for the relevant methods and objects.
Inline bots support all types of content available in Telegram (20 in all). They are capable of sending stickers, videos, music, locations, documents and more.
Clients can display the results with vertical or horizontal scrolling, depending on the type of content:
As soon as the user taps on an item, it’s immediately sent to the recipient, and the input field is cleared.
Some inline bots can benefit from an initial setup process, like connecting them to an account on an external service (e.g., YouTube). We’ve added an easy way of switching between the private chat with a bot and whatever chat the user wants to share inline results in.
You can display a special ‘Switch to PM’ button above the inline results (or instead of them). This button will open a private chat with the bot and pass a parameter of your choosing, so that you can prompt the user for the relevant setup actions. Once done, you can use an inline keyboard with a switch_inline_query button to send the user back to the original chat.
Sample bots
@youtube – Shows a ‘Sign in to YouTube’ button, then suggests personalized results.
Inline bots can request location data from their users. Use the /setinlinegeo command with @BotFather to enable this. Your bot will ask the user for permission to access their location whenever they send an inline request.
Sample bot
@foursquare – This bot will ask for permission to access the user’s location, then provide geo-targeted results.
Messages sent with the help of your bot will show its username next to the sender’s name.
When a user taps on the bot username in the message header, the mention is automatically inserted into the input field. Entering the @ symbol in the input field brings up a list of suggestions, featuring recently used inline bots.
To know which of the provided results your users are sending to their chat partners, send @Botfather the /setinlinefeedback command. With this enabled, you will receive updates on the results chosen by your users.
Please note that this can create load issues for popular bots – you may receive more results than actual requests due to caching (see the cache_time parameter in answerInlineQuery). For these cases, we recommend adjusting the probability setting to receive 1/10, 1/100 or 1/1000 of the results.
Here are some sample inline bots, in case you’re curious to see one in action. Try any of these:
@gif – GIF search
@vid – Video search
@pic – Yandex image search
@bing – Bing image search
@wiki – Wikipedia search
@imdb – IMDB search
@bold – Make bold, italic or fixed sys text