xml地图|网站地图|网站标签 [设为首页] [加入收藏]

开发一个Telegram,年轻人的第一个telegram机器人

必威 1

摘 要:着眼于主流 IM 软件中的聊天机器人、微信小程序和系统级的语音助手,介绍 Telegram、Skype、Messenger、Kik、Slack 中的 Chatbot ,微信小程序和智能个人助理 Contana、Siri、Google Assistant ,通过不同角度的对比分析,窥见App演变的方向。目 的:总结2016年阅读各种书籍和文章,把玩各种 App 和不同操作系统,综合产生的一些想法。

声明:本文是篇翻译文,翻译原文。翻译不是很好,如有阅读不顺畅的地方,请阅读原文。

1. Telegram

在介绍Telegram Bot之前先认识一下Telegram这个聊天工具.

先来一个直观的感受, 看一下这个Telegram长什么样

必威 2

Telegram

相信很多同学都应该听说过或者用过这个软件, 这个软件简单的说就是一个简版的微信, 但是和微信不同的是这个软件的安全性更加的高, 这里所说的安全性是指你聊天的内容不容易泄露. 当然, 你知道的, 在一个聊天比较安全的环境下就会有一些比较"劲爆"的内容. 这些就不展开讨论了, 有兴趣的同学自行去发现吧. 最近这个软件比较火热, 我觉得有一部分原因是国内的小密圈被封了, 所以很多业界的网红程序员都开了telegram, 比如池建强, 冯大辉等等. 这里有两篇关于Telegram更加详细的介绍, 有兴趣的可以看一下

Telegram,隐秘通道(池建强)&version=12020810&nettype=WIFI&fontScale=100&pass_ticket=DcfDLqEGG5dyi/PQXlfwsGRjhxV46MJdxi0JmVQbbyeX7lGnExzNNry8/xmsW5Gf)
Telegram传奇:俄罗斯富豪、黑客高手、极权和阴谋…(霍炬)&version=12020810&nettype=WIFI&fontScale=100&pass_ticket=DcfDLqEGG5dyi/PQXlfwsGRjhxV46MJdxi0JmVQbbyeX7lGnExzNNry8/xmsW5Gf)

所谓的生命线

也就是上周,生命线第三部,静夜在App Store上发布,这一部剧情是承接第一部的,主角还是初代产品中的那个话唠泰勒,也就是说自从倒霉的泰勒在遥远的外太空遭遇了飞船事故在你的帮助下获救后,这次又遇上麻烦啦,可爱的泰勒再次呼叫您的帮助,没错,又要去陪他“聊天”了!

必威 3

整个游戏的故事情节是波荡起伏扣人心弦的,当然啦,18块的价格就看你愿不愿意接受啦。不过幸运的是,现在你可以免费在telegram上体验原版的生命线啦!

必威 4

这里顺带安利一下telegram,这是个什么鬼,战斗名族开发的暴强跨平台的实时通讯App,专为聊天而生,开放源代码,非营利无商业利益驱动,端对端加密。总之,还是那句话说得好,每一个被GFW认证的产品,都是好产品。。

只要在telegram上搜索@LifelineSilentNightBot并添加就可以跟泰勒对话了。支持六国语言,泰勒也会说日语。

必威 5

如果你仅仅是想在telegram上玩生命线,看到这里就可以了;如果你也想做一个的话,那么下面则是教你如何在telegram上做自己的生命线游戏。

关键词:Chatbot ; 微信小程序;智能个人助理

介绍

telegram.ext子模块是通过纯API的基础上实现的。它提供了简单的交互,并让程序员从一些工作中解脱出来,让你不必重复你自己(黑人问号??)
它包含了多个类,但是有两个最重要的是telegram.ext.Updatertelegram.bot.Dospatcher
Updater类持续从telegram接收新信息,以及转发给Dispatcher类。如果你创建了一个Updater目标,它将创建一个Dispatcher给你,并且通过一个Queue连接起来。你可以通过注册一个通过Dispatcher注册不同类型的handlers,Dispatcher将会使用注册过的handlers,对从Updater接收的信息进行分类,以及分发给你定义的不同的响应程序(callback function)。
每个handler都是通过telegram.ext.Handler类创建的实例。这个包提供几乎所有会用到的事件提供handler,但是如果你需要一些非常特殊的东西,你可以自己定义议程Handler
开始,你需要一个Token。如果你已经阅读了第一篇文章,你可以使用之前生成的token。要生成一个token,你必须和@BotFather交互,并且跟从一些简单步骤。

