Compare commits
3 commits
a51aea8013
...
590798c0c5
Author | SHA1 | Date | |
---|---|---|---|
590798c0c5 | |||
225f708c9f | |||
9d9a6fc42f |
9 changed files with 77 additions and 102 deletions
|
@ -24,31 +24,31 @@ public class DiscordRest {
|
|||
this.webConfig = webConfig;
|
||||
}
|
||||
|
||||
public void postMessage(int channelId, Message message) throws IOException, InterruptedException {
|
||||
var uri = URI.create(DISCORD_URL + "/channels/%s/messages".formatted(channelId));
|
||||
HttpRequest request = HttpRequest.newBuilder()
|
||||
public void postMessage(final int channelId, final Message message) throws IOException, InterruptedException {
|
||||
final var uri = URI.create(DISCORD_URL + "/channels/%s/messages".formatted(channelId));
|
||||
final HttpRequest request = HttpRequest.newBuilder()
|
||||
.uri(uri)
|
||||
.header("Authorization", "Bot " + webConfig.token())
|
||||
.header("User-Agent", USER_AGENT)
|
||||
.POST(HttpRequest.BodyPublishers.ofString(message.toJson()))
|
||||
.build();
|
||||
|
||||
HttpResponse<Void> response = httpClient.send(request, HttpResponse.BodyHandlers.discarding());
|
||||
final HttpResponse<Void> response = httpClient.send(request, HttpResponse.BodyHandlers.discarding());
|
||||
if (response.statusCode() != 201) {
|
||||
logger.error("Unexpected status code: {}", response.statusCode());
|
||||
}
|
||||
}
|
||||
|
||||
public Optional<String> getMessage(int channelId, int messageId) throws IOException, InterruptedException {
|
||||
var uri = URI.create(DISCORD_URL + "/channels/%s/messages/%s".formatted(channelId, messageId));
|
||||
HttpRequest request = HttpRequest.newBuilder()
|
||||
final var uri = URI.create(DISCORD_URL + "/channels/%s/messages/%s".formatted(channelId, messageId));
|
||||
final HttpRequest request = HttpRequest.newBuilder()
|
||||
.uri(uri)
|
||||
.header("Authorization", "Bot " + webConfig.token())
|
||||
.header("User-Agent", USER_AGENT)
|
||||
.GET()
|
||||
.build();
|
||||
|
||||
HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
|
||||
final HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
|
||||
if (response.statusCode() != 200) {
|
||||
logger.error("Could not get message");
|
||||
return Optional.empty();
|
||||
|
|
|
@ -8,7 +8,6 @@ import org.slf4j.LoggerFactory;
|
|||
|
||||
public final class DiscordWebSocket {
|
||||
private static final Logger logger = LoggerFactory.getLogger(DiscordWebSocket.class);
|
||||
private static final String DISCORD_API_URL = "wss://gateway.discord.gg/?v=10&encoding=json";
|
||||
private final String discordApiKey;
|
||||
private final EventHandler eventHandler;
|
||||
private final Retryer retryer;
|
||||
|
@ -30,8 +29,10 @@ public final class DiscordWebSocket {
|
|||
instance.start();
|
||||
}
|
||||
|
||||
public void start() {
|
||||
public void start() throws InterruptedException {
|
||||
final var connector = new Connector(eventHandler);
|
||||
final var connectionManager = new ConnectionManager(DISCORD_API_URL, discordApiKey, retryer);
|
||||
final String initGatewayUrl = "wss://gateway.discord.gg/?v=10&encoding=json";
|
||||
final var connectionManager = new ConnectionManager(initGatewayUrl, discordApiKey, retryer);
|
||||
connectionManager.start(connector);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ public final class IdendificationConnectionInitiator implements ConnectionInitia
|
|||
}
|
||||
|
||||
@Override
|
||||
public void initiate(WebSocket webSocket) {
|
||||
public void initiate(final WebSocket webSocket) {
|
||||
final String identifyPayload = "{\"op\": 2, \"d\": {\"token\": \"" + token + "\", \"intents\": 513, \"properties\": {\"os\": \"linux\", \"browser\": \"dchat_lib\", \"device\": \"dchat_lib\"}}}";
|
||||
webSocket.sendText(identifyPayload, true);
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ public final class ResumeConnectionInitiator implements ConnectionInitiator {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void initiate(WebSocket webSocket) {
|
||||
public void initiate(final WebSocket webSocket) {
|
||||
final String identifyPayload = "{\"op\": 6, \"d\": {\"token\": \"" + token + "\", \"session_id\": \"" + sessionId + "\", \"seq\": " + lastSequence + "}}";
|
||||
webSocket.sendText(identifyPayload, true);
|
||||
}
|
||||
|
|
|
@ -6,6 +6,36 @@ import org.json.JSONObject;
|
|||
import java.util.Map;
|
||||
|
||||
public final class EventDeserializer {
|
||||
private static EventType resolveEventType(final String type) {
|
||||
if (type.isBlank()) return new EventType.Empty();
|
||||
if ("READY".equals(type)) return new EventType.Ready();
|
||||
return new EventType.Unknown(type);
|
||||
}
|
||||
|
||||
private static int extractPossibleNullInt(final JSONObject jsonObject, final String key) {
|
||||
try {
|
||||
return jsonObject.getInt(key);
|
||||
} catch (JSONException e) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
private static String extractPossibleNullString(final JSONObject jsonObject, final String key) {
|
||||
try {
|
||||
return jsonObject.getString(key);
|
||||
} catch (JSONException e) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
private static JSONObject extractPossibleNullObject(final JSONObject jsonObject, final String key) {
|
||||
try {
|
||||
return jsonObject.getJSONObject(key);
|
||||
} catch (JSONException e) {
|
||||
return new JSONObject(Map.of());
|
||||
}
|
||||
}
|
||||
|
||||
public Event deserialize(final String text) {
|
||||
final JSONObject object = new JSONObject(text);
|
||||
final String type = extractPossibleNullString(object, "t");
|
||||
|
@ -15,34 +45,4 @@ public final class EventDeserializer {
|
|||
final JSONObject data = extractPossibleNullObject(object, "d");
|
||||
return new Event(eventType, sequence, operation, data);
|
||||
}
|
||||
|
||||
private EventType resolveEventType(final String type) {
|
||||
if (type.isBlank()) return new EventType.Empty();
|
||||
if ("READY".equals(type)) return new EventType.Ready();
|
||||
return new EventType.Unknown(type);
|
||||
}
|
||||
|
||||
private int extractPossibleNullInt(final JSONObject jsonObject, final String key) {
|
||||
try {
|
||||
return jsonObject.getInt(key);
|
||||
} catch (JSONException e) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
private String extractPossibleNullString(final JSONObject jsonObject, final String key) {
|
||||
try {
|
||||
return jsonObject.getString(key);
|
||||
} catch (JSONException e) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
private JSONObject extractPossibleNullObject(final JSONObject jsonObject, final String key) {
|
||||
try {
|
||||
return jsonObject.getJSONObject(key);
|
||||
} catch (JSONException e) {
|
||||
return new JSONObject(Map.of());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package de.hhhammer.dchat.openai.rest.models;
|
||||
package de.hhhammer.dchat.openai.rest;
|
||||
|
||||
import de.hhhammer.dchat.openai.rest.JsonSerializable;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONObject;
|
|
@ -2,7 +2,6 @@ package de.hhhammer.dchat.openai.rest;
|
|||
|
||||
import de.hhhammer.dchat.openai.rest.MessageContext.PreviousInteraction;
|
||||
import de.hhhammer.dchat.openai.rest.MessageContext.ReplyInteraction;
|
||||
import de.hhhammer.dchat.openai.rest.models.ChatGPTRequest;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
|
|
@ -1,15 +1,22 @@
|
|||
package de.hhhammer.dchat.openai.rest;
|
||||
|
||||
import de.hhhammer.dchat.openai.rest.models.ChatGPTRequest;
|
||||
import de.hhhammer.dchat.openai.rest.models.ChatGPTResponse;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URI;
|
||||
import java.net.http.HttpClient;
|
||||
import java.net.http.HttpRequest;
|
||||
import java.net.http.HttpResponse;
|
||||
import java.time.Duration;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.Spliterator;
|
||||
import java.util.Spliterators;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.StreamSupport;
|
||||
|
||||
public final class ChatGPTService {
|
||||
private final String apiKey;
|
||||
|
@ -20,7 +27,15 @@ public final class ChatGPTService {
|
|||
this.httpClient = httpClient;
|
||||
}
|
||||
|
||||
public ChatGPTResponse submit(final ChatGPTRequest chatGPTRequest) throws IOException, InterruptedException, ResponseException {
|
||||
private static <T> @Nullable T getFromJson(final Supplier<T> supplier) {
|
||||
try {
|
||||
return supplier.get();
|
||||
} catch (final JSONException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public Optional<String> submit(final ChatGPTRequest chatGPTRequest) throws IOException, InterruptedException, ResponseException {
|
||||
final String data = chatGPTRequest.toJson().toString();
|
||||
final URI uri = URI.create("https://api.openai.com/v1/chat/completions");
|
||||
final HttpRequest request = HttpRequest.newBuilder(uri)
|
||||
|
@ -30,11 +45,21 @@ public final class ChatGPTService {
|
|||
.timeout(Duration.ofMinutes(5))
|
||||
.build();
|
||||
|
||||
final HttpResponse<InputStream> responseStream = httpClient.send(request, HttpResponse.BodyHandlers.ofInputStream());
|
||||
if (responseStream.statusCode() != 200) {
|
||||
throw new ResponseException("Response status code was not 200: " + responseStream.statusCode());
|
||||
final HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
|
||||
if (response.statusCode() != 200) {
|
||||
throw new ResponseException("Response status code was not 200: " + response.statusCode());
|
||||
}
|
||||
|
||||
return mapper.readValue(responseStream.body(), ChatGPTResponse.class);
|
||||
final var responseJson = new JSONObject(response);
|
||||
final JSONArray choices = responseJson.getJSONArray("choices");
|
||||
final Spliterator<Object> spliterator = Spliterators.spliterator(choices.iterator(), choices.length(), Spliterator.SIZED);
|
||||
return StreamSupport.stream(spliterator, false)
|
||||
.filter(JSONObject.class::isInstance)
|
||||
.map(JSONObject.class::cast)
|
||||
.map(choice -> getFromJson(() -> choice.getJSONObject("message")))
|
||||
.filter(Objects::nonNull)
|
||||
.map(message -> getFromJson(() -> message.getString("content")))
|
||||
.filter(Objects::nonNull)
|
||||
.findFirst();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,49 +0,0 @@
|
|||
package de.hhhammer.dchat.openai.rest.models;
|
||||
|
||||
import de.hhhammer.dchat.openai.rest.JsonSerializable;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public record ChatGPTResponse(Usage usage, List<Choice> choices) implements JsonSerializable {
|
||||
@Override
|
||||
public @NotNull JSONObject toJson() {
|
||||
final var json = new JSONObject();
|
||||
json.put("usage", usage.toJson());
|
||||
final var jsonChoices = new JSONArray(choices.stream().map(Choice::toJson).toList());
|
||||
json.put("choices", jsonChoices);
|
||||
return json;
|
||||
}
|
||||
|
||||
public record Usage(int promptTokens, int completionTokens, int totalTokens) implements JsonSerializable {
|
||||
@Override
|
||||
public @NotNull JSONObject toJson() {
|
||||
final var json = new JSONObject();
|
||||
json.put("prompt_tokens", promptTokens);
|
||||
json.put("completion_tokens", completionTokens);
|
||||
json.put("total_tokens", totalTokens);
|
||||
return json;
|
||||
}
|
||||
}
|
||||
|
||||
public record Choice(Message message) implements JsonSerializable {
|
||||
@Override
|
||||
public @NotNull JSONObject toJson() {
|
||||
final var json = new JSONObject();
|
||||
json.put("message", message.toJson());
|
||||
return json;
|
||||
}
|
||||
|
||||
public record Message(String role, String content) implements JsonSerializable {
|
||||
@Override
|
||||
public @NotNull JSONObject toJson() {
|
||||
final var json = new JSONObject();
|
||||
json.put("role", role);
|
||||
json.put("content", content);
|
||||
return json;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue