最近 ChatGPT 很火,也注冊了賬號玩了玩,確實(shí)灰常強(qiáng)大。但是也有的小伙伴可能沒辦法注冊賬號,我就想著把qq群機(jī)器人接入ChatGPT。 過程還是比較簡單順利的。下面簡單介紹一下
創(chuàng)新互聯(lián)公司是一家專注于成都做網(wǎng)站、成都網(wǎng)站制作與策劃設(shè)計(jì),西鄉(xiāng)塘網(wǎng)站建設(shè)哪家好?創(chuàng)新互聯(lián)公司做網(wǎng)站,專注于網(wǎng)站建設(shè)10多年,網(wǎng)設(shè)計(jì)領(lǐng)域的專業(yè)建站公司;建站業(yè)務(wù)涵蓋:西鄉(xiāng)塘等地區(qū)。西鄉(xiāng)塘做網(wǎng)站價(jià)格咨詢:13518219792直接跳過介紹,查項(xiàng)目代碼
1. ChatGPT 網(wǎng)頁的幾個(gè)接口介紹。 1.1 第一個(gè)接口https://chat.openai.com/backend-api/moderations
1.2 第二個(gè)接口控制臺上看到每次都有調(diào)用這個(gè)接口,但是阻塞這個(gè)接口,也可以正常運(yùn)行。所有可以忽略這個(gè)接口。
https://chat.openai.com/backend-api/conversation
1.3 第三個(gè)接口這個(gè)接口就是發(fā)送請求,獲取響應(yīng)的接口??刂婆_上看是fetch請求,但把請求直接copy出來,發(fā)現(xiàn)請求總是403。
https://chat.openai.com/api/auth/session
1.4 總結(jié): 經(jīng)過我的搗鼓,再加上 github 看了下別人寫的插件,可以像下面這樣正確的發(fā)送請求已經(jīng)接受響應(yīng)。 2. ChatGPT 具體請求示例 1. 復(fù)制cookie最后看到這個(gè)接口,大概就是刷新token的,第二個(gè)接口之前沒有調(diào)用這個(gè)接口,所以請求可能鑒權(quán)失敗。
從瀏覽器控制臺請求的請求頭,或者 application ->cookie 復(fù)制出 __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. 發(fā)起session請求,這里用java okhttp實(shí)現(xiàn),沒有多余封裝,直接硬碼把結(jié)果 nextAuthSessionToken 和 authorization 保留下來。nextAuthSessionToken 作為下一次請求 sessionReq
方法的參數(shù)(就不用每次都復(fù)制了),nextAuthSessionToken 和 authorization 都傳遞到下一個(gè)接口作為參數(shù)
public static String[] sessionReq(String copyCookie) throws IOException {//copyCookie就是從瀏覽器請求的請求頭,或者 application ->cookie 復(fù)制出 __Secure-next-auth.session-token 的key和value。
//ps: (__Secure-next-auth.callback-url 和 __Host-next-auth.csrf-token 可要可不要)
//示例: "__Secure-next-auth.session-token=eyJhbGciOiJkaXIiLCJlbmMiOiJBMjU2R0NNIn0....后面省略"
HashMapheaderMap = 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");
Mapcollect = 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. 發(fā)起 conversation 請求,同樣用java okhttp實(shí)現(xiàn),沒有多余封裝,直接硬碼requestBody 只用替換 query就行,conCookieMap 就是之前復(fù)制的cookie里的內(nèi)容,這里我把三組都寫上了,
__Host-next-auth.csrf-token 和 __Secure-next-auth.callback-url 都是固定值
public static String conversation(String[] auths, String requestBody) throws IOException {//這個(gè) 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];
//替換那個(gè) cookie
MapconCookieMap = new HashMap<>(4, 1);
//這個(gè)就是上面復(fù)制的cookie里的內(nèi)容
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);
HashMaphashMap = 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的響應(yīng)消息
String res = CharStreams.toString(new InputStreamReader(response.body().byteStream(), StandardCharsets.UTF_8));
//這里是連續(xù)多行
//a
//a b
//a b c
//這直接取倒數(shù)第二行
String[] split = res.split("\n");
Listcollect1 = 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 "服務(wù)出錯(cuò)了, g了";
}
這樣基本就能返回成功了,需要的依賴是 okhttp3 和 jackson 和 guava。普通java web項(xiàng)目里應(yīng)該都有
3. 接入qq機(jī)器人,我用的是 github 開源 mirai
3.1 基于 mirai 開發(fā)一個(gè)簡單的 qq機(jī)器人,支持艾特回復(fù)。
想了一下,還是直接上代碼吧,介紹累死我了。(以后有空再加)
項(xiàng)目地址mirai-qq-bot 最后效果演示這里跟一下趨勢,用的springboot3.0 java17開發(fā)
你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機(jī)房具備T級流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級服務(wù)器適合批量采購,新人活動首月15元起,快前往官網(wǎng)查看詳情吧