- PVSM.RU - https://www.pvsm.ru -
Чем отличается Telegram от других популярных мессенджеров? Он — открытый!
Другие мессенджеры тоже имеют API, но почему-то именно телеграм известен как наиболее открытый из самых популярных?
Начнем с того, что у Telegram действительно полностью открытый клиентский
код [1]. К сожалению, мы не видим комиты каждый день прямо на GitHub, но у нас есть код под открытой лицензией. Архитектура Telegram подразумевает, что и Bot и API имеет практически такие же методы — https://core.telegram.org/methods [2].
На самом деле, Telegram представляет не просто чат-мессенджер, а социальную платформу, доступ к которой открыт для разного рода приложений. Они могут предоставлять дополнительные фишки пользователям, взамен используя готовую сеть пользователей и сервера для доставки сообщений. Звучит настолько привлекательно, что нам захотелось попробовать написать своего "клиента" для Телеграм.
В основном мы занимаемся картами и навигацией, поэтому мы сразу смотрели что-нибудь связанные с геолокацией. Мне очень понравилось, что в Telegram, раньше всех остальных приложений, появился удобный способ делится местоположением в реальном времени (https://telegram.org/blog/live-locations [3]) и я достаточно часто этим пользуюсь: помочь сориентироваться другу, показать дорогу и самое главное ответить на главный вопрос "Когда ты будешь?". В принципе, этого хватает большинству людей, но как всегда есть сценарии, когда простых возможностей не хватает. Например, это может быть группа более 10 человек, с разными устройствами (некоторые устройства возможно не являются телефонами) и разными людьми. Этим людям было бы удобно обмениваться сообщениями в группе, а также видеть перемещения друг друга на карте.
Во главу угла мы поставили задачу создать дополнительную ценность для Telegram, а не пытаться использовать его не по назначению. Мы не хотели, чтобы люди у которых нет специального клиента Телеграм, видели в чате месиво сообщений или что-то невразумительное. У людей с "улучшенным" клиентом, появляются же дополнительные возможности, например:
К счастью, весь код, который мы пишем — Open-Source, поэтому я сразу могу дать ссылку на его реализацию — Реализация Bot [4] и Реализация Telegram Client на Kotlin [5].
По реализации Bot существует достаточно много документации и примеров, но все же хочется пройтись и рассказать про некоторые подводные камни. Для начала, мы писали серверную часть
на Java и выбрали библиотеку org.telegram:telegrambots. Так как наш сервер — это обычный SpringBoot, то инициализация крайне простая:
// Gradle implementation "org.telegram:telegrambots:3.6"
TelegramBotsApi telegramBotsApi = new TelegramBotsApi();
telegramBotsApi.registerBot(new TelegramLongPollingBot() {...});
Основная особенность передачи 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 пришлось переписывать аж 2.5 раза. Основная проблема — неправильный дизайн коммуникации.
Найти примеры готовых telegram client, кроме основного, нам не удалось, но достаточно простая структура tdlib помогла нам создать базовый клиент буквально за пару дней.
task downloadTdLibzip {
doLast {
ant.get(src: 'https://core.telegram.org/tdlib/tdlib.zip', dest: 'tdlib.zip', skipexisting: 'true')
ant.unzip(src: 'tdlib.zip', dest: 'tdlib/')
}
}
task copyNativeLibs(type: Copy) {
dependsOn downloadTdLibzip
from "tdlib/libtd/src/main/libs"
into "libs"
}
task copyJavaSources(type: Copy) {
dependsOn downloadTdLibzip
from "tdlib/libtd/src/main/java/org/drinkless/td"
into "src/org/drinkless/td"
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
}
Практически все внутренности Телеграмма написаны на С++ и с точки зрения Android виден только класс API на 1.5 Мб прокси методов TdApi.java [8]. Путем сопоставления документации ботов и названия методов, можно достаточно просто сориентироваться куда двигаться.
fun init(): Boolean {
return if (libraryLoaded) {
// create client
client = Client.create(UpdatesHandler(), null, null)
true
} else {
false
}
}
private fun requestUserPhoto(user: TdApi.User) {
val remotePhoto = user.profilePhoto?.small?.remote
if (remotePhoto != null && remotePhoto.id.isNotEmpty()) {
downloadUserFilesMap[remotePhoto.id] = user
client!!.send(TdApi.GetRemoteFile(remotePhoto.id, null)) { obj ->
when (obj.constructor) {
TdApi.Error.CONSTRUCTOR -> {
val error = obj as TdApi.Error
val code = error.code
if (code != IGNORED_ERROR_CODE) {
listener?.onTelegramError(code, error.message)
}
}
TdApi.File.CONSTRUCTOR -> {
val file = obj as TdApi.File
client!!.send(TdApi.DownloadFile(file.id, 10), defaultHandler)
}
else -> listener?.onTelegramError(-1, "Receive wrong response from TDLib: $obj")
}
}
}
}
Наверное, зная все подводные камни можно было бы все сделать в разы быстрее, но получилось где-то 1-2 месяца на трех человек. Финальное приложение можно найти в Google Play [9].
Главный вопрос в этой истории, насколько правильно это взаимодействие с точки зрения Телеграма и понравятся ли пользователям такого рода интеграции. В любом случае, сама идея нишевая и отдельных клиентов она уже нашла.
Буду рад ответить на ваши вопросы.
Автор: Victor Shcherb
Источник [10]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/android-development/294392
Ссылки в тексте:
[1] код: https://github.com/TelegramOrg
[2] https://core.telegram.org/methods: https://core.telegram.org/methods
[3] https://telegram.org/blog/live-locations: https://telegram.org/blog/live-locations
[4] Реализация Bot: https://github.com/osmandapp/OsmAnd-tools/blob/master/java-tools/OsmAndServer/src/main/java/net/osmand/server/assist/OsmAndAssistantBot.java
[5] Реализация Telegram Client на Kotlin: https://github.com/osmandapp/Osmand/tree/master/OsmAnd-telegram
[6] Inline bots: https://core.telegram.org/bots/inline
[7] https://core.telegram.org/bots/2-0-intro#switch-to-inline-buttons: https://core.telegram.org/bots/2-0-intro#switch-to-inline-buttons
[8] TdApi.java: https://raw.githubusercontent.com/ihorvitruk/Telegram-Client/master/libtd/src/main/java/org/drinkless/td/libcore/telegram/TdApi.java
[9] Google Play: https://play.google.com/store/apps/details?id=net.osmand.telegram
[10] Источник: https://habr.com/post/424245/?utm_source=habrahabr&utm_medium=rss&utm_campaign=424245
Нажмите здесь для печати.