偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

附代碼,ChatGPT接入飛書(shū)詳細(xì)步驟

人工智能
飛書(shū)與ChatGPT的交互如下,我們的自定義服務(wù)就是充當(dāng)一個(gè)中間人的角色,進(jìn)行消息的轉(zhuǎn)發(fā)。

最近ChatGPT大火,boss也蠢蠢欲動(dòng)要求我們把ChatGPT接入飛書(shū),經(jīng)過(guò)一上午的研究,終于注冊(cè)成功并且實(shí)現(xiàn)了飛書(shū)機(jī)器人對(duì)接到ChatGPT。

下面給大家分享一下接入飛書(shū)的詳細(xì)步驟。

如何接入飛書(shū)

飛書(shū)與chatgpt的交互如下,我們的自定義服務(wù)就是充當(dāng)一個(gè)中間人的角色,進(jìn)行消息的轉(zhuǎn)發(fā)。

創(chuàng)建飛書(shū)機(jī)器人

1,進(jìn)入飛書(shū)開(kāi)放平臺(tái),選擇創(chuàng)建企業(yè)自建應(yīng)用。

2,創(chuàng)建完應(yīng)用以后,點(diǎn)擊進(jìn)入應(yīng)用,添加機(jī)器人。

3,給機(jī)器人配置消息相關(guān)的權(quán)限,如果不確定需要什么權(quán)限,可以先全部開(kāi)通。

4,配置事件訂閱。事件訂閱需要先開(kāi)發(fā)一個(gè)接口供飛書(shū)驗(yàn)證。接口需要可以公網(wǎng)訪問(wèn)。

這個(gè)接口的代碼可以參考如下:

@PostMapping(value = "/message")
public FeishuEventDTO message(@RequestBody String body) {
log.info("收到消息:{}", body);
FeishuEventParams feishuEventParams = JSON.parseObject(body, FeishuEventParams.class);
FeishuEventDTO eventDTO = new FeishuEventDTO();
eventDTO.setChallenge(feishuEventParams.getChallenge());
return eventDTO;
}

@Data
public class FeishuEventParams {

private String challenge;
private String token;
private String type;
}

@Data
public class FeishuEventDTO {
private String challenge;
}

有一點(diǎn)需要注意的是,這個(gè)校驗(yàn)接口和下面接收飛書(shū)消息的接口是同一個(gè)地址,但是消息體不一樣。

也就是說(shuō)校驗(yàn)接口是一次性的,校驗(yàn)完之后需要對(duì)這個(gè)接口進(jìn)行改造。

我們先將這個(gè)接口發(fā)布到一個(gè)可以公網(wǎng)訪問(wèn)的項(xiàng)目中,比如接口地址是
??http://xx.xx.xx.xx/xx/xx/message,將其填寫(xiě)到飛書(shū)中保存,飛書(shū)如果可以成功保存就沒(méi)問(wèn)題了。??

OK,到這里飛書(shū)的配置基本搞定了,下面就是我們需要進(jìn)行處理的邏輯了。

對(duì)接邏輯及實(shí)現(xiàn)

先說(shuō)一下我司對(duì)接的大致邏輯,供大家參考。

用戶(hù)發(fā)送消息到飛書(shū)之后,飛書(shū)會(huì)將消息轉(zhuǎn)發(fā)到我們自己的服務(wù)上。

但是這里會(huì)存在一個(gè)問(wèn)題,就是當(dāng)多個(gè)用戶(hù)并發(fā)發(fā)起會(huì)話時(shí),或者一個(gè)大群里很多人都在@我們的機(jī)器人時(shí),我們需要記住每一個(gè)人的回話,在chatgpt查詢(xún)到結(jié)果后,準(zhǔn)確的回復(fù)這個(gè)人。

由于我司目前也是用于內(nèi)部測(cè)試不想實(shí)現(xiàn)太復(fù)雜,所以我們采用的思路是:每一個(gè)用戶(hù)的會(huì)話轉(zhuǎn)發(fā)到我們的服務(wù)上時(shí),先將會(huì)話內(nèi)容保存到一個(gè)全局的ConcurrentLinkedQueue隊(duì)列中,然后啟動(dòng)一個(gè)線程,不停的消費(fèi)這個(gè)隊(duì)列。

隊(duì)列的泛型是一個(gè)提前構(gòu)造好的對(duì)象,這個(gè)對(duì)象保存著當(dāng)前消息的消息id,發(fā)送人,提問(wèn)內(nèi)容等。

每消費(fèi)一個(gè)對(duì)象,就將對(duì)象的提問(wèn)內(nèi)容發(fā)送到chatgpt,獲取響應(yīng)結(jié)果以后,調(diào)用飛書(shū)提供的會(huì)話回復(fù)接口去回復(fù)用戶(hù)。(如果并發(fā)量比較大,這里可以搞成異步的)。

好了,大致思路就說(shuō)到這,我們看一下具體的代碼。

1,打開(kāi)我們的項(xiàng)目,引入chatgpt提供的jar。

<dependency>
<groupId>com.theokanning.openai-gpt3-java</groupId>
<artifactId>service</artifactId>
<version>0.10.0</version>
</dependency>

2,重寫(xiě)上面的校驗(yàn)接口,改造成接收飛書(shū)消息。(接口路徑不要變)

@Slf4j
@RestController
@RequestMapping(value = "/query")
public class QureyController {

public static ConcurrentLinkedQueue<FeishuResponse> consumer
= new ConcurrentLinkedQueue<>();

@PostMapping(value = "/message")
public String message(@RequestBody String body) {
log.info("收到飛書(shū)消息:{}", body);
JSONObject jsonObject = JSONObject.parseObject(body);
JSONObject header = jsonObject.getJSONObject("header");
String eventType = header.getString("event_type");
if ("im.message.receive_v1".equals(eventType)) {
JSONObject event = jsonObject.getJSONObject("event");
JSONObject message = event.getJSONObject("message");
String messageType = message.getString("message_type");
if ("text".equals(messageType)) {
String messageId = message.getString("message_id");
String content = message.getString("content");
JSONObject contentJson = JSON.parseObject(content);
String text = contentJson.getString("text");

FeishuResponse feishuResponse = new FeishuResponse();
feishuResponse.setMessageId(messageId);
feishuResponse.setQuery(text);
log.info("投遞用戶(hù)消息,{}", JSON.toJSON(feishuResponse));
consumer.add(feishuResponse);
} else {
log.info("非文本消息");
}
}

return "suc";
}
}

FeishuResponse的結(jié)構(gòu)如下。

@Data
public class FeishuResponse {

private String messageId;

private String query;

}

3,寫(xiě)一個(gè)任務(wù)線程。

@Slf4j
public class AutoSendTask implements Runnable {
//你的chatgpt的key
public static final String token = "";
public static OpenAiService openAiService = null;

static {
openAiService = new OpenAiService(token, Duration.ofSeconds(60));
}

@Override
public void run() {
while (true) {
try {
FeishuResponse poll = consumer.poll();
if (poll == null) {
log.info("no query,sleep 2s");
TimeUnit.SECONDS.sleep(2);
} else {
String query = this.query(poll.getQuery());
this.reply(poll, query);
}
} catch (InterruptedException e) {
log.error("Thread exception...", e);
}
}
}

private String query(String q) {
log.info("開(kāi)始提問(wèn):{}", q);
CompletionRequest completionRequest = CompletionRequest.builder()
.prompt(q)
.model("text-davinci-003")
.maxTokens(2048)
.echo(false)
.build();
StringBuilder sb = new StringBuilder();
CompletionResult completion = openAiService.createCompletion(completionRequest);
log.info("q:{},獲取響應(yīng):{}", q, JSON.toJSONString(completion));
completion.getChoices().forEach(v -> {
sb.append(v.getText());
});
String rs = sb.toString();
if (rs.startsWith("?")) {
rs = rs.replaceFirst("?", "");
}
if (rs.startsWith("\n\n")) {
rs = rs.replaceFirst("\n\n", "");
}
log.info("格式化后的rs:{}", rs);
return rs;
}

private String reply(FeishuResponse poll, String rs) {
JSONObject params = new JSONObject();
params.put("uuid", RandomUtil.randomNumbers(10));
params.put("msg_type", "text");

JSONObject content = new JSONObject();
content.put("text", rs);
params.put("content", content.toJSONString());

String url = String.format("https://open.feishu.cn/open-apis/im/v1/messages/%s/reply",
poll.getMessageId());
String tenantAccessToken = FeishuUtils.getTenantAccessToken();
String body = null;
try (HttpResponse authorization = HttpUtil.createPost(url)
.header("Authorization", "Bearer " + tenantAccessToken)
.body(params.toJSONString())
.execute()) {
body = authorization.body();
}

return body;
}

}

獲取飛書(shū)token的工具類(lèi)如下:

@Slf4j
public class FeishuUtils {

public static final String tokenUrl
= "https://open.feishu.cn/open-apis/auth/v3/app_access_token/internal/";
//構(gòu)建一個(gè)cache 緩存飛書(shū)的token
static Cache<String, String> tokenCache =
CacheBuilder.newBuilder().expireAfterWrite(Duration.ofSeconds(3500)).build();
//這個(gè)是飛書(shū)應(yīng)用的appid和key,可以在創(chuàng)建的飛書(shū)應(yīng)用中找到
public static final String appId = "";
public static final String appKey = "";

public static String getTenantAccessToken() {
String token = null;
try {
token = tokenCache.get("token", () -> {
JSONObject params = new JSONObject();
params.put("app_id", appId);
params.put("app_secret", appKey);
String body;
try (HttpResponse execute = HttpUtil.createPost(tokenUrl)
.body(params.toJSONString()).execute()) {
body = execute.body();
}
log.info("獲取飛書(shū)token:{}", body);
if (StrUtil.isNotBlank(body)) {
String tenantAccessToken = JSON.parseObject(body).getString("tenant_access_token");
tokenCache.put("token", tenantAccessToken);
return tenantAccessToken;
}
return null;
});
} catch (ExecutionException e) {
throw new RuntimeException(e);
}
return token;
}
}

4,啟動(dòng)線程類(lèi)即可。

最后,出于隱私,chatgpt群會(huì)話的效果就不展示了,展示一下直接對(duì)話機(jī)器人的效果吧。

最后

由于我們引入chatgpt也只是抱著嘗試的態(tài)度,所以代碼相對(duì)也比較粗糙,如果有哪里寫(xiě)的不好的地方,還望大家海涵。

文中代碼還額外引入的jar有:guava、hutool-all、fastjson。

責(zé)任編輯:姜華 來(lái)源: 今日頭條
相關(guān)推薦

2020-12-02 10:27:40

C語(yǔ)言

2020-09-09 08:23:53

URLIP代碼

2023-03-16 16:09:29

ChatGPT證據(jù)任務(wù)

2014-01-02 10:19:54

PostgreSQL安裝

2009-11-06 11:20:01

家庭接入網(wǎng)

2020-12-09 11:32:10

CSS前端代碼

2009-07-10 17:40:58

Jython訪問(wèn)MyS

2009-07-09 14:16:00

Linux安裝JDK詳

2023-07-31 17:29:21

Docker鴻蒙

2009-12-24 16:37:03

XDSL寬帶接入系統(tǒng)

2009-11-02 15:47:09

無(wú)線接入網(wǎng)

2009-11-04 10:16:01

2009-12-25 10:29:28

2009-12-30 15:34:53

無(wú)線接入技術(shù)

2009-12-25 16:52:57

網(wǎng)絡(luò)接入控制

2009-12-09 15:22:10

2009-10-28 17:25:03

寬帶無(wú)線接入網(wǎng)

2010-07-02 14:37:20

配置SSH協(xié)議

2015-08-06 15:46:06

2023-12-13 13:28:00

Spring全局異常處理架構(gòu)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)