Telegram
,请看之前的文章: 谈谈Telegram&食用教程。本文可能会有部分内容翻译自 Telegram 官方网站,翻译可能出现偏差,如果有条件的话,还是看原版的英文文档比较好。什么是 Bot(机器人)
机器人是一种特殊的不额外需要手机号码的账号。用户可以通过给机器人发消息来进行交互。从 2015年6月24日 以后,Telegram
正式开始提供开放的 机器人平台。实际上在这之前,Telegram 上已经有大量的 Bots
存在,只不过它们多数是使用 telegram-cli 实现的。但是这些机器人不能够与 Telegram 客户端的UI交互,不能够弹出可选项之类,而且也不能设置是否允许加入群组、是否能够查看所有消息等。而机器人平台具有一些特殊的API接口,比如说能够自定义用户可见的选项、可以在Telegram客户端中添加一个命令菜单等等。更重要的是,机器人API采用的是简单的 http(s) 协议,而不需要像以前那样自己实现一套 MTProto。
Bot和普通用户有何不同呢?
- Bot没有在线状态,也没有没有上次在线时间,界面上只显示标签'bot'。
- Bot的存储空间是有限的, 服务器处理完毕后,服务器可能会删除较旧的消息。
- Bot无法与用户进行对话。用户必须将它们添加到组中或首先向它们发送消息。我们可以使用telegram.me/
链接或用户名搜索来查找Bot。 - Bot用户名总是以'bot'结尾(例如@TriviaBot,@ GitHub_bot)。
- 把Bot加到群里的时候,默认情况下(开启隐私模式),Bot是不会收到所有的消息的;
- Bot从不吃饭,睡觉或抱怨(除非另有明确规定)。
如何拥有一个自己的Bot
很简单,跟 @BotFather 进行对话,他会引导你创建一个机器人的。
这里我创建了一个叫做 Spiribot 的Bot,链接为 t.me/Spiriibot ,API TOKEN为XXXX:XXXXXX(我肯定不会告诉你啦哈哈哈哈哈哈哈哈
搭建开发环境
首先是官方文档:Telegram Bots API,官方文档其实已经非常详尽,Telegram Bot 的一切动作都由发送 get/post 请求来完成,也基本没有奇怪的 header 要求,非常简明了。
python 比较方便,能通过 pip/pip3 来安装开发所需要的库,这里我使用了 python-telegram-bot ,当然也可以选择另一个比较优秀的 pyTelegramBotAPI 。如果你还没有 pip/pip3 ,请参考 Installation 。
准备venv & python-telegram-bot
Virtual Environment/虚拟环境 是一个包含二进制程序和 shell 脚本的目录。二进制程序包含执行脚本的 python 和安装其它模块的 pip。脚本包括激活环境的脚本,bash,csh 和fish 各有一个。这个虚拟环境模拟了一个完整的 Python 执行环境和需要的模块,将程序运行的环境与系统其它部分隔离开来。
为什么要使用 virtual environment 呢?唔是这样的,pip 默认会把库安装到系统里对应的 site-packages 里,这样无论你在哪打开 Python,都是可以用这个库的。这样听起来好像挺好,但实际上还是有一些弊端的。比如说,在一些项目中,我们最后需要整理出来一个这个项目使用了哪些第三方库,然后指引用户去安装这些库。一个两个还好,多了的话,恐怕开发者也容易找不全、漏掉一些库吧。再加上一些库的依赖、版本等问题,会让我们的开发环境和项目造成很多不必要的麻烦,管理也相当混乱。所以如果有必要,那么一定要使用 Virtual Environment/虚拟环境 的。
命令行方式
如果是 python3 就使用 pip3 ,否则使用 pip/pip2 .
pip install virtualenv
之后我们创建一个目录,使之成为工程目录:
mkdir mybot
cd mybot
#创建virtualenv
virtualenv venv
#激活virtualenv
source venv/bin/activate
此时命令行前面会变成 (venv),代表着已经进入了。这个时候再运行 pip 就会安装到虚拟环境中
pip install python-telegram-bot
IDE方式
如果你和我一样使用IDE,那么事情就变得很简单啦,pycharm 里新建 project ,选择 Virtualenv
即可,之后在 File - Settings - Project interpreter - Project Interpreter
右侧直接点击 +
搜索 python-telegram-bot
添加即可
开始编写第一个Bot
.py文件说明
说明:
第一行的 # !/usr/bin/python
用于指定当给文件加 x 权限并执行时 (./main.py) 该使用哪个解释器,用法和 shell 脚本中 #! /bin/bash
是一样的
第二行用于指定编码格式,下面则是注释说明与 doc 。好奇这些是怎么来的吗?实际上是 IDE 自动生成的啦~
可以在 File - Settings - Editor - File and Code Templates
自行修改,更多信息请参考 JetBrains File and code templates
编写tset.py
接下来我们编写一个Echo Bot,它会重复用户的话(其实就是复读机23333
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# author:spirit
# 首先需要引入需要的库
import telegram
import logging
import telegram
from telegram.error import NetworkError, Unauthorized
from time import sleep
# 初始化 update_id
update_id = None
# 定义主函数
def main():
global update_id
## 创建Bot类的对象,下方填入自己的TOKEN
bot = telegram.Bot('XXXXXXXX:XXXXXXXXXXXXX')
# 获取第一个挂起的update_id,这样我们可以跳过它以防万一
# 得到一个 "Unauthorized" 异常.
try:
update_id = bot.get_updates()[0].update_id
except IndexError:
update_id = None
# 记录日志
logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
# 主函数功能
while True:
try:
echo(bot)
except NetworkError:
sleep(1)
except Unauthorized:
# 用户已屏蔽或取消了与机器人对话时
update_id += 1
# 定义复读机(雾
def echo(bot):
global update_id
# 在最后一个update_id之后请求更新
for update in bot.get_updates(offset=update_id, timeout=10):
update_id = update.update_id + 1
if update.message: # 如果Bot收到消息
# 回复同样的消息给用户
update.message.reply_text(update.message.text)
# 定义程序的入口
if __name__ == '__main__':
main()
运行与调试
Webhook与Long Polling
目前 Telegram 支持两种取得更新的方法,分别为
- 设定Webhook
- 在有人发送消息给你的bot (或加入群组、点击按键等) 时, Telegram 将会使用 JSON 格式 POST 到你的服务器
- 需使用 setWebhook 预先设定
- 可用 getWebhookInfo 自行debug
- 可参考官方 完整教学 (英文)
- 每次主动询问
- 以 getUpdates 请求,将会回传一个 JSON 阵列
- 也可用Long polling取得,详见 WiKi
Long Polling是指程序间隔一定时间通过过getUpdates 取得讯息,缺点是浪费资源,不够即时,所以适合在程序还没有发布,在开发和测试阶段时使用。
Webhook是指向Telegram设定一组callback url,只要当使用者发送消息给Bot,Telegram就会把消息连同metada透过url传给web server。适合在程序已经发布,有固定url的生产环境使用。
ps:我个人是极其建议使用Webhook的方式的,不过由于Webhook的配置使用略微复杂,且我们的 Echo Bot 比较简单,故没有使用Webhook的方式传送信息
开始运行
由于 Webhook 活动时不能使用 getUpdates 方式发送信息,所以我们需要删除 Webhook 集成,访问 https://api.telegram.org/bot'token'/deleteWebhook 将 'token'
替换为申请的TOKEN。如果浏览器返回 True
就说明删除成功。
在 Terminal 执行 pip freeze > requirements.txt
导出所需依赖
将 test.py
和requirements.txt
传到服务器上,如果你对如何上传没有头绪,请安装 lrzsz
服务器执行 pip install -r requirements.txt
安装对应的依赖,直接执行我们的代码
python test.py
这时返回客户端,找到刚申请的Bot : t.me/Spiriibot ,进行调戏对话,如果不出意外的话,你会收获一台可爱的复读机(捂脸
当然如果你觉得不过瘾的话可以再进一步改进它,让它化身人工智障人工智能
tset.py
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# author:spirit
import sys
reload(sys) # Python2初始化后会删除 sys.setdefaultencoding 这个方法,我们需要重新载入
sys.setdefaultencoding('utf-8')
import logging
import telegram
from telegram.error import NetworkError, Unauthorized
from time import sleep
update_id = None
def main():
global update_id
bot = telegram.Bot('XXXXXXXX:XXXXXXXXXXXXX')
try:
update_id = bot.get_updates()[0].update_id
except IndexError:
update_id = None
logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
while True:
try:
echo(bot)
except NetworkError:
sleep(1)
except Unauthorized:
update_id += 1
def echo(bot):
global update_id
for update in bot.get_updates(offset=update_id, timeout=10):
update_id = update.update_id + 1
if update.message:
if update.message.text.find("你好"):
update.message.reply_text(
update.message.text.replace("你", "我").replace("吗", "").replace("?", "!").replace("?", "!"))
else:
update.message.reply_text("你好!")
if __name__ == '__main__':
main()
后记
编写这个 Bot 的过程让我学到了很多东西,尤其是 python 的相关知识,由于初学,一些东西难免出错,欢迎在下方评论区指正
在之后的文章中我会继续完善 Bot ,主要为以下:
- Bot 响应 '/' 菜单
- Bot 添加正在输入标签
- Bot 使用表情包
- Bot 添加选单
- Bot 结合数据库
- Bot 部署在GAE
- Bot 结合WordPress
- ...
暂时只想到那么多,以后再慢慢增加吧 ^_^
Comments | 2 条评论
博主 墨忆
该评论为私密评论
博主 someone
「你似乎正在查看一篇很久远的文章。为了你这样的访客,我特地保留了我的历史博文。不要笑话过去的我,用温柔的目光看下去吧。」
天,太贴心了,谢谢你!