2. 开发Telegram Bot之前的准备工作

介绍完Telegram之后, Telegram Bot是干嘛的大家看名字就清楚了, 其实就是一个程序, Telegram会将用户发送的信息发送到你配置的一个webhook url上, 这样程序就可以根据用户发送的信息做出响应, 就是这么简单.

Telegram官方或者第三方已经有一些Bot可以使用了, 但是作为有强迫症什么都要亲自做一遍的程序员来说, 自己写一个Bot是肯定的了.

首先, 要写一个能使用的Bot以下的东西是必须要有的

  • Bot Token
    这个简单, 这个Token可以直接到BotFather(后面会介绍)申请

  • 一个Bot程序
    这个是肯定要有的, 这个程序就是对用户消息做出响应的程序. 这个也简单, 直接写一个可以接受Http请求的web程序就可以了(我们每天都在做的事情)

  • 支持https的公网地址
    你写的程序肯定是要放到公网上Telegram才能将消息发到你的程序, 而且Telegram要求这个公网地址必须是Https的. 这个要求就有点高了, 难不成为了写了一个Bot还得搞一台云服务器, 买个Https的证书吗? 如果这个Bot是商用或者要推广的这个是必须要的, 但是我的Bot只是为了满足我的强迫症啊!! 所以是时候祭出这个大杀器了 --- ngrok. 这个工具可以将你本地的地址映射成公网的一个地址, 而且它还支持Https. 一起来看一下这个杀器

    必威 6

    ngrok

这样就把一个公网网址映射到你本地的程序了, 所以只要同时启动你的程序和ngrok, Telegram就可以将消息发送到你本地的程序了. 嗯, 简直完美!

本该是件有趣的事情

在telegram上玩生命线本是件有趣的事情,可是要自己写代码就显得没那么有趣了。那句话叫什么来着:

我有好多想法,就差一个程序员了。

好吧,当我什么也没说。

下面就简单废话一下,不细讲,整个流程是这样的。

打开生命线ipa文件,你会看到很多东西,你会一眼发现,有个名为StoryData_xx.txt的文本文件,打开一看你就知道,你要找的都在这里了:

必威 7

没错,这就是整个游戏的剧本,上图是中文的。剧本整体写得不错,结构格式十分清晰明了,接下来只要自己简单写个程序解释这个脚本就可以了。值得一提的是,人家还提供了处理后的categories_xx.jsonwaypoints_xx.json文件,所以我用的是这两个,json格式比较好用,而不是剧本文件本身。

程序一开始当然不是在telegram上跑,于是乎,产生了一个副产品,终端版的生命线。。我知道,有人更喜欢玩这种。。

必威 8

思路已经阐明了,那代码就不讲了。

必威 9

于是乎,用上图第212行注释掉的随机数跑了N遍,没啥问题,就是结局每次都以失败告终,人品差没办法。

然后就是移植到telegram上去了,至于telegram bot是个什么鬼,下个应用用了就知道了,然后就是telegram bot API,哪怕被墙了,也还是要看的,当然,用不用就是另一回事了。嗯,这里我用的是python-telegram-bot这个包。

然后就是把上述的终端版改改改,其实也不用改太多。至于服务器呢,我没有vps,于是就放到了Cloud9上面,免费的Ubuntu 1CPU 512M RAM 1GB HDD也够了。

必威 10

接下来就可以在telegram上愉快的玩耍了。

「本文参与 少数派2016年度征文」

一步一步创建你的第一个机器人

现在,让我们开始吧!再说一次,如果你想跟随教程,请打开一个Python命令行。
第一步,你必须创建一个Updater。将TOKEN替换为你的机器人的token。

>>> from telegram.ext import Updater
>>> updater = Updater(token='TOKEN')

相关阅读文档:telegram.ext.Updarer
为了让你的Updater更快的使用到Dispatcher,你可以在本地输入:

>>> dispatcher = updater.dispatcher

现在是设置logging模块的好时候,这会让你知道什么时候(为什么)程序没有和你预想的一样工作:

>>> import logging
>>> logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', level=logging.INFO)

注意:如果你想学习更多内容,请阅读Exception Handling
现在,你可以定义一个处理特定类型信息的函数:

>>> def start(bot, update):
...      bot.sendMessage(chat_id=update.message.chat_id, text='I'am a bot,please talk to me !')

相关阅读文档:sendMessage
我们的目标就是希望当机器人接收到包含/start命令的telegram信息时,这个函数会被触发!为了完成这个目标,你可以使用一个CommandHandlerHandler类提供的其中一个),并且通过dispatcher注册:

>>> from telegram.ext import CommandHandler
>>> start_handler = CommandHandler('start',start)
>>> dispatcher.add_handler(start_handler)

相关阅读文档: telegram.ext.CommandHandler, telegram.ext.Dispatcher.add_handler
接下来,你所需要做的,就是运行这个机器人,运行:

>>> updater.start_polling()

相关阅读:telegram.ext.Updater.start_polling
尝试一下!和你的机器人聊天,假如没有问题,给你的机器人发送/start命令后,机器人将会回复。

译者发话:每次定义一个函数都需要先定义一个handler,然后通过dispatcher.add_handler注册,这一点都不Pythonic!这里译者将定义一个装饰器,省去重复工作!

# decorater:不用每定义一个函数都要用handler以及add_handler
def command(handler,cmd=None,**kw):
    def decorater(func):
        def wrapper(*args,**kw):
            return func(*args,**kw)
        if cmd==None:
            func_hander=handler(func,**kw)
        else:
            func_hander=handler(cmd,func,**kw)
        dispatcher.add_handler(func_hander)
        return wrapper
    return decorater

这个装饰器就不介绍了。不懂装饰器的可以google之,或者直接用吧!
使用方法:

# 命令:/start ,回复一句话
@command(CommandHandler,'start')
def start(bot, update):
    bot.sendMessage(chat_id=update.message.chat_id, text="I'm a bot, please talk to me!")

其实很简单,就是定义每个callback函数时,先在前面加一个@command(handler,cmd)handler就是像CommandHandler这样的handler。cmd就是给机器人定义的命令,比如/startcmd就是startcmd默认是None值。

但是现在我们的机器人只能回答/start命令。让我们添加另外一个handler,让它接收常规消息并回复同一句话(复读机)吧!使用MessageHandler,这个Handler子类,可以回应所有的文字信息:

>>> @command(MessageHandler,Filters.text)
... def echo(bot,update):
...     print update.message.chat_id
...     #print dir(update.message)
...     bot.sendMessage(chat_id=update.message.chat_id,text=update.message.text)

原文代码:

def echo(bot, update): ... bot.sendMessage(chat_id=update.message.chat_id, text=update.message.text) ... from telegram.ext import MessageHandler, Filters echo_handler = MessageHandler(Filters.text, echo) dispatcher.add_handler(echo_handler)

下面的代码将直接使用装饰器,不再贴原代码!

相关阅读:telegram.ext.MessageHandler
从现在开始,你的机器人将会回复所有的非命令信息!
注意:每次当你向dispatcher添加handlers的时候,他们会立刻生效!
注意:Filters类包含一系列的函数来过滤接收到的文字、图片、状态等信息。其中任何一个返回True的过滤器将会把信息传给MessageHandler。如果你想要使用一个单一参数类型的telegram.Message,你可以使用你自己的过滤函数。
让我们给你的机器人添加一个真正的功能吧。我们希望实现一个/caps命令,它将接受一些信息作为参数,然后返回大写的信息。为了让事情更简单,你将接受到的参数(作为空格间隔的list)传给下面的响应函数:

>>> # 命令:/caps args,接收一段英文,返回大写的同一段英文
... @command(CommandHandler,'caps',pass_args=True)
... def caps(bot,update,args):
...     text_caps=' '.join(args).upper()
...     bot.sendMessage(chat_id=update.message.chat_id,text=text_caps)

注意:观察一下CommandHandler初始化时接受的pass_args=True。如果你想要将命令参数传给回调函数,这个是必须的。所以的handler类都有类似的关键词参数。有一些关键词参数适用于所以的handlers,有一些则只适用于特定的handler类。如果你第一次使用新类型的handler,请查阅文档,看是否对你有用。
Bot API另外一个很酷的特性,就是inline mode。如果你希望给你的机器人添加inline功能,请先和 @BotFather发送/setinline开通inline。使用客户端给你的机器人开通inline将会花费一些时间。使用telegram APP可能会加快速度(或者有时候,你只需要等待一会就开通好了)。
当你的机器人显然太吵的时候,让我们继续inline这个主题。你也许已经知道添加响应函数的过程了,但是还有一些新类型的函数将会用到,所以请注意:

>>> # inline query,不是太懂
... @command(InlineQueryHandler)
... def inline_caps(bot, update):
...      query = update.inline_query.query
...      if not query:
...          return
...      results = list()
...      results.append(
...          InlineQueryResultArticle(
...              id=query.upper(),
...              title='Caps',
...              input_message_content=InputTextMessageContent(query.upper())
...          )
...      )
...      bot.answerInlineQuery(update.inline_query.id, results) 

相关阅读:telegram.ext.InlineQueryHandler, answerInlineQuery

还不错!你的机器人已经可以通过inline mode回应你的命令了!

译者话:其实这个inline mode就跟微信里面差不多,当你跟别人聊天时,写了哈哈但是还没有发送时,微信是不是会自动弹出一个贴切的表情?在telegram中,利用上面的命令,以及给你的机器人开通inline mode之后,跟你的机器人聊天时,@它,就能看到这个

必威 11

QQ截图20170325131757.png

必威 12

QQ截图20170325132014.png


但是具体的,译者还没有具体去研究,可能后续还需继续看一下。

有一些困惑的用户可能会给你的机器人发送它(机器人)不明白的命令,所以这个时候我们可以使用MessageHandler结合command过滤器,来回应那些没有被之前的handlers识别的命令:

>>> # 当收到一个未知命令时,回复一句话 | 必须放在最后
... @command(MessageHandler,Filters.command)
... def unknown(update,bot):
...     bot.sendMessage(chat_id=update.message.chat_id,text="Sorry, I didn't understand that command.")

注意:这个handler必须在最后添加(add_handler)!如果你提前添加,它将会在CommandHandler有机会回应命令之前被触发。一旦信息被掌控(handled),所有之后的handlers都会被忽略。
如果你已经玩了一圈了,可以使用下面的命令停止机器人:

>>> updater.stop()

注意:就像你之前看的一样,Updater在不同的线程运行。在这篇教程里这是很好的,但是如果你在写脚本,你也许希望通过按Ctrl

  • C 或者给机器人发送一条命令来停止机器人。想要实现这种情况,可以使用updater.idle()。它将阻止运行程序知道上面两件事其中一件发生,然后运行updater.stop(),然后继续运行脚本。

3. 正式开发一个Telegram Bot

万事俱备只欠东风, 这个东风就是Bot程序. 所以我开发了一个叫dude的MiscellaneousBot

必威 13

MiscellaneousBot

看这个名字就知道这个Bot可以做很多事情, 但是现在只有一个查询快递物流的功能.

必威 14

express

嗯, 界面是难看了一点, 但是目的是达到了. Telegram Bot接口支持html, 所以这个界面可以改的更加的好看和友好一点.

还结尾一个精彩

看到了这里,我感觉你内心里有种想要在telegram上自己也做一款文字冒险游戏的想法,代码不想写不怕,我已经写好了,你只用写剧本就可以啦。替换对应的文件就可以了,如此简单,是不是该剁手了。

Github地址:

什么,彩蛋?我只想说除了生命线,还有火星救援这么好的故事,只是你确定你能玩的下去吗!

必威 15

无论是泰勒还是马丁,我希望最后都能带他们回家,回到地球。

必威 16

概述

下一步该阅读什么?

学习有关库异常以及最佳实践,请阅读Exception Handling.(下一步翻译)
如果想要学习更多特性,请查阅Extensions – JobQueue!
或者,如果你想通过我们的机器人实例获取灵感,请查看examples folder.

3.1 实现

这个Bot的思路很简单, 这里说一下(至于具体的实现可以直接看代码, 非常简单.):

  1. 首先Bot程序要有一个接口用于Telegram回调(也就是之前说的webhook url), 这个webhook url的后面会再解释一下, 由于我们所处的这个网络环境, 用网上的那个curl或者程序的方式设置webhook url基本都是不行的(一直是请求超时), 所以我用了一个比较trick的方式

  2. 但程序里接收用户的消息之后, 对用户的消息进行校验提取出快递商户名和快递单号, 对于提取方式其实是自定义的, 因为程序会让用户记录一定的格式发送要查询的消息, 我制定的规则是"快递商户名,快递单号". 有了这两个信息就可以查询快递物流信息了. 这里我用的是快递鸟这个免费api, 所以之后要做的就是对接快递鸟提供的api接口了. 这些正是我们每天都在做的事情, 这里就不在赘述了.

  3. 获取到用户的快递信息之后就可以给用户响应了, 我这里是直接将快递信息返回了, 实际在操作的时候应该要对数据进行格式化之后再返回, Telegram Bot api支持markdown, html等格式, 所以灵活度是很高的.

这样,一个Bot的查询快递的完整流程就完成了.

概念界定

4. Miscellaneous

微信小程序是一种不需要下载安装即可使用的应用,它实现了应用「触手可及」的梦想,用户扫一扫或搜一下即可打开应用。也体现了「用完即走」的理念,用户不用关心是否安装太多应用的问题。应用将无处不在,随时可用,但又无需安装卸载。[1]

4.1 BotFather

BotFather的作用就是帮你初始化一个Bot, 只要在Telegram和BotFather发起聊天, 它就会给你提示, 你只要一步一步按要求回答它的问题, 比如输入Bot名字等等, 一个Bot就创建好了

必威 17

BotFather

A chatbot is a program which conducts a conversation via auditory or textual methods. [2]Bots provide you with fun, engaging, and usefulservices,all through chat. Find laughs, watch videos, get makeup tips, see the hottest GIFs, and find out if it’s going to rain tomorrow.[3] 这里谈论的 bot ,一言以蔽之,就是一个功能丰富的聊天机器人助理。

4.2 设置webhook url

网上设置webhook url的方式基本都是使用官方的curl(因为我们之间使用ngrok获取了一个https的域名, 如果是自己搭建的服务, 设置webhook url要更加复杂, 具体看官方文档).

curl -X POST -H "Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW" -F "url=https://你的webhook url" "https://api.telegram.org/bot你的token/setWebhook"

这样执行基本上就是超时

所以在我都快绝望的时候, 看到官网上有这么一段描述:

必威 18

trick

然后我抱着试一试的心理(比较网上没说这样可以做, 在官网上我也没找到可以这样做的例子),
用了这种方法:

https://api.telegram.org/bot你的token/setWebhook?url=https://你的域名

没想到设置成功了. 也因此有了这个dude Bot

智能个人助理(Intelligent Personal Assistant)属于一种行动代理人软件(software agent),其能依据用户输入的内容、位置感测而完成相对应的任务或提供相关服务,同时也具有从网络上查找并提供用户各种信息(像是天气、交通状况、新闻、股市行情、进程或零售价格等)的能力。像是微软的 Cortana, 苹果的 Siri ,Google 的 Google Assistant 。[4]

5. 最后

Telegram在我个人看来体验还是很好的,界面很清爽, 作为实时通讯的软件各个功能也都有了, 还是值得用一用的. 其实对于Telegram来说, bot只是它锦上添花的一部分, 最重要的是它的安全性, 而这个安全性的基石MTProto协议应该是值得研究的(虽然我还没有研究...).
基于我们所处的网络环境, 如果想要用一用Telegram, 你先要找把梯子.
如果要开发Bot, 那就看一看Telegram Bot Api
最后, 我的Bot的源代码

内在关联

Chatbot 和智能个人助理是基于人工智能的可以感知周遭环境并作出行动以达致目标的系统,它们均可以不同程度上预测和感知用户需要的服务;微信小程序则是需要用户扫一扫或搜一下来获取自己需要的服务,与人工智能的关联不大。二者均旨在为用户提供更加便捷的服务,路径不同也折射出中美在人工智能技术发展上的差距。

Chatbot 和微信小程序是依托特定 app 存在的,旨在给优质服务提供一个基于自身的开放平台,降低用户对操作系统服务的依赖;智能个人助理则是操作系统层级的,旨在给优质服务提供一个基于系统的开放平台,将更多的服务集成至系统层面。

微信小程序

「微信 OS」,这大概是微信小程序给予微信新的定位。小程序是中国的互联网公司在产品演变上的一次尝试,当人们正在惊呼小程序巨大的线下引流效果时,人们却忽视了小程序作为物联网的入口的作用。试想未来某天,以微信为节点,基于统一的协议,使用小程序将自己的冰箱、电饭煲、空调等进行连接,设置好各个物件的运行逻辑,即可实现最大可能性的人-机-物互联交互。预计小程序会是一个开放体系,可以通过二维码将不同品牌、规格、功能的器具连接在一起。

你在微信中发送一段文字文字或一句语音:我要回家。电饭煲便开启了煮饭模式,空调开始运行调节温度至你最爱的20摄氏度,冰箱也预备着将三文鱼解冻等待你的归来。又或者,你在一家餐厅用餐,通过小程序点餐,微信支付完成,直接将该点餐小程序和家中的电饭煲小程序建立连接,或许下次回家时或许就已经可以吃到电饭煲做出的同类菜肴了。

这就类似于目前 IFTTT或者 tasker 的功能,建立不同的 app 之间的关联,小程序可以建立以微信为核心的不同物件之间的关联,打破移动 app 和智能硬件之间信息孤岛的问题。

必威 19

这是我对于小程序的解读,它是中国最顶尖的产品经理试图引领互联网潮流的尝试,它是正确的方向吗?不知道。但是,这是中美存在在人工智能方面存在技术沟壑时最好的弯道超车方案,至少,小程序已经领先了半个身位。

这几天也坚持试用了好几个小程序,目前来看使用体验都不算友好,不够成熟,有待完善,但是有些契合场景的小程序也做到了轻量和实用的平衡。药顾问、豆瓣评分、滴滴公交三个小程序十分实用,我也直接在桌面建立了小程序文件,方便快速开启。

必威 20

药顾问

方便用户直接搜索查询常见药物的主治功能、用法用量、注意事项等信息。

必威 21

豆瓣评分

必威,之前看豆瓣电影评分的流程是这样:想看某某电影评分如何→打开手机浏览器→搜索豆瓣电影→进入页面现在直接变成了:桌面→小程序豆瓣评分→进入页面

必威 22

滴滴公交

纯粹的公交查询工具,简单易用。

必威 23

Chatbot

聊天机器人,这是由copy to China到to China copy转变的一种证明。2016年就在国内微信、支付宝等 app 通过对话窗口式的服务号提供服务的时候,国外几乎所有知名的互联网科技公司都利用技术领先优势机智地重新玩起了 Chatbot 这项看似过时的技术。

Provide you with fun, engaging, and useful services,all through chat

规划着使用 Chatbot 来提供各种各样的服务,将所有服务的交互变成一种对话的交互[5],以此突破单纯的 IM 软件服务局限,拓展自身的想象空间。

某种意义上来说,Chatbot 是一种全新的人机交互模式,一种集成程度更高的服务模式。当你通过 Chatbot 获取服务时,你使用的是哪种操作系统便变得不再重要了。这是一场革命!要在 Google 和 Apple 脑袋上开一枪,怪不得 Facebook 、微软等公司如此热衷于 Chatbot 。

必威 24

下面就介绍一下各家特色 Chatbot 和使用体验。

Telegram_bots

Telegram就是从互联网中继聊天系统的斜杠指令中获得的灵感,用户使用斜杠指令来获取投票、游戏、图片、贴图、排名、提醒、搜索等各式服务,你也可以自己开发符合自己需求的功能,并且开放给其它用户使用。它是开放的,任何服务提供商都可以通过特定的 bot 将自己的服务接入 Telegram 之中。在群聊之中加入 bot 也可以增加聊天的趣味性。

@gif

寻找 gif bot ,聊天输入框直接输入@gif have fun,Telegram 会帮助你搜索have fun字段的内容,选择发送就可以了。当然你也可以选择任何你需要的字段,whatever you like 。

必威 25必威 26

@vote

可以用来创建投票,并且分享到任何一个群组中。

必威 27

最近在telegram中做了一个多群组的2016年最佳Android手机的评选活动,结果如下:

Pixel – 112

44%

一加3T – 54

21%

Galaxy note 7 – 33

13%

Galaxy s7 – 15

6%

Xiaomi mix – 6

️ 2%

HTC 10 – 5

️ 2%

Huawei mate9 – 3

️ 1%

Xiaomi note2 – 3

️ 1%

LG v20 – 1

️ 0%

Others – 22

9%

本文由必威发布于编程,转载请注明出处:开发一个Telegram,年轻人的第一个telegram机器人