ChatGPT ist in letzter Zeit populär geworden und der Chef ist auch bereit, uns zu bitten, ChatGPT mit Feishu zu verbinden. Nach einem Vormittag der Recherche haben wir uns endlich erfolgreich registriert und implementiert Feishu-Roboter zur Verbindung mit ChatGPT.
Lassen Sie mich die detaillierten Schritte für den Zugriff auf Feishu mit Ihnen teilen.
Die Interaktion zwischen Feishu und chatgpt ist wie folgt: Unser benutzerdefinierter Dienst fungiert als Vermittler für die Weiterleitung von Nachrichten.
1. Betreten Sie die offene Feishu-Plattform und wählen Sie die Erstellung einer selbst erstellten Unternehmensanwendung.
2 Klicken Sie nach dem Erstellen der Anwendung auf , um die Anwendung aufzurufen und den Roboter hinzuzufügen.
3. Wenn Sie nicht sicher sind, welche Berechtigungen erforderlich sind, können Sie sie zuerst alle aktivieren.
4, Ereignisabonnement konfigurieren. Für das Event-Abonnement muss zunächst eine Schnittstelle entwickelt werden, die Feishu überprüfen kann. Die Schnittstelle muss über das öffentliche Netzwerk erreichbar sein.
Der Code dieser Schnittstelle kann wie folgt bezeichnet werden:
@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; }
Eine Sache ist zu beachten dass diese Schule Die Verifizierungsschnittstelle hat dieselbe Adresse wie die Schnittstelle unten zum Empfangen von Feishu-Nachrichten, der Nachrichtentext ist jedoch unterschiedlich.
Das heißt, die Verifizierungsschnittstelle ist einmalig und muss nach der Verifizierung geändert werden.
Wir veröffentlichen diese Schnittstelle zunächst in einem Projekt, auf das über das öffentliche Netzwerk zugegriffen werden kann. Die Schnittstellenadresse lautet beispielsweise
https://www.php. cn/link/ 4aee31b0ec9f7bb7885473d95961e9a6
OK, jetzt ist die Konfiguration von Feishu im Grunde fertig. Hier ist die Logik, die wir verarbeiten müssen .
Lassen Sie mich zunächst als Referenz auf die allgemeine Logik des Andockens unseres Unternehmens eingehen.
Nachdem ein Benutzer eine Nachricht an Feishu gesendet hat, leitet Feishu die Nachricht an unseren eigenen Dienst weiter.
Aber hier wird es ein Problem geben, das heißt, wenn mehrere Benutzer gleichzeitig Gespräche initiieren oder wenn viele Personen in einer großen Gruppe @unserem Roboter sind, müssen wir uns die Antworten aller nach Chatgpt-Anfragen merken Ergebnisse, es wird dieser Person genau antworten.
Da unser Unternehmen es derzeit für interne Tests verwendet und nicht möchte, dass die Implementierung zu kompliziert wird, verfolgen wir die Idee: Wenn die Sitzung jedes Benutzers an unseren Dienst weitergeleitet wird, steht der Sitzungsinhalt an erster Stelle Speichern Sie es in einer globalen ConcurrentLinkedQueue-Warteschlange und starten Sie dann einen Thread, um diese Warteschlange kontinuierlich zu nutzen.
Der generische Warteschlangentyp ist ein im Voraus erstelltes Objekt. Dieses Objekt speichert die Nachrichten-ID der aktuellen Nachricht, den Absender, den Frageinhalt usw.
Jedes Mal, wenn ein Objekt verbraucht wird, wird der Frageinhalt des Objekts an chatgpt gesendet. Nach Erhalt des Antwortergebnisses wird die von Feishu bereitgestellte Konversationsantwortschnittstelle aufgerufen, um dem Benutzer zu antworten. (Wenn die Parallelität relativ groß ist, kann sie hier asynchron gemacht werden).
Okay, das war's für die allgemeine Idee, werfen wir einen Blick auf den spezifischen Code.
1, öffnen Sie unser Projekt und stellen Sie das von chatgpt bereitgestellte Glas vor.
<dependency> <groupId>com.theokanning.openai-gpt3-java</groupId> <artifactId>service</artifactId> <version>0.10.0</version> </dependency>
2, schreiben Sie die obige Verifizierungsschnittstelle neu und ändern Sie sie, um Feishu-Nachrichten zu empfangen. (Ändern Sie den Schnittstellenpfad nicht)
@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("收到飞书消息:{}", 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("投递用户消息,{}", JSON.toJSON(feishuResponse)); consumer.add(feishuResponse); } else { log.info("非文本消息"); } } return "suc"; } }
Die Struktur von FeishuResponse ist wie folgt.
@Data public class FeishuResponse { private String messageId; private String query; }
3, schreibe einen Aufgabenthread.
@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("开始提问:{}", 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:{},获取响应:{}", 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("nn")) { rs = rs.replaceFirst("nn", ""); } 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; } }
Die Tool-Klasse zum Erhalten des Feishu-Tokens lautet wie folgt:
@Slf4j public class FeishuUtils { public static final String tokenUrl = "https://open.feishu.cn/open-apis/auth/v3/app_access_token/internal/"; //构建一个cache 缓存飞书的token static Cache<String, String> tokenCache = CacheBuilder.newBuilder().expireAfterWrite(Duration.ofSeconds(3500)).build(); //这个是飞书应用的appid和key,可以在创建的飞书应用中找到 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("获取飞书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, starten Sie einfach die Thread-Klasse.
Abschließend wird aus Datenschutzgründen der Effekt des Chatgpt-Gruppengesprächs nicht angezeigt.
Da wir chatgpt nur mit einer Testeinstellung eingeführt haben, ist der Code relativ grob, wenn ja, hoffe ich Jeder wird mir verzeihen, wenn ich etwas Schlechtes schreibe.
Der Code in diesem Artikel führt auch zusätzliche Gläser ein: guava, hutool-all und fastjson.
Das obige ist der detaillierte Inhalt vonCode beigefügt, detaillierte Schritte zum Verbinden von ChatGPT mit Feishu. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!