Telegram bot пример — Написать Telegram клиент

Чем отличается Telegram от других популярных мессенджеров? Он — открытый! Другие мессенджеры тоже имеют API, но почему-то именно телеграм известен как наиболее открытый из самых популярных?

Начнем с того, что у Telegram действительно полностью открытый клиентский код. К сожалению, мы не видим комиты каждый день прямо на GitHub, но у нас есть код под открытой лицензией. Архитектура Telegram подразумевает, что и Bot и API имеет практически такие же методы — https://core.telegram.org/methods.

На самом деле, Telegram представляет не просто чат-мессенджер, а социальную платформу, доступ к которой открыт для разного рода приложений. Они могут предоставлять дополнительные фишки пользователям, взамен используя готовую сеть пользователей и сервера для доставки сообщений. Звучит настолько привлекательно, что нам захотелось попробовать написать своего «клиента» для Телеграм.

Суть приложения

В основном мы занимаемся картами и навигацией, поэтому мы сразу смотрели что-нибудь связанные с геолокацией. Мне очень понравилось, что в Telegram, раньше всех остальных приложений, появился удобный способ делится местоположением в реальном времени (https://telegram.org/blog/live-locations) и я достаточно часто этим пользуюсь: помочь сориентироваться другу, показать дорогу и самое главное ответить на главный вопрос «Когда ты будешь?». В принципе, этого хватает большинству людей, но как всегда есть сценарии, когда простых возможностей не хватает. Например, это может быть группа более 10 человек, с разными устройствами (некоторые устройства возможно не являются телефонами) и разными людьми. Этим людям было бы удобно обмениваться сообщениями в группе, а также видеть перемещения друг друга на карте.

Во главу угла мы поставили задачу создать дополнительную ценность для Telegram, а не пытаться использовать его не по назначению. Мы не хотели, чтобы люди у которых нет специального клиента Телеграм, видели в чате месиво сообщений или что-то невразумительное. У людей с «улучшенным» клиентом, появляются же дополнительные возможности, например:

  1. Более тонкое управление временем при отправке локации в реальном времени в чат.
  2. Просмотр местоположения контактов на карте.
  3. Подключение к чату маячковых устройств, через внешний API (Bot).

Как мы это делали

К счастью, весь код, который мы пишем — Open-Source, поэтому я сразу могу дать ссылку на его реализацию — Реализация Bot и Реализация Telegram Client на Kotlin.

Bot — основы

По реализации Bot существует достаточно много документации и примеров, но все же хочется пройтись и рассказать про некоторые подводные камни. Для начала, мы писали серверную часть на Java и выбрали библиотеку org.telegram:telegrambots. Так как наш сервер — это обычный SpringBoot, то инициализация крайне простая:

Основная особенность передачи location, что его надо часто обновлять, и боту необходимо редактировать уже отправленные сообщения. Если бы не было такой возможности, то Bot бы просто заспамил чат и это, конечно, был бы Epic Fail. Слава богу, Telegram предоставляет права боту редактировать сообщения на протяжении 24 часов (минимум, возможно и дольше).

Передать сообщение можно многими способами. Есть тип Plain Text, Venue, Location, Game, Contact, Invoice и т.д. Казалось, что для нашей задачи отлично подходит Location, но вскрылась неприятная особенность. Location можно передать только с одного устройства для одного аккаунта или бота одновременно! Представьте у вас 2 телефона и с двух телефонов вы отправили свой Location в один чат. Так вот, на сервере случится ошибка и первый Location Sharing просто остановится. Казалось бы, это явно неральный случай, но представьте, у вас много китайских маячков, которые умеют отправлять Location по заданному URL, но они не умеют отправлять прямо в Telegram. Вы пишите Bot, который забирает с сервера и пушит в телеграм. Вот тут и вылазит, то что Bot не сможет отправить больше одного сообщения маячка с типом Location. Получается, это отлично подходит для единоразовой отправки, но не подходит для Live Location.

Решение простое — отправлять текстовые сообщения, а клиент будет парсить текст и показывать локации на карте. К сожалению в стандартном клиенте Telegram будут видны только текстовые сообщения, но там можно вставить ссылку, чтобы открыть карту.

Bot — Подводные камни

К сожалению, Bot пришлось переписывать аж 2.5 раза. Основная проблема — неправильный дизайн коммуникации.

  1. Почему-то вначале казалось хорошей идеей, если бот будет полноценным участником чата и отправлять сообщения. Но, это плохо и с точки зрения Privacy переписки и с точки зрения взаимодействия с ботом. Правильное решение, использовать Inline bots. Таким образом, гарантируется, что бот не видит ничего кроме своего Location и его можно использовать в любом чате. По-человечески говоря, некультурно тащить своего бота в какой-то общий чат, а нужно пообщаться с ботом один на один и настроить его, а дальше он сможет отправлять нужные сообщения в любой выбранный чат.
  2. В Telegram Message API есть исторически 2 типа взаимодействия: кнопки под текстом ( (inline buttons)[https://core.telegram.org/bots/2-0-intro#switch-to-inline-buttons] ) и ответы боту напрямую текстом. В общем, ответы с ботом безнадежно устарели. Кнопки немного сложнее с точки зрения реализации, но это полностью окупается удобством использования и именно их надо использовать для всего нетекстового ввода.
  3. В качестве примера бота можно посмотреть популярный @vote_bot или наш @osmand_bot.
Telegram Client

Найти примеры готовых telegram client, кроме основного, нам не удалось, но достаточно простая структура tdlib помогла нам создать базовый клиент буквально за пару дней.

Практически все внутренности Телеграмма написаны на С++ и с точки зрения Android виден только класс API на 1.5 Мб прокси методов TdApi.java. Путем сопоставления документации ботов и названия методов, можно достаточно просто сориентироваться куда двигаться.

Telegram Client — подводные камни
  1. Регистрация/Login и Logout. При регистрации необходимо учесть разные сценарии: когда код доступа присылается SMS или в другой телеграм клиент, двухфакторную авторизацию и т.п. Самая большая сложность — это тестирование. Любая авторизация более 3-х раз вела к блокировке аккаунта на 24 часа, поэтому тестировать Logout было особенно весело. Несмотря на то, что регистрация нужна всего лишь один раз, наверное это самая сложная часть интеграции.
  2. Определить как и в каком порядке вычитывать сообщения. Любой клиент имеет доступ ко всем сообщениям во всех чатах, но вычитывать их надо последовательно. В нашем случае 99% сообщений нужно отбрасывать. Сначала мы почему-то сделали чтение всех сообщений за последние 3 дня при логине, но в дальнейшем это только вызвало проблемы и при рестарте у нас пропадали сообщения. Поэтому сейчас мы читаем только новые сообщения, а для тех сообщений, что нам нужны сохраняем id во внутренней БД.

Что получилось

Наверное, зная все подводные камни можно было бы все сделать в разы быстрее, но получилось где-то 1-2 месяца на трех человек. Финальное приложение можно найти в Google Play.

Главный вопрос в этой истории, насколько правильно это взаимодействие с точки зрения Телеграма и понравятся ли пользователям такого рода интеграции. В любом случае, сама идея нишевая и отдельных клиентов она уже нашла.

Поделиться:
Нет комментариев

Добавить комментарий

Ваш e-mail не будет опубликован. Все поля обязательны для заполнения.

Этот сайт использует Akismet для борьбы со спамом. Узнайте как обрабатываются ваши данные комментариев.