qq群聊机器人接入ChatGPT-简介和源码授权转载
Posted 牛哄哄的柯南
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了qq群聊机器人接入ChatGPT-简介和源码授权转载相关的知识,希望对你有一定的参考价值。
qq群聊机器人接入ChatGPT
最近 ChatGPT 很火,也注册了账号玩了玩,确实灰常强大。但是也有的小伙伴可能没办法注册账号,我就想着把qq群机器人接入ChatGPT。 过程还是比较简单顺利的。下面简单介绍一下
1. ChatGPT 网页的几个接口介绍。
1.1 第一个接口 https://chat.openai.com/backend-api/moderations
控制台上看到每次都有调用这个接口,但是阻塞这个接口,也可以正常运行。所有可以忽略这个接口。
1.2 第二个接口 https://chat.openai.com/backend-api/conversation
这个接口就是发送请求,获取响应的接口。控制台上看是fetch请求,但把请求直接copy出来,发现请求总是403。
1.3 第三个接口 https://chat.openai.com/api/auth/session
最后看到这个接口,大概就是刷新token的,第二个接口之前没有调用这个接口,所以请求可能鉴权失败。
1.4 总结: 经过我的捣鼓,再加上 github 看了下别人写的插件,可以像下面这样正确的发送请求已经接受响应。
2. ChatGPT 具体请求示例
1. 复制cookie
从浏览器控制台请求的请求头,或者 application -> cookie 复制出 __Secure-next-auth.session-token 的key和value。
示例:
"__Secure-next-auth.session-token=eyJhbGciOiJkaXIiLCJlbmMiOiJBMjU2R0NNIn0..R3Kc7SzojKpBGjqD.A8_9DrrtRoHFzEiJXrfWzePQg后面省略..."
ps: (__Secure-next-auth.callback-url 和 __Host-next-auth.csrf-token 可要可不要)
2. 发起session请求,这里用java okhttp实现,没有多余封装,直接硬码
把结果 nextAuthSessionToken 和 authorization 保留下来。nextAuthSessionToken 作为下一次请求 sessionReq 方法的参数(就不用每次都复制了),nextAuthSessionToken 和 authorization 都传递到下一个接口作为参数
public static String[] sessionReq(String copyCookie) throws IOException <!-- -->
//copyCookie就是从浏览器请求的请求头,或者 application -> cookie 复制出 __Secure-next-auth.session-token 的key和value。
//ps: (__Secure-next-auth.callback-url 和 __Host-next-auth.csrf-token 可要可不要)
//示例: "__Secure-next-auth.session-token=eyJhbGciOiJkaXIiLCJlbmMiOiJBMjU2R0NNIn0....后面省略"
HashMap<String, String> headerMap = Maps.newHashMap();
headerMap.put("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (Khtml, like Gecko) Chrome/107.0.0.0 Safari/537.36");
headerMap.put("cookie", copyCookie);
headerMap.put("accept-encoding", "gzip, deflate, br");
//session接口
Request getRequest = new Request.Builder()
.url("https://chat.openai.com/api/auth/session")
.get()
.headers(Headers.of(headerMap))
.build();
Response responseSession = client.newCall(getRequest).execute();
String result = CharStreams.toString(new InputStreamReader(responseSession.body().byteStream(), StandardCharsets.UTF_8));
logger.info("session response: ", result);
Map map = objectMapper.readValue(result, Map.class);
String setCookie = responseSession.headers().get("set-cookie");
Map<String, String> collect = Splitter.on(";").splitToList(setCookie)
.stream().filter(it -> it.contains("=")).map(it -> it.split("="))
.collect(Collectors.toMap(it -> it[0], it -> it[1]));
String nextAuthSessionToken = collect.get("__Secure-next-auth.session-token");
String authorization = (String) map.get("accessToken");
logger.info("nextAuthSessionToken: ", nextAuthSessionToken);
ChatGPTHandle.sessionToken = nextAuthSessionToken;
logger.info("authorization: ", authorization);
return new String[]<!-- -->nextAuthSessionToken, authorization;
3. 发起 conversation 请求,同样用java okhttp实现,没有多余封装,直接硬码
requestBody 只用替换 query就行,conCookieMap 就是之前复制的cookie里的内容,这里我把三组都写上了, __Host-next-auth.csrf-token 和 __Secure-next-auth.callback-url 都是固定值
public static String conversation(String[] auths, String requestBody) throws IOException <!-- -->
//这个 requestBody 可以作为模板写死,不同的请求只需要修改里面的query
// String requestBody = "\\"parent_message_id\\":\\"" + UUID.randomUUID()
// + "\\",\\"action\\":\\"next\\",\\"messages\\":[\\"role\\":\\"user\\",\\"id\\":\\""
// + UUID.randomUUID() + "\\",\\"content\\":\\"content_type\\":\\"text\\",\\"parts\\":[\\"" + "query" + "\\"]]," +
// "\\"model\\":\\"text-davinci-002-render\\"";
String nextAuthSessionToken = auths[0];
String authorization = auths[1];
//替换那个 cookie
Map<String, String> conCookieMap = new HashMap<>(4, 1);
//这个就是上面复制的cookie里的内容
conCookieMap.put("__Secure-next-auth.session-token", nextAuthSessionToken);
StringBuilder sb = new StringBuilder();
conCookieMap.forEach((k, v) -> sb.append(k).append("=").append(v).append("; "));
sb.deleteCharAt(sb.length() - 2);
HashMap<String, String> hashMap = Maps.newHashMap();
hashMap.put("accept-encoding", "gzip, deflate, br");
hashMap.put("accept-language", "zh-CN,zh;q=0.9");
hashMap.put("authorization", "Bearer " + authorization);
hashMap.put("content-type", "application/json");
hashMap.put("cookie", sb.toString().trim());
hashMap.put("origin", "https: //chat.openai.com");
hashMap.put("referer", "https: //chat.openai.com/chat");
hashMap.put("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36");
Request post = new Request.Builder()
.headers(Headers.of(hashMap))
.url("https://chat.openai.com/backend-api/conversation")
.post(RequestBody.create(MediaType.parse("application/json"), requestBody)).build();
Call call = client.newCall(post);
Response response = call.execute();
if (response.isSuccessful()) <!-- -->
//处理response的响应消息
String res = CharStreams.toString(new InputStreamReader(response.body().byteStream(), StandardCharsets.UTF_8));
//这里是连续多行
//a
//a b
//a b c
//这直接取倒数第二行
String[] split = res.split("\\n");
List<String> collect1 = Arrays.stream(split).filter(Strings::isNotBlank)
.collect(Collectors.toList());
String fullLine = collect1.get(collect1.size() - 2);
Map map1 = objectMapper.readValue(fullLine.substring(5), Map.class);
ArrayList list = (ArrayList) ((Map) ((Map) map1.get("message")).get("content")).get("parts");
return (String) list.get(0);
else <!-- -->
logger.info(response.code() + " " + response.toString());
return "服务出错了, g了";
这样基本就能返回成功了,需要的依赖是 okhttp3 和 jackson 和 guava。普通java web项目里应该都有
3. 接入qq机器人,我用的是 github 开源
3.1 基于 mirai 开发一个简单的 qq机器人,支持艾特回复。
想了一下,还是直接上代码吧,介绍累死我了。(以后有空再加)
项目地址
这里跟一下趋势,用的springboot3.0 java17开发
最后效果演示
转载说明
以上文章内容来自,我的朋友 我不是文盲 ,是一位低调的大佬,大家看完上面的文章感兴趣,可以进他主页关注一波。
版权声明:
原创博主:牛哄哄的柯南
博主原文链接:https://keafmd.blog.csdn.net/
个人博客链接:https://www.keafmd.top/
看完如果对你有帮助,感谢点击下面的点赞支持!
[哈哈][抱拳]
加油!
共同努力!
Keafmd
感谢支持牛哄哄的柯南,期待你的三连+关注~~
keep accumulate for my dream【共勉】
↓ ↓ ↓ ↓ ↓ ↓
以上是关于qq群聊机器人接入ChatGPT-简介和源码授权转载的主要内容,如果未能解决你的问题,请参考以下文章