
Telegram和其他流行的Messenger有什么区别? 他是开放的!
其他Messenger也具有API,但由于某种原因,电报是否被称为最开放,最受欢迎?
首先,Telegram有一个真正的完全开放的客户端
代码 。 不幸的是,我们并不是每天都能直接在GitHub上看到提交,但是我们有一个开放许可下的代码。 Telegram体系结构意味着Bot和API都具有几乎相同的方法-https://core.telegram.org/methods 。
实际上,Telegram不仅是一个聊天通讯程序,而且是一个社交平台,所有类型的应用程序都可以访问该平台。 他们可以向用户提供其他芯片,而不是使用现成的用户和服务器网络来传递消息。 听起来如此诱人,以至于我们想尝试为Telegrams编写“客户端”。
应用程序的本质
我们主要处理地图和导航,因此我们立即查看了与地理位置有关的内容。 我真的很喜欢Telegram,在所有其他应用程序之前,有一种方便的方式可以实时共享您的位置( https://telegram.org/blog/live-locations ),而且我经常使用它:帮助我确定方向,显示自己的路线并最重要的是回答主要问题“你什么时候来?”。 原则上,这对于大多数人来说就足够了,但是像往常一样,在某些情况下,简单的机会是不够的。 例如,它可能是一个由10个人组成的小组,他们使用不同的设备(某些设备可能不是电话)和不同的人。 这些人可以方便地在一个小组中交换消息,以及彼此在地图上移动。
我们专注于为电报创造附加价值的任务,而不是试图将其用于其他目的。 我们不希望没有特殊电报客户端的人在聊天中看到一堆混乱的消息或一些难以理解的消息。 具有“改善的”客户的人还有更多机会,例如:
- 实时发送位置聊天时,更精细的时间管理。
- 在地图上查看联系人的位置。
- 通过外部API(Bot)连接到信标设备的聊天。
我们是怎么做到的
幸运的是,我们编写的所有代码都是开源的,因此我可以立即提供其实现的链接-Bot 实现和Kotlin上的Telegram Client实现 。
Bot-基础
关于Bot的实现,有很多文档和示例,但我仍然想继续讨论一些陷阱。 首先,我们写了服务器端
在Java中选择org.telegram库:telegrambots。 由于我们的服务器是常规的SpringBoot,因此初始化非常简单:
// Gradle implementation "org.telegram:telegrambots:3.6" TelegramBotsApi telegramBotsApi = new TelegramBotsApi(); telegramBotsApi.registerBot(new TelegramLongPollingBot() {...});
位置转移的主要特征是需要经常更新,并且漫游器需要编辑已发送的消息。 如果没有这样的机会,Bot只会向聊天室发送垃圾邮件,当然这将是Epic Fail。 谢天谢地,Telegram赋予该机器人24小时(最少,可能更长)编辑消息的权利。
有多种发送消息的方法。 有纯文本,地点,位置,游戏,联系人,发票等类型。 似乎“位置”非常适合我们的任务,但显示了不愉快的功能。 一次只能将位置信息从一台设备转移到一个帐户或漫游器! 假设您有2部电话,而您通过一次聊天发送了2部电话。 因此,服务器上将发生错误,并且第一个位置共享将停止。 看来这显然是一个神经病,但假设您有很多中文信标可以将Location发送到给定的URL,但不能直接发送给Telegram。 您编写了Bot,该Bot从服务器提取并推送电报。 Bot将无法发送多个具有Location类型的信标消息的地方。 事实证明,这非常适合一次性发送,但不适用于实时定位。
解决方案很简单-发送文本消息,客户端将解析文本并在地图上显示位置。 不幸的是,在标准Telegram客户端中只有文本消息可见,但是您可以在其中插入链接以打开地图。
Bot-陷阱
不幸的是,Bot不得不重写多达2.5次。 主要问题是通讯设计错误。
- 出于某种原因,起初,如果该机器人成为聊天中的正式参与者并发送消息,似乎是个好主意。 但是,这在通信的私密性和与机器人的交互方面都是不利的。 正确的决定,请使用Inline机器人 。 因此,可以确保该漫游器除了其位置以外不会看到其他任何东西,并且可以在任何聊天中使用。 从人类的角度来讲,将您的漫游器拖入某种形式的常规聊天是不合文化的,但是您需要与该漫游器进行一对一的交谈并进行配置,然后他就可以向所有选定的聊天发送必要的消息。
- 历史上,Telegram Message API中有两种交互类型:文本下方的按钮((内联按钮)[ https://core.telegram.org/bots/2-0-intro#switch-to-inline-buttons ]),并直接回答机器人文字。 通常,机器人的答案已经过时了。 从实现的角度来看,按钮要稍微复杂一些,但是按钮的易用性完全可以弥补这一点,因此按钮应用于所有非文本输入。
- 作为机器人的示例,您可以看到流行的@vote_bot或我们的@osmand_bot。
电报客户端
除了主要的电报客户端,我们无法找到现成的电报客户端的示例,但是相当简单的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']) }
Telegram的几乎所有内部组件都是用C ++编写的,从Android的角度来看,在1.5 MB代理方法TdApi.java上仅可见API类。 通过比较自动程序的文档和方法的名称,您可以简单地找出要移动的位置。
使用全局处理程序进行客户初始化: fun init(): Boolean { return if (libraryLoaded) {
用户照片要求: 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") } } } }
电报客户端-陷阱
- 注册/登录和注销。 注册时,有必要考虑不同的情况:通过SMS或其他电报客户端发送访问代码时,需要进行两因素授权等。 最大的挑战是测试。 任何超过3次的授权都会导致帐户被封锁24小时,因此测试登出特别有趣。 尽管事实上只需要注册一次,但这可能是集成中最困难的部分。
- 确定如何以及以什么顺序阅读消息。 任何客户端都可以访问所有聊天中的所有消息,但是必须顺序读取它们。 在我们的情况下,需要丢弃99%的消息。 首先,由于某种原因,我们通过登录读取了过去三天的所有消息,但后来仅引起问题,当我们重新启动时,消息消失了。 因此,现在我们只读取新消息,对于所需的消息,我们将ID保存在内部数据库中。
发生什么事了
大概知道了所有陷阱,一个人可以将所有事情做的快很多倍,但事实证明,三个人大约需要1-2个月。 最终的应用程序可以在Google Play上找到。

这个故事中的主要问题是,从电报的角度来看,这种交互的正确性如何,以及用户是否喜欢这种集成。 无论如何,这个想法本身就是利基市场,它已经找到了个人客户。
我很高兴回答您的问题。