写在前面
鸣谢:感谢@brownsnow、@於黾、@7*24 工作者在发布关于本文的问题时的耐心解答,感谢@怪量小龙人提供的创作灵感。
Python提供了许多的第三方模块,requests是适用于python的url请求模块。
Potato是一款免费的社交聊天软件,除了拥有一般的社交软件所有的功能,Potato还提供了可扩展的机器人开发端口,适用于所有阶段的开发者使用。Potato内置的机器人API名为Bot API,我们将使用这个API进行开发。
在本文章中,我们将结合使用Python的requests包与Bot API开发一个自动的关键字聊天机器人。
文章较长,请耐心阅读!
Potato
下载Potato Chat
首先,请先下载Potato的客户端,Potato官网:https://www.potato.im/
为了解决官网连接超时的问题,你可以根据你的需要点击下方表格中的链接下载当前Potato App官方发布的最新版本(Version:2.37 For All)。(手机端左右滑动查看更多!)
Android | |
Windows | |
iPhone & iPad | |
Mac OS | |
Linux | |
Github全版本托管 |
注意:因为在Potato及其相关网站一般连接较慢,建议进行 翻墙访问!
安装完成后,注册一个Potato账号,我们将进行下一步操作。
注册开发平台
为了使用Bot API,Potato要求我们先要注册其开发平台(也叫商户平台)。
Bot API官网:https://www.potato.im/api/bot
商户平台注册网址:https://developer.pticc.net/#/
打开你的Potato App,点击右上角的+,扫一扫,扫描商户平台上右侧的二维码。扫描成功后点击App中间的Confirm Login,在商户平台中点击注册,并注册一个账号。相关注册流程请参见其官方帮助文档。
创建开发机器人
现在,请你打开Potato App,点击右上角的“搜索”标志,搜索“@BotFather”,点击机器人BotFather,创建与其的聊天。点开下方的消息输入框,点击“开始”。在机器人发送给你的消息中点击蓝色字体的/newbot,这将创建一个新的机器人,随后请给你的机器人取一个别名,成功后再输入一个用户名。具体操作如下图:
注意:因为Potato机器人是通用的,因此会发生机器人名已被占用的情况,尝试给其他名字重试即可。 每个机器人在创建时都会获得一个 唯一的token 来标志身份。 例如 123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11, 机器人所有的接口调用都 必须带上token , 请妥善保管。所有机器人接口调用必须通过HTTPS,格式此所示: https://api.rct2008.com:8443/<bot_token>/METHOD_NAME。上图创建的机器人已在本文发布时删除!!!
创建成功后,BotFather发送给了我们一条创建成功的消息,其中最为重要的是机器人的token,这将是访问机器人唯一的凭证,请将这个token复制到你的剪切板中,后面我们将用到这个。
现在,我们已经完成了机器人的创建工作,请在Potato App中,点击右上角的“搜索”标志,搜索你刚刚创建的机器人用户名,点击你创建的机器人,创建与其的聊天并点击“开始”。例如我刚刚创建的机器人:
检验机器人是否已经创建成功
为了检验我们的机器人是否已经创建成功,我们将使用Bot API中的getMe接口来查看,这是一种测试机器人token是否有效的简单方法, 不需要参数。 以User对象的形式返回该机器人的基本信息。请在浏览器中访问类似于如下的网站:
https://api.rct2008.com:8443/<bot_token>/getMe
其中的<bot_token>请替换为你创建的机器人的token。下方程序中出现的<bot_token>请均替换为你的机器人token。
如果你看到了类似于如下的消息,那么代表机器人已经创建成功;如果没有看到类似于如下的信息,请重试上述的操作,如果还是不可行,可以在本文下方评论并说明你的问题。
{ "ok": true, "result": { "id": 10100427, "first_name": "ll_bot", "last_name": "", "username": "ll_bot" } }
Python
在执行下面的这些操作时,请确保你已经成功创建了Potato机器人,正确安装并配置了Python。
安装第三方库——requests
在所有的检查完成后,我们来安装requests库。请打开一个终端,并输入如下命令:
pip install requests
在出现successfully等字样时,代表requests库已经安装成功。
如果出现了一些报错问题,请参见我的另一篇文章:Python安装第三方库时的报错处理
熟悉环境与调试
在正式编写程序之前,我们先来熟悉一下Bot API
我们这里需要的两个接口分别是sendTextMessage与getUpdates。
sendTextMessage是Bot API提供的发送消息接口,可以向用户、群组、频道发送消息,请求方式为POST。getUpdates是Bot API提供的获取消息的接口,可以获取用户发送的消息,请求方式为GET。
首先,我们先来熟悉一下getUpdates这个接口。请新建一个.py文件,输入如下命令(手机端左右滑动查看更多!):
import requests
url_getUp = "https://api.rct2008.com:8443/<bot_token>/getUpdates"
res_getUp = requests.get(url=url_getUp)
print('url:', res_getUp.request.url)
print("response:", res_getUp.text)
user_answer = res_getUp.text
print(user_answer)
代码输出类似于:
url: https://api.rct2008.com:8443/<bot_token>/getUpdates
response: {"ok":true,"result":[]}
{"ok":true,"result":[]}
现在请你在App中向你创建的机器人随便发送一些消息,然后再次运行上面的程序。代码输出类似于(手机端左右滑动查看更多!):
url: https://api.rct2008.com:8443/<bot_token>/getUpdates
response: {"ok":true,"result":[{"update_id":76,"message":{"message_id":127,"chat":{"id":76166858,"type":1},"from":{"id":76166858,"first_name":"Mike","last_name":"Qin","username":""},"text":"Hello World!","date":1675924704},"lang":"zh-CN","os_type":"android"}]}
{"ok":true,"result":[{"update_id":76,"message":{"message_id":127,"chat":{"id":76166858,"type":1},"from":{"id":76166858,"first_name":"Mike","last_name":"Qin","username":""},"text":"Hello World!","date":1675924704},"lang":"zh-CN","os_type":"android"}]}
从response中可以看出,输出的信息是json字符串格式,里面最为重要的是chat中的id和type以及text。
chat_id是发送消息用户的ID。chat_type是用户类型,1代表用户私聊会话,2代表普通群聊会话,3表示超级群(或者说是频道)会话,这个数字很重要,因为这个值将辅助告诉机器人当前的聊天类型。chat_text是用户发送的消息。
然后,我们来熟悉sendTextMessage这个接口。
请再创建一个.py文件,并输入如下命令(手机端左右滑动查看更多!):
import requests
url_send = "https://api.rct2008.com:8443/<bot_token>/sendTextMessage"
data = {"chat_type": 1, "chat_id": [your id], "text": "你好!我是test机器人."}
res = requests.post(url=url_send, json=data)
print("发送的body:", res.request.body)
print("response返回结果:", res.text)
其中的<bot_token>与[your id]请根据你的情况自行填入,[your id]就是上面输出的response中的chat_id,稍后将介绍如何自动获取这些信息。
运行此程序,就能看到你创建的机器人在和你说:你好!我是test机器人.
至此,你应该已经充分熟悉了两个接口的相关操作,接下来我们来具体分析response中返回的内容。
一般情况下,response返回内容结构如下所示:
我们需要让程序自动提取response中的chat_id与chat_type(已在上面的结构图中标红),那么如何提取呢?
第一种方式:直接使用split()函数对字符串进行分割,例如:
str = '{"ok":true,"result":[{"update_id":40,"message":{"message_id":62,"chat":{"id":76166858,"type":1},"from":{"id":76166858,"first_name":"Mike","last_name":"Qin","username":""},"text":"你好","date":1675146092},"lang":"zh-CN","os_type":"android"}]}'
chat_id = str.split("chat")[1].split(',')[0].split(':')[2]
print(chat_id)
运行这个代码,将直接打印出str中的chat_id。
第二种方式:通过json的loads方法把字符串转换成json对象,并调用dict的方法,获取对应的数据,例如:
import json
str = '{"ok":true,"result":[{"update_id":40,"message":{"message_id":62,"chat":{"id":76166858,"type":1},"from":{"id":76166858,"first_name":"Mike","last_name":"Qin","username":""},"text":"你好","date":1675146092},"lang":"zh-CN","os_type":"android"}]}'
data=json.loads(str)
chat_id = data.get('result')[0].get('message').get('chat').get('id')
print(chat_id)
运行这个代码,也将直接打印出str中的chat_id。
综上两个获取方式,我更推荐第二个方式,因为看上去一目了然。
编写程序
创建一个.py文件,我们将开始编写程序。
首先,导入必要的第三方库,定义url以及创建主程序(手机端左右滑动查看更多!):
import requests, time, json
run = True
# url_send为发送消息的请求url,url_getUp为获取请求url
url_send = "https://api.rct2008.com:8443/<bot_token>/sendTextMessage"
url_getUp = "https://api.rct2008.com:8443/<bot_token>/getUpdates"
# 主程序
while run:
--skip--
一开始,我们导入了request用于发送与接收url的信息。time是Python内置的一个库,我们将用这个库来控制发送频率以防止端口崩溃。json也是Python内置的一个库,用于处理以json格式的信息,因为Bot API所有的返回与发送的文本格式均为json格式,json库可以大大地提高运行效率。
在代码的第六行与第七行,我们定义了两个url值,分别用于接收与发送消息。
接下来,我们来编写主程序,代码如下(手机端左右滑动查看更多!):
# 主程序
while run:
try:
res_getUp = requests.get(url=url_getUp)
print('url:', res_getUp.request.url)
print("response:", res_getUp.text)
user_answer = res_getUp.text
# 实时抓取发信息的用户ID和聊天type信息
try:
chat_id = user_answer.split(",")[3].split(":")[2]
data = json.loads(user_answer)
chat_type = data.get('result')[0].get('message').get('chat').get('type')
except:
pass
# check_text是可定义的关键字
check_text = "你好"
check_text_2 = '再见'
if check_text in user_answer:
data = {"chat_type": int(chat_type), "chat_id": int(chat_id), "text": "你好!我是test机器人"}
res = requests.post(url=url_send, json=data)
print("发送的body:", res.request.body)
print("response返回结果:", res.text)
elif check_text_2 in user_answer:
data = {"chat_type": int(chat_type), "chat_id": int(chat_id), "text": "下次见!"}
res = requests.post(url=url_send, json=data)
print("发送的body:", res.request.body)
print("response返回结果:", res.text)
# 暂缓循环,防止端口崩溃
time.sleep(1.5)
except KeyboardInterrupt:
run = False
如代码所示,我们写了一个try-except,用于处理因程序停止运行而导致的报错问题。
我们首先向接收url发送请求,当用户发送消息时,将返回消息的ID。
接下来抓取消息ID中的用户ID与Type消息,并分别储存在两个变量中,因为用户不可能会时时刻刻发送消息,因此这里也运用了一个try-except。
接下去,我们定义了两个关键字,你可以根据你的需要添加关键字。
其次,有两个if-elif判断语句,用于判断用户输入的消息是否出现在了关键字中,如果有,则向用户发送规定的消息。
完整代码
import requests, time, json
run = True
# url_send为发送请求url,url_getUp为接受请求url
url_send = "https://api.rct2008.com:8443/<bot_token>/sendTextMessage"
url_getUp = "https://api.rct2008.com:8443/<bot_token>/getUpdates"
# 主程序
while run:
try:
res_getUp = requests.get(url=url_getUp)
print('url:', res_getUp.request.url)
print("response:", res_getUp.text)
user_answer = res_getUp.text
# 实时抓取发信息的用户ID和聊天type信息
try:
chat_id = user_answer.split(",")[3].split(":")[2]
data = json.loads(user_answer)
chat_type = data.get('result')[0].get('message').get('chat').get('type')
except:
pass
# check_text是可定义的关键字
check_text = "你好"
check_text_2 = '再见'
if check_text in user_answer:
data = {"chat_type": int(chat_type), "chat_id": int(chat_id), "text": "你好!我是test机器人。"}
res = requests.post(url=url_send, json=data)
print("发送的body:", res.request.body)
print("response返回结果:", res.text)
elif check_text_2 in user_answer:
data = {"chat_type": int(chat_type), "chat_id": int(chat_id), "text": "下次见!"}
res = requests.post(url=url_send, json=data)
print("发送的body:", res.request.body)
print("response返回结果:", res.text)
# 暂缓循环,防止端口崩溃
time.sleep(1.5)
except KeyboardInterrupt:
run = False
注意:其中的<bot_token>请根据你的情况自行填入!
最后
本文至此,相信你已经学会了这项操作(也可能没有,但是相信一定能帮助到你!),最后的代码你可以在此基础上继续开发,你可以尝试解决如下问题,我也有可能会出续篇(剧透):
代码中的关键字定义具有局限性,可以想想怎么样在简洁的情况下定义这些关键字,并缩减判断的语句,使代码运行更高效。
向用户发送表单等多样化交互信息,打开与用户互动的大门!
探索Bot API的其它接口,尝试使用它们。
在这里列出本文所用到的所有网址(Potato与其相关网站需翻墙访问!):
api官网: https://www.potato.im/api
bot api: https://www.potato.im/api/bot
potato商户官网: https://developer.pticc.net/#/
商户平台注册流程: https://developer.pticc.net/#/help/register
potato官网: https://www.potato.im/
Android版本下载: https://download.ddlpt.org/android/potato-2.37.apk
iOS版本下载(跳转至App Store): https://apps.apple.com/us/app/potato-chat/id1204726898
GitHub托管(全版本): https://github.com/potatogm/potato/releases
Mac OS版本下载: https://download.ddlpt.org/mac/Potato_Desktop2.37.dmg
Linux版本下载: https://download.ddlpt.org/linux/Potato_Desktop.2.37.tar.gz
如果你喜欢本文,就点个赞吧。。。