Что такое inline mode telegram bot
Инлайн-боты
Помимо отправки команд боту напрямую, пользователи могут использовать вашего бота через инлайн-запросы. Если режим инлайн запросов включён, пользователи смогут обращаться к вашему боту, написав его юзернейм и ключевое слово в поле отправки сообщений в любом чате, группе или канале. Таким образом происходит запрос к боту без непосредственной отправки ему сообщений.
Чтобы включить эту возможность, отправьте команду /setinline пользователю @BotFather и укажите текст-подсказку, который будет отображаться в поле ввода при наборе пользователем имени вашего бота.
Результаты инлайн-запросов
Встроенные боты могут отображать любые данные, доступные в Telegram (19 штук): фильмы, аудиозаписи, стикеры и т. д.
Приложения Telegram могут отображать встроенные результаты как с горизонтальной, так и с вертикальной прокруткой, в зависимости от типа результата.
Как только пользователь нажмёт на предложенный результат, он сразу же отправится в чат, а поле ввода будет очищено.
Переключение между инлайн-режимом и чатом
Ваш бот может отобразить кнопку перехода в личный чат над результатами запроса или вместо них. После перехода и выполнения настроек возможен переход обратно в тот чат, откуда пришёл пользователь с помощью встроенной клавиатуры и метода switch_inline_query
Пример
@youtube — Предлагает войти в аккаунт YouTube, чтобы отобразить персонализированные результаты.
Геоориентированные сервисы
Пример
@foursquare — этот бот будет запрашивать местоположение пользователя для поиска мест поблизости.
Вирусное распространение
Сообщения, отправленные с помощью вашего бота, будут содержать пометку с его именем пользователя рядом с именем отправителя.
Когда пользователь нажимает на юзернейм бота в заголовке сообщения, оно автоматически копируется в поле ввода сообщения. Ввод символа @ в поле ввода сообщения вызовет список недавно использованных ботов.
Сбор статистики
Обратите внимание: в популярных ботах эта функция может вызвать существенную нагрузку из-за кэширования (см. параметр cache_time в answerInlineQuery). Чтобы избежать этого, рекомендуется устанавливать настройку вероятности в 1/10, 1/100 или 1/1000 от результатов.
Примеры инлайн-ботов
Вот небольшой список ботов, работающих в инлайн-режиме. Попробуйте:
Сайт про Telegram на русском (неофициальный).
Здесь собраны приложения на базе MTProto, переведена некоторая документация с официального сайта, а также работает Webogram.
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 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
Инлайн-режим¶
Введение¶
В предыдущих главах бот и человек общались каждый сам за себя, однако в 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 не рекомендует из-за удвоения нагрузки на бота. Таким образом, для сколько-нибудь серьёзной аналитики подобная фича не подходит, но в умелых руках и за большой период времени может дать общее представление о наиболее полезных инлайн-результатах. Пример хэндлера на подобные события:
Bot API v2: Специальные кнопки, опять редактирование сообщений, кэшированный инлайн
Продолжаю рассказывать о нововведениях в Bot API версии 2. Мы не будем рассматривать методы getChat, getChatMember и т.д., которые появились в обновлении 2.1: они интуитивно понятны и особых проблем не вызывают. Вопросы могут возникнуть при изучении специальных обычных кнопок, вроде тех, что запрашивают у вас номер телефона и геолокацию, при попытке получить отредактированное сообщение, а также при работе с уже загруженными в облако объектами с инлайн-режимом. Обо всём по порядку.
Специальные кнопки
Нажатие на кнопку запроса телефона
При нажатии на кнопку отправки номера телефона сервер вернёт объект Message с непустым типом Contact, а при нажатии на кнопку отправки геолокации – с непустым типом Location.
Редактирование сообщений пользователями
Начиная с мая 2016 года, пользователи могут редактировать свои сообщения, а боты могут видеть исправления. Как им в этом помочь, давайте разберёмся вместе. В качестве примера заставим нашего бота отвечать на ругательства. К примеру, если пользователь пишет “дурак”, бот ответит “сам дурак”. Хитрые люди могут попробовать отредактировать своё сообщение и выставить бота в дурном свете, но мы будем изменять ответ бота под пользовательский текст.
Заметили? Да, при вызове edit_message_text надо указать message_id на единицу бОльший, чем тот, который прислан сервером, потому что сервер сообщает о сообщении от пользователя, а нам нужно редактировать сообщение бота, которое шло за ним следом. И вот как это будет выглядеть (это одни и те же сообщения, что видно по метке “изм.” около моего)
Кэшированный инлайн
Когда инлайн-боты только появились, то в качестве источника данных для ответов надо было указывать внешние ссылки, причем с ограничениями по размеру указываемого файла. Очевидно, такой подход мог быть не очень быстрым, а чем дольше пользователь ждёт, тем он менее доволен результатами работы бота 🙂 В итоге, в Bot API v2 инлайн-режиму разрешили в качестве источника для медиа использовать file_id уже имеющихся на сервере файлов (напомню, что file_id для одного и того же файла будут разниться от бота к боту) Итак, у меня есть file_id двух фотографий с капибарами (как получить file_id загружаемых боту фотографий, считайте это заданием для самоподготовки), надо на любой инлайн-запрос (даже пустой) предложить эти 2 изображения. По сути, всё сводится к замене типа InlineQueryResultPhoto на тип InlineQueryResultCachedPhoto
Запускаем бота. Ура, теперь мы умеем очень быстро предлагать разных капибар нашим пользователям 🙂
Можно сделать альбом капибар
Помимо фотографий, из “кэша” можно показывать любые типы, поддерживаемые мессенджером: видео, аудио, стикеры, файлы (пока что только pdf и zip ).
На этом всё. Хороших ботов!