Compare commits
10 commits
2ab3c5e01d
...
654aca86cc
Author | SHA1 | Date | |
---|---|---|---|
654aca86cc | |||
034a5152df | |||
9fe5175f13 | |||
7fe9a82176 | |||
6e01af7572 | |||
9701d3faea | |||
79a13592c1 | |||
db872beac5 | |||
161509ad96 | |||
ac14f7ad42 |
11 changed files with 39 additions and 23 deletions
13
.env.example
13
.env.example
|
@ -1,13 +0,0 @@
|
|||
# No need to change
|
||||
POSTGRES_DB=dchat
|
||||
# "db" being the name of the postgresql service inside the docker-compose.yml, "5432" is the port on which postgres
|
||||
# listens for new connections and "dchat" is the database name.
|
||||
POSTGRES_URL=jdbc:postgresql://db:5432/dchat
|
||||
|
||||
# Please change
|
||||
DISCORD_API_KEY=<discord-api-key>
|
||||
OPENAI_API_KEY=<openai-api-key>
|
||||
|
||||
# Those values can not change after the first start
|
||||
POSTGRES_USER=<postgres-user>
|
||||
POSTGRES_PASSWORD=<postgres-password>
|
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -126,5 +126,6 @@ fabric.properties
|
|||
.idea/caches/build_file_checksums.ser
|
||||
|
||||
.env
|
||||
dchat.properties
|
||||
|
||||
data/
|
||||
|
|
|
@ -46,7 +46,6 @@
|
|||
<!--Remove unneeded files and symbols to reduce the image size and performance-->
|
||||
<noHeaderFiles>true</noHeaderFiles>
|
||||
<noManPages>true</noManPages>
|
||||
<stripDebug>true</stripDebug>
|
||||
<!--Compression is not needed since we unzip it in our OCI build-->
|
||||
<compress>zip-0</compress>
|
||||
</configuration>
|
||||
|
|
|
@ -10,6 +10,7 @@ import org.slf4j.Logger;
|
|||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
|
||||
public final class MessageService {
|
||||
|
@ -27,12 +28,12 @@ public final class MessageService {
|
|||
}
|
||||
|
||||
public void process(final String messageContent, final String referencedMessageContent, final String guildId, final String channelId, final String originalMessageId) {
|
||||
final var chatGPTRequest = new ChatGPTRequestBuilder().contextRequest(referencedMessageContent, messageContent, "system msg");
|
||||
final var chatGPTRequest = new ChatGPTRequestBuilder().contextRequest(referencedMessageContent, messageContent, systemMessage);
|
||||
process(chatGPTRequest, channelId, originalMessageId, guildId);
|
||||
}
|
||||
|
||||
public void process(final String messageContent, final String guildId, final String channelId, final String originalMessageId) {
|
||||
final var chatGPTRequest = new ChatGPTRequestBuilder().contextRequest(messageContent, "system msg");
|
||||
final var chatGPTRequest = new ChatGPTRequestBuilder().contextRequest(messageContent, systemMessage);
|
||||
process(chatGPTRequest, channelId, originalMessageId, guildId);
|
||||
}
|
||||
|
||||
|
@ -46,6 +47,11 @@ public final class MessageService {
|
|||
}
|
||||
};
|
||||
|
||||
executorService.submit(callable);
|
||||
// FIXME: We should find a solution to not block the main thread without loosing the started thread.
|
||||
try {
|
||||
executorService.submit(callable).get();
|
||||
} catch (InterruptedException | ExecutionException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,12 +22,15 @@ public final class DiscordRest {
|
|||
}
|
||||
|
||||
public void postMessage(final String channelId, final Message message) throws IOException, InterruptedException {
|
||||
final String data = message.toJson();
|
||||
logger.trace("Submitting new discord message: {}", data);
|
||||
final var uri = URI.create(DISCORD_URL + "/channels/%s/messages".formatted(channelId));
|
||||
final HttpRequest request = HttpRequest.newBuilder()
|
||||
.uri(uri)
|
||||
.header("Authorization", "Bot " + discordApiKey)
|
||||
.header("User-Agent", USER_AGENT)
|
||||
.POST(HttpRequest.BodyPublishers.ofString(message.toJson()))
|
||||
.header("Content-Type", "application/json")
|
||||
.POST(HttpRequest.BodyPublishers.ofString(data))
|
||||
.build();
|
||||
|
||||
final HttpResponse<Void> response = httpClient.send(request, HttpResponse.BodyHandlers.discarding());
|
||||
|
|
|
@ -1,8 +1,12 @@
|
|||
package de.hhhammer.dchat.discord.ws.connection;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.net.http.WebSocket;
|
||||
|
||||
public final class ResumeConnectionInitiator implements ConnectionInitiator {
|
||||
private static final Logger logger = LoggerFactory.getLogger(ResumeConnectionInitiator.class);
|
||||
private final String token;
|
||||
private final String sessionId;
|
||||
private final int lastSequence;
|
||||
|
@ -16,6 +20,7 @@ public final class ResumeConnectionInitiator implements ConnectionInitiator {
|
|||
@Override
|
||||
public void initiate(final WebSocket webSocket) {
|
||||
final String identifyPayload = "{\"op\": 6, \"d\": {\"token\": \"" + token + "\", \"session_id\": \"" + sessionId + "\", \"seq\": " + lastSequence + "}}";
|
||||
logger.debug("Resuming connection");
|
||||
webSocket.sendText(identifyPayload, true);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -68,7 +68,7 @@ public final class DiscordListener implements WebSocket.Listener {
|
|||
final String text = optText.get();
|
||||
final Event event = eventDeserializer.deserialize(text);
|
||||
final int currentSequence = event.sequence();
|
||||
lastSeq.set(currentSequence);
|
||||
if (currentSequence != 0) lastSeq.set(currentSequence);
|
||||
if (!(event.type() instanceof EventType.Empty)) {
|
||||
if (event.type() instanceof EventType.Ready) {
|
||||
final JSONObject payload = event.data();
|
||||
|
@ -109,6 +109,7 @@ public final class DiscordListener implements WebSocket.Listener {
|
|||
|
||||
@Override
|
||||
public CompletionStage<?> onClose(final WebSocket webSocket, final int statusCode, final String reason) {
|
||||
logger.info("Connection closed: {}: {}", statusCode, reason);
|
||||
switch (statusCode) {
|
||||
case 0, 4000, 4001, 4002, 4005, 4008 ->
|
||||
this.closeEventQueue.add(new CloseEvent.ResumableCloseEvent(this.resumeGatewayUrl.get(), this.sessionId.get(), lastSeq.get()));
|
||||
|
@ -141,6 +142,7 @@ public final class DiscordListener implements WebSocket.Listener {
|
|||
final int intSeq = lastSeq.get();
|
||||
final String stringSeq = intSeq != 0 ? String.valueOf(intSeq) : "null";
|
||||
// Send heartbeat
|
||||
logger.debug("Sending heartbeat: {}",stringSeq);
|
||||
webSocket.sendText("{\"op\": 1, \"d\": %s}".formatted(stringSeq), true);
|
||||
receivedAck.set(false);
|
||||
TimeUnit.MILLISECONDS.sleep(heartbeatInterval);
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
services:
|
||||
bot:
|
||||
image: git.hhhammer.de/hamburghammer/dchat/bot:latest
|
||||
env_file:
|
||||
- .env
|
||||
build:
|
||||
dockerfile: Dockerfile
|
||||
context: .
|
||||
target: bot
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
DCHAT_CONFIG_FILE: "/opt/dchat/dchat.properties"
|
||||
volumes:
|
||||
- ./dchat.properties:/opt/dchat/dchat.properties:ro
|
||||
|
|
7
example.properties
Normal file
7
example.properties
Normal file
|
@ -0,0 +1,7 @@
|
|||
dchat.discord-api-key=xxx
|
||||
dchat.openai-api-key=xxx
|
||||
dchat.bot-id=xxx
|
||||
# comma separated list
|
||||
dchat.allowed-guild-ids=foo,bar
|
||||
# not allowed to contain "!
|
||||
dchat.system-message=
|
|
@ -2,6 +2,8 @@ package de.hhhammer.dchat.openai.rest;
|
|||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONObject;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
|
@ -11,6 +13,7 @@ import java.net.http.HttpResponse;
|
|||
import java.time.Duration;
|
||||
|
||||
public final class ChatGPTService {
|
||||
private static final Logger logger = LoggerFactory.getLogger(ChatGPTService.class);
|
||||
private final String apiKey;
|
||||
private final HttpClient httpClient;
|
||||
|
||||
|
@ -21,6 +24,7 @@ public final class ChatGPTService {
|
|||
|
||||
public String submit(final ChatGPTRequest chatGPTRequest) throws IOException, InterruptedException, ResponseException {
|
||||
final String data = chatGPTRequest.toJson().toString();
|
||||
logger.trace("Submitting new ChatGPT request: {}", data);
|
||||
final URI uri = URI.create("https://api.openai.com/v1/chat/completions");
|
||||
final HttpRequest request = HttpRequest.newBuilder(uri)
|
||||
.POST(HttpRequest.BodyPublishers.ofString(data))
|
||||
|
@ -34,7 +38,7 @@ public final class ChatGPTService {
|
|||
throw new ResponseException("Response status code was not 200: " + response.statusCode());
|
||||
}
|
||||
|
||||
final var responseJson = new JSONObject(response);
|
||||
final var responseJson = new JSONObject(response.body());
|
||||
final JSONArray choices = responseJson.getJSONArray("choices");
|
||||
return getResponse(choices);
|
||||
}
|
||||
|
|
|
@ -5,4 +5,5 @@ module de.hhhammer.dchat.openai.rest {
|
|||
|
||||
requires org.json;
|
||||
requires static org.jetbrains.annotations;
|
||||
requires org.slf4j;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue