Python+Potato API实现关键字聊天机器人

写在前面

鸣谢:感谢@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)。(手机端左右滑动查看更多!)

注意:因为在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

如果你喜欢本文,就点个赞吧。。。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值