如何创建和部署 Telegram 机器人
这是引言,您可以跳过。
在本教程中,我们将使用 Python 构建一个非常简单的机器人,并将其部署到 Heroku 服务器上。
接下来的段落中,我将深入探讨机器人究竟是什么,以及为什么创建机器人可能对你来说很有趣。如果你已经了解这些内容,可以直接跳过这部分。
表面上看,Telegram 只是另一款即时通讯应用。这款应用宣称自己安全、快速、无广告等等。然而,它有一个功能确实使其在同类应用中脱颖而出,那就是机器人!
如果你还不熟悉这个概念,并且把它想象成某种脚本化的自动回复“在线聊天”客服,那么很遗憾,你错了。这些机器人是非常棒的小助手,你可以在任何聊天中使用它们。
你可以把机器人想象成一个自动化的用户账号,它可以帮你完成一些小任务。例如,你想在群聊中分享一个 YouTube 链接,但你还没有链接。
如果没有机器人:
- 你在浏览器中打开 YouTube。
- 搜索你想分享的视频
- 选择分享方式…(并希望您的应用已列入 YouTube 分享列表)
- 跳过上述步骤,直接使用传统的复制粘贴方式。
- 返回你的聊天应用,最后分享链接
- 哇哦
当然,我们大多数人已经习惯了上述算法,而且它对我们有效。然而……
使用机器人:
- 您正在使用即时通讯应用进行通讯。
- 输入@vid,后面加上你想查找和分享的视频名称。
- 按下或轻触回车键
上述方法要好得多,更方便用户使用,也更省时。而这仅仅是机器人功能的一个例子。
Telegram做得非常出色,它允许用户创建自己的机器人。至于为什么这会很有趣,我可以说,这是了解API概念最简单的方法。
何不创建你的第一个机器人呢?
首先,你需要注册一个 Telegram 账号(这显而易见)。我建议使用Telegram 网页版来测试一些基本概念。
打开 Telegram 应用,搜索@botfather 并开始聊天。发送/newbot命令并按照提示操作。完成初始步骤后,您将获得——
- 您的代币
- 电报 API URL — https://api.telegram.org/bot
- 文档链接
没错,就是这样。目前这个机器人完全处于被动状态。
您需要与机器人建立对话。打开搜索框,输入机器人的名称。点击“ /start ”按钮开始对话。输入类似“你好”的内容。这条消息很重要,因为它是机器人收到的第一条更新信息。
如果你是第一次接触 API 构建,你可以轻松地通过网页浏览器来了解其原理。在浏览器中打开一个新标签页,然后使用 Telegram API URL -
https://api.telegram.org/bot/token/getUpdates
当你在浏览器中打开这个网址时,你会向 Telegram 服务器发出一个请求,服务器会以 JSON 格式返回响应。响应类似于 Python 字典。你应该会看到类似这样的内容:
{"ok":true,"result":[{"update_id":523349956,
"message":{"message_id":51,"from":{"id":303262877,"first_name":"YourName"},"chat":{"id":303262877,"first_name":"YourName","type":"private"},"date":1486829360,"text":"Hello"}}]}
如果您打开机器人文档并查看 ` /sendMessage`方法部分,您会注意到此方法需要两个额外的参数:`chat_id`和`text`。在浏览器搜索栏中,您可以使用`?`输入第一个参数,` &`输入后续参数。发送消息的命令如下所示:
/sendMessage?chat_id=303262877&text=test
尝试通过将chat_id替换为调用/getUpdates获取的 ID来获取机器人的回复。在我的例子中,chat_id 是 303262877。文本参数由你决定。请求应该如下所示。
https://api.telegram.org/bot<token>/sendMessage?chat_id=303262877&text=Hello
几乎是编码部分
如果你使用的是 Windows 系统且尚未安装 Python,可以从这里获取。
无论你使用的是 Python 2.x 还是 3.x 版本都无所谓,但我会在示例中使用 Python 3.x。
如果你使用的是 Linux/Mac 系统,很可能你已经安装了这两个版本,或者至少安装了 Python 2.x。
下一步是安装 pip。Python 2.7.9 及以上版本,以及 Python 3.4 及以上版本都已包含 pip。
同样,在 macOS/Linux 系统上,您可能也遇到了这个问题。您可以使用终端中的`pip --version`命令进行检查。
如果由于某种原因您没有安装 pip,可以使用以下命令在基于 Debian 的 Linux 系统上安装 pip。
$ sudo apt-get install python-pip.
棘手之处在于,不同版本的 Python 使用各自的 pip。
在 Mac OS 系统上,您可以尝试按照这里的说明操作。
在 Windows 系统中,下载 get-pip.py 文件,打开命令提示符,进入保存该文件的目录,然后运行以下命令——
$ python get-pip.py
这是最难的部分。
接下来,您需要使用 pip 安装 requests 包。使用以下命令:
$ pip install requests
下一步是可选的,但会很有帮助。安装PyCharm,它非常棒。
编码部分
如果 API 的概念很清晰,并且你拥有所有必要的工具,那么让我们编写一个 Python 脚本来检查更新并回复所需的文本。
首先,我们的机器人应该检查更新。我们发送的消息可以视为最新更新。但是,`getUpdates` 函数会返回过去 24 小时内的所有更新。让我们编写一个小脚本来获取最新更新。
import requests
url = "https://api.telegram.org/bot<token>/"
def get_updates_json(request):
response = requests.get(request + 'getUpdates')
return response.json()
def last_update(data):
results = data['result']
total_updates = len(results) - 1
return results[total_updates]
更新字典包含两个元素——“ok”和“results”。我们关注的是“results”部分,它列出了我们的机器人在过去24小时内收到的所有更新。
您可以在这里查看更多关于 requests 库的信息。其最基本的概念是:每当您需要获取、更新或删除服务器上的信息时,您都会发送一个请求并接收一个响应。参数
下一步是添加两个函数。第一个函数会从更新中获取 chat_id,第二个函数会发送一条消息。
def get_chat_id(update):
chat_id = update['message']['chat']['id']
return chat_id
def send_mess(chat, text):
params = {'chat_id': chat, 'text': text}
response = requests.post(url + 'sendMessage', data=params)
return response
chat_id = get_chat_id(last_update(get_updates_json(url)))
send_mess(chat_id, 'Your message goes here')
还记得以前用“?”和“&”连接参数吗?你也可以通过将字典作为第二个可选参数添加到请求的get/post函数中来实现同样的效果。
脚本已经编写完成。但是,它远非完美。其中一个主要缺点是,每次想用机器人发送消息时,都需要运行脚本。让我们来解决这个问题。为了让机器人监听服务器以获取更新,我们需要启动一个主循环。在`import requests`之后另起一行,添加`from time import sleep`。
def main():
update_id = last_update(get_updates_json(url))['update_id']
while True:
if update_id == last_update(get_updates_json(url))['update_id']:
send_mess(get_chat_id(last_update(get_updates_json(url))), 'test')
update_id += 1
sleep(1)
if __name__ == '__main__':
main()
尽管我们添加了 1 秒的“超时”时间,但上述示例仅应用于测试目的,因为它使用的是短轮询。它不适用于 Telegram 服务器,应该避免使用。使用机器人 API 获取更新有两种方法:长轮询或 Webhook。但是,如果我们使用不带任何参数的 `getUpdates` 方法检查更新,则会使用短轮询。
由于我们的脚本开始使用主循环,因此我们需要切换到长轮询。
为了使我们的脚本使用长轮询,我们需要修改第一个函数,添加超时参数。
设置超时本身并不会降低脚本检查更新的频率。超时仅在没有近期更新时才会生效。如果您想表明某个更新已被检测到,则需要添加“offset”参数。
def get_updates_json(request):
params = {'timeout': 100, 'offset': None}
response = requests.get(request + 'getUpdates', data=params)
return response.json()
现在机器人应该可以正常工作了,不过我们还是稍微修改一下代码。最好把目前为止用到的所有函数封装到一个类里。修改后的版本可能看起来像这样——
import requests
import datetime
class BotHandler:
def __init__(self, token):
self.token = token
self.api_url = "https://api.telegram.org/bot{}/".format(token)
def get_updates(self, offset=None, timeout=30):
method = 'getUpdates'
params = {'timeout': timeout, 'offset': offset}
resp = requests.get(self.api_url + method, params)
result_json = resp.json()['result']
return result_json
def send_message(self, chat_id, text):
params = {'chat_id': chat_id, 'text': text}
method = 'sendMessage'
resp = requests.post(self.api_url + method, params)
return resp
def get_last_update(self):
get_result = self.get_updates()
if len(get_result) > 0:
last_update = get_result[-1]
else:
last_update = get_result[len(get_result)]
return last_update
最后一步是声明变量并教这个机器人一些礼仪。我们的想法是创建一个每天向你问好一次的机器人。根据一天中不同的时间,回复的内容也会有所不同。如果你想尝试这个脚本,需要在 `import requests` 之后的下一行添加`import datetime`,并将以下代码添加到你的脚本中。
greet_bot = BotHandler(token)
greetings = ('hello', 'hi', 'greetings', 'sup')
now = datetime.datetime.now()
def main():
new_offset = None
today = now.day
hour = now.hour
while True:
greet_bot.get_updates(new_offset)
last_update = greet_bot.get_last_update()
last_update_id = last_update['update_id']
last_chat_text = last_update['message']['text']
last_chat_id = last_update['message']['chat']['id']
last_chat_name = last_update['message']['chat']['first_name']
if last_chat_text.lower() in greetings and today == now.day and 6 <= hour < 12:
greet_bot.send_message(last_chat_id, 'Good Morning {}'.format(last_chat_name))
today += 1
elif last_chat_text.lower() in greetings and today == now.day and 12 <= hour < 17:
greet_bot.send_message(last_chat_id, 'Good Afternoon {}'.format(last_chat_name))
today += 1
elif last_chat_text.lower() in greetings and today == now.day and 17 <= hour < 23:
greet_bot.send_message(last_chat_id, 'Good Evening {}'.format(last_chat_name))
today += 1
new_offset = last_update_id + 1
if __name__ == '__main__':
try:
main()
except KeyboardInterrupt:
exit()
从这里开始,你可以用成千上万种方式自定义你的机器人。我建议尝试发送媒体文件或添加“自定义”按钮。
进入荒野。部署
让你的机器人真正成为机器人的最后一步是将其部署到服务器上。你很可能没有自己的服务器,也不想购买……而且你完全不必这样做。目前,有很多云解决方案可以免费托管你的应用程序。接下来,我将向你展示如何将这个小脚本部署到 Heroku。
首先,你需要一个GitHub账号。赶紧注册一个吧,如果你对任何类型的编程感兴趣,这都是必不可少的一步。除了GitHub账号,你还需要安装git。
在基于 Debian 的 Linux 系统上运行以下命令——
$ sudo apt-get install git-all
下载 Git:
在这里注册Heroku
使用以下命令安装virtualenv -
$ pip install virtualenv
现在你需要稍微整理一下文件。创建一个新文件夹,打开终端/CMD,然后进入你的新文件夹。
在新文件夹中初始化虚拟环境 - 输入
$ virtualenv my_env
名称其实并不重要,不过最好还是尽量使用具有描述性的名称。
进入 my_env 文件夹。
下一步——克隆你的 Git 仓库。输入以下命令:
$ git clone https://github.com/yourprofilename/yourreponame
将你的脚本放入 git 克隆文件夹中。
返回到 my_env 文件夹,并使用以下命令启动 virtualenv -
视窗:
$ scripts\activate.bat
Linux/macOS:
$ source bin/activate
如果virtualenv已成功激活,则控制台提示符应以 (my_env) 开头。
下一步——进入你克隆的仓库,再次输入命令安装 Python requests 模块——
$ pip install requests
下一步是创建 Heroku 的依赖项列表。很简单,只需输入以下内容即可。
$ pip freeze > requirements.txt
创建一个Procfile 文件。在这个文件中,你需要提供脚本的运行指令。文件名必须完全是Procfile, Windows 系统下文件名应为Procfile.windows。文件不能带有 .txt、.py 或任何其他扩展名。文件内容应如下所示(将 my_bot 替换为你的脚本名称):
web: python my_bot.py
在你的文件夹中添加__init__.py文件。该文件可以为空,但它必须存在。
输入以下命令序列以提交并推送您所做的更改。
$ git init
$ git add .
$ git commit -m ‘short message that describe changes to commit’
$ git push -u https://github.com/yourusername/nameofrepo
下一步是在 Heroku 上进行实际部署。不知何故,我无法使用 Heroku 的网页版控制面板完成部署。不过,使用 Heroku 命令行界面则非常简单。如果您遇到任何问题,我建议您参考这篇指南。
我将仅提供几个步骤,这些步骤足以完成应用程序的部署。如果您使用的是 Mac 或 Windows 系统,可以从这一步下载 CLI 。
如果你和我一样使用的是Ubuntu系统,请使用以下命令——
$ sudo add-apt-repository "deb https://cliassets.heroku.com/branches/stable/apt ./"
$ curl -L https://cli-assets.heroku.com/apt/release.key |
$ sudo apt-key add -
$ sudo apt-get update
$ sudo apt-get install heroku
在我的家用电脑上一切顺利,但在我的第二台笔记本电脑上,我无法立即完成最后一步。如果您遇到同样的问题,请检查终端以获取提示并查找缺失的依赖项。
请按照以下指令操作 -
$ heroku login
$ heroku create
$ git push heroku master
$ heroku ps:scale web=1
$ heroku open
从现在开始,您的应用应该可以在 Heroku 服务器上运行了。如果由于某种原因无法运行,请使用以下命令检查日志——
$ heroku logs --trail
您可以在这里找到错误代码。
免费账户会有一些限制。不过,这里提供的是一个功能齐全的机器人。
本文作者为 Roman Gaponov。这篇关于Telegram 机器人的文章最初发表于 Django Stars 博客。
您还可以访问我们的内容平台Product Tribe,该平台由专业人士为产品开发和增长流程中的参与者创建。
欢迎您随时提问,并分享您想了解的主题!
文章来源:https://dev.to/django_stars/how-to-create-and-deploy-a-telegram-bot-37lj
