--永恒的烦恼

ChatGPT对接QQ

最近挺火的OpenAI,本次对接的并不是意义上的ChatGPT的模型,主要是ChatGPT的模型还没开放,其他的模型是它叔叔爷爷那一辈的,该项目没有完善,谨慎使用!后期更新直接在GitHub更新,不会在本文更新源代码!

说明

本项目是基于 go-cqhttp+Python 搭建,配置由OpenAI给出的text-davinci-003模型接口、QQ账号、go-cqhttp框架的配置组成。没有使用网上一搜索就给出Python的web框架,我这里主要是为了方便打包环境没有使用,虽然基本功能已经完成,但很多方面的测试也没有进行,如有问题请发我邮件或进群询问!

一、go-cqhttp搭建

注意:以下所有的项目都在GitHub,国内的有时候访问不了,可以尝试更换电脑的DNS可以解决或者多刷新几次。
该项目个源地址:go-cqhttp项目地址
配置说明与文档都在,如果想自己开发扩展根据文档就可以解决!
项目是由go语言编写开发,如果你是小白,也不想知道那么多,就想下载安装使用,那这个windows下载就比较适合你。

以下是windows10版本的教程:

1.下载 地址:go-cqhttp下载地址


2.运行
在cmd环境下先进入程序所在的目录地址,最好每次启动都是如此,程序会根据当前的路径生成配置信息,查找配置文件时也是在当前的cmd目录查找。
我的是在F盘,根据你自己的来!

cd F:\个人脚本\QQ机器人\go-cqhttp
F:
dir
go-cqhttp.exe

我们需要生成的配置文件是:正向 Websocket 通信,如图所示:

3.修改go-cqhttp的启动文件
第一运行完成会默认在当前的cmd目录生成一个config.yml配置文件,在里面修改你的QQ号码和访问秘钥access-token就可以了,当然也修改端口,默认情况下在配置文件倒数第三行,address配置中,具体的一些配置和说明自行百度参考。

配置完成保存,再进行启动就可以了

cd F:\个人脚本\QQ机器人\go-cqhttp
F:
dir
go-cqhttp.exe

二、OpenAI的key获取

需要先在OpenAI进行注册并验证手机号码,这一个步骤请自己在百度搜索!这里仅演示如何获取
在登录的情况下点击个人中心:访问 OpenAI api接口key
点击添加,注意秘钥仅显示一次,需要复制好!

三、获取交互的程序

Python与go-cqhttp交互的源码如下:

import websocket
import json
from requests import post as requests_post

# 对接ChatGPT模型
def generate_text(prompt):
    global global_api_key, global_model
    try:
        completions_endpoint = f"https://api.openai.com/v1/engines/{global_model}/completions"
        headers = { "Content-Type": "application/json","Authorization": f"Bearer {global_api_key}"}
        data = {"prompt": prompt,"max_tokens": 1000,"temperature": 0.5}
        response = requests_post(completions_endpoint, headers=headers, json=data)
        if response.status_code == 200:
            completions = response.json()["choices"][0]["text"]  # 获取信息内容
            if response.json()["usage"]['completion_tokens'] < data.get('max_tokens'):
                return {"code": True, "mes": completions}
            else:
                return {"code": True, "mes": completions + '\n 回复太多,仅显示部分!'}
        if response.status_code == 401:
            if response.json()['error']['code'] == None:
                return {"code": False, "mes": '请填写api_key!'}
            if response.json()['error']['code'] == 'invalid_api_key':
                return {"code": False, "mes": 'api_key不对,请检查!'}
        if response.status_code == 400:
            return {"code": False, "mes": '信息有误或返回太大!返回信息:'+response.json()["error"]["message"]}
        if response.status_code == 429:
            return {"code": False, "mes": '无法处理信息:'+response.json()["error"]["message"]}
        return {"code": False,"mes":'连接不上api接口的服务器,网络不好!'}
    except Exception as e:
        print(e)
        return {"code": False,"mes":'对接ChatGPT 程序出错了!暂时不清楚情况!'}

# 消息发送通用封装
def send_msg(mes_data,user_id,type='group',group_id='0'):  # 消息是否为真、回复给谁、回复类型
    if type == 'private':
        data_mes = {"action": "send_msg", "params": {"message_type": 'private',"user_id": user_id,'message':mes_data['mes']}}
    else:
        data_mes = {"action": "send_group_msg", "params": {"group_id": group_id,"message": f"[CQ:at,qq={user_id}] {mes_data['mes']}"}}

    return json.dumps(data_mes)   # 返回字符串形式的数据

# 客户端接收服务端数据时触发
def on_message(ws, message):
    data = json.loads(message)
    if data.get('message_type') == 'private':  # 私人信息处理
        message = {'code':True,'mes':f'问题:{data.get("message")} \n 正在为您查询中......'}
        ws.send(send_msg(message, data['user_id'], 'private'))
        # 是否仅允许部分QQ
        global global_private_disabled
        if global_private_disabled:
            global global_private_group
            if str(data['user_id']) in global_private_group:
                mes = generate_text(data.get('message'))  # 发送数据并返回答案,返回的是字典
            else:
                mes = {'code': False, 'mes': '对不起,您的账号不在允许范围,详情请询问 玖伴一鹏'}
            data_mes = send_msg(mes, data['user_id'], 'private')
            ws.send(data_mes)
        else:
            mes = generate_text(data.get('message'))
            data_mes = send_msg(mes, data['user_id'], 'private')
            ws.send(data_mes)

    elif data.get('message_type') == 'group':  # 群消息
        # 判断是否是 @ 机器人的消息
        if f"[CQ:at,qq={data['self_id']}]" in data['message']:
            sickle_mes = data['message'].replace(f'[CQ:at,qq={data["self_id"]}]','')  # 将群信息@替换处理,仅保留信息内容
            mes_reply  = {'code':True,'mes':f'问题:{sickle_mes} \n 正在为您查询中......'}
            ws.send(send_msg(mes_reply,data['user_id'],group_id=data['group_id']))
            global global_group_disabled
            if global_group_disabled:
                mes = {'code':False,'mes':'对不起,暂时取消了对接的功能,详情请询问 玖伴一鹏'}
            else:
                mes = generate_text(sickle_mes)  # 需要将数据切割再发送数据并返回答案
            data_mes = send_msg(mes, data['user_id'],group_id=data['group_id'])  # 将信息发送到信息封装函数
            ws.send(data_mes)

# 通信发生错误时触发
def on_error(ws, error):
    print("{}返回错误:{}".format(ws,error))

# 连接关闭时触发
def on_close(ws):
    print("### 关闭 ###")

# 连接建立时触发
def on_open(ws):
    ws.send('{"action":get_msg, "params":{"message_id":1}')  # 获取消息

# 读配置文件
def read_setting():
    try:
        with open('./openai_config.json','r',encoding='utf-8') as f:
            return {'code':True,'mes':json.loads(f.read())}
    except Exception as e:
        return {'code':False,'mes':e}

if __name__ == "__main__":
    data = read_setting()
    if data['code']:
        setting_mes = data['mes']
        access_token = setting_mes['access_token']  # 你设置的access_token
        url = setting_mes['url']  # ip:端口 或 域名:端口
        global_api_key = setting_mes['global_api_key']  # ChatGPT 的api-key
        global_model = setting_mes['global_model']  # openai的模型,目前免费版本中比较好的是这个,其他的模型没有测试过
        global_group_disabled = setting_mes['global_group_disabled']  # 默认在QQ群里面的@使用模型回答,yes则禁用,默认是全部人,不允许单个
        global_private_disabled = setting_mes['global_private_disabled']  # 是否仅允许指定的QQ号回答,yes则禁用
        global_private_group = setting_mes['global_private_group']  # 启用仅允许指定的QQ号回答,需要添加账号
        websocket.enableTrace(True)
        ws = websocket.WebSocketApp(f"ws://{url}/?access_token={access_token}", on_message=on_message,on_error=on_error, on_close=on_close)
        ws.on_open = on_open
        ws.run_forever()
    else:
        print('配置文件有问题!')
        print(data['mes'])

为了配置方便特意改为json文件的配置方式,也方便后期的维护。
如果你不懂这些配置文件,可以直接点击 QQ对接chatgpt安装程序

四、交互程序的配置

配置文件为openai_config.json,默认如图所示,具体的说明请参考openai_config-说明.json文件

五、运行交互程序与测试




其他

本项目并没有完善,对于模型的接口我也不是很满意。

赞(6) 打赏
转载请带上源站链接:玖伴一鹏 » ChatGPT对接QQ

觉得文章有用就打赏一下文章作者

非常感谢你的打赏,我们将继续给力更多优质内容,让我们一起创建更加美好的网络世界!

支付宝扫一扫打赏

微信扫一扫打赏