From 5f3adb62511ca56ccfa55850352d29c85811eb75 Mon Sep 17 00:00:00 2001 From: jenz Date: Sun, 8 Feb 2026 12:46:37 +0100 Subject: [PATCH] simple stoat integration --- ArtificialAutism/app.config | 3 + .../java/DataLayer/ThreadClientStoat.java | 180 ++++++++++++++++++ .../main/java/FunctionLayer/Datahandler.java | 4 +- .../FunctionLayer/PipelineJMWESingleton.java | 2 +- .../PresentationLayer/DiscordHandler.java | 23 ++- 5 files changed, 200 insertions(+), 12 deletions(-) create mode 100644 ArtificialAutism/src/main/java/DataLayer/ThreadClientStoat.java diff --git a/ArtificialAutism/app.config b/ArtificialAutism/app.config index b930ef1..2f0129b 100644 --- a/ArtificialAutism/app.config +++ b/ArtificialAutism/app.config @@ -11,3 +11,6 @@ app.string_count=14000 app.thread_count=4 app.interval_days_minus=4 app.random_length=2.5 +app.stoat_bot_token= +app.stoat_channel_id= +app.stoat_api_url= diff --git a/ArtificialAutism/src/main/java/DataLayer/ThreadClientStoat.java b/ArtificialAutism/src/main/java/DataLayer/ThreadClientStoat.java new file mode 100644 index 0000000..fbd62d8 --- /dev/null +++ b/ArtificialAutism/src/main/java/DataLayer/ThreadClientStoat.java @@ -0,0 +1,180 @@ +package DataLayer; + +import FunctionLayer.Datahandler; +import com.google.gson.Gson; +import com.google.gson.JsonArray; +import com.google.gson.JsonObject; +import edu.stanford.nlp.pipeline.StanfordCoreNLP; + +import java.io.*; +import java.net.HttpURLConnection; +import java.net.URL; +import java.util.Properties; + +public class ThreadClientStoat { + + private String lastProcessedMessageId = null; + + public ThreadClientStoat(Datahandler datahandler, StanfordCoreNLP stanfordCoreNLP, StanfordCoreNLP stanfordCoreNLPSentiment) { + Properties prop = new Properties(); + String fileName = "app.config"; + try (FileInputStream fis = new FileInputStream(fileName)) { + prop.load(fis); + } catch (FileNotFoundException ex) { + } catch (IOException ex) { + } + + + String botToken = prop.getProperty("app.stoat_bot_token"); + String channelId_general_autism = prop.getProperty("app.stoat_channel_id"); + String API_URL = prop.getProperty("app.stoat_api_url"); + + + while (true) { + try { + Thread.sleep(5000); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + //we dont need to constantly request new messages so adding some artifical delay to see if anything new is here. + JsonObject JsonObjmessages = GetLastMessagesFromStoad(botToken, channelId_general_autism, API_URL); + if (JsonObjmessages == null || JsonObjmessages.isEmpty()) + { + continue; + } + String sentence = GetMessageToProcess(JsonObjmessages); + if (!sentence.isEmpty()) + { + String ResponseMsg = datahandler.getResponseMsg(sentence, "", stanfordCoreNLP, stanfordCoreNLPSentiment, + false); + System.out.println(" ResponseMsg stoat: " + ResponseMsg); + + sendMessage(botToken, channelId_general_autism, API_URL, ResponseMsg); + } + } + } + + private String GetMessageToProcess(JsonObject JsonObjmessages) { + JsonArray messages = JsonObjmessages.getAsJsonArray("messages"); + JsonArray users = JsonObjmessages.getAsJsonArray("users"); + + for (int index = 0; index < messages.size(); index++) { + JsonObject message = messages.get(index).getAsJsonObject(); + lastProcessedMessageId = message.get("_id").getAsString(); + String authorId = message.get("author").getAsString(); + + JsonObject author = findUserById(users, authorId); + if (author != null) { + // Check if bot field exists and is true + if (author.has("bot")) { + continue; // Skip bot messages + } + } + return message.get("content").getAsString(); + + } + return ""; + } + + private JsonObject findUserById(JsonArray users, String userId) { + for (int i = 0; i < users.size(); i++) { + JsonObject user = users.get(i).getAsJsonObject(); + if (user.get("_id").getAsString().equals(userId)) { + return user; + } + } + return null; + } + + public JsonObject GetLastMessagesFromStoad(String botToken, String channelId_general_autism, String API_URL) { + try { + String urlString = API_URL + "/channels/" + channelId_general_autism + "/messages?limit=1&include_users=true"; + if (lastProcessedMessageId != null) + { + urlString = API_URL + "/channels/" + channelId_general_autism + "/messages?limit=5&include_users=true&sort=Oldest&after=" + lastProcessedMessageId; + } + URL url = new URL(urlString); + HttpURLConnection conn = (HttpURLConnection) url.openConnection(); + + // Set up the request + conn.setRequestMethod("GET"); + conn.setRequestProperty("x-bot-token", botToken); + conn.setRequestProperty("Content-Type", "application/json"); + + // Get the response + int responseCode = conn.getResponseCode(); + if (responseCode == HttpURLConnection.HTTP_OK) { + BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream())); + String inputLine; + StringBuilder response = new StringBuilder(); + + while ((inputLine = in.readLine()) != null) { + response.append(inputLine); + } + in.close(); + + if (response.toString().isEmpty()) + { + return null; + } + Gson gson = new Gson(); + return gson.fromJson(response.toString(), JsonObject.class); + } else { + System.err.println("GET request failed. Response Code: " + responseCode); + return null; + } + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + public void sendMessage(String botToken, String channelId_general_autism, String API_URL, String responseMessage) { + try { + String urlString = API_URL + "/channels/" + channelId_general_autism + "/messages"; + URL url = new URL(urlString); + HttpURLConnection conn = (HttpURLConnection) url.openConnection(); + + // Set up POST request + conn.setRequestMethod("POST"); + conn.setRequestProperty("x-bot-token", botToken); + conn.setRequestProperty("Content-Type", "application/json"); + conn.setDoOutput(true); + + // Create JSON body + JsonObject jsonBody = new JsonObject(); + jsonBody.addProperty("content", responseMessage); + Gson gson = new Gson(); + String jsonString = gson.toJson(jsonBody); + + // Send the request + try (OutputStream os = conn.getOutputStream()) { + byte[] input = jsonString.getBytes("utf-8"); + os.write(input, 0, input.length); + } + + // Get response + int responseCode = conn.getResponseCode(); + if (responseCode == HttpURLConnection.HTTP_OK || responseCode == 201) { + //System.out.println("Message sent successfully to Stoat"); + } else { + System.err.println("Failed to send message. Response Code: " + responseCode); + + // Read error response + BufferedReader errorReader = new BufferedReader( + new InputStreamReader(conn.getErrorStream()) + ); + String errorLine; + StringBuilder errorResponse = new StringBuilder(); + while ((errorLine = errorReader.readLine()) != null) { + errorResponse.append(errorLine); + } + errorReader.close(); + System.err.println("Error response: " + errorResponse.toString()); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + +} diff --git a/ArtificialAutism/src/main/java/FunctionLayer/Datahandler.java b/ArtificialAutism/src/main/java/FunctionLayer/Datahandler.java index fbe505b..38c0d12 100644 --- a/ArtificialAutism/src/main/java/FunctionLayer/Datahandler.java +++ b/ArtificialAutism/src/main/java/FunctionLayer/Datahandler.java @@ -144,7 +144,7 @@ public class Datahandler { props.setProperty("parse.model", shiftReduceParserPath); props.setProperty("parse.maxlen", "90"); props.setProperty("parse.binaryTrees", "true"); - props.setProperty("threads", "1"); + props.setProperty("threads", "2"); props.setProperty("pos.maxlen", "90"); props.setProperty("tokenize.maxlen", "90"); props.setProperty("ssplit.maxlen", "90"); @@ -171,7 +171,7 @@ public class Datahandler { propsSentiment.setProperty("parse.model", lexParserEnglishPCFG); propsSentiment.setProperty("sentiment.model", sentimentModel); propsSentiment.setProperty("parse.maxlen", "90"); - propsSentiment.setProperty("threads", "1"); + propsSentiment.setProperty("threads", "2"); propsSentiment.setProperty("pos.maxlen", "90"); propsSentiment.setProperty("tokenize.maxlen", "90"); propsSentiment.setProperty("ssplit.maxlen", "90"); diff --git a/ArtificialAutism/src/main/java/FunctionLayer/PipelineJMWESingleton.java b/ArtificialAutism/src/main/java/FunctionLayer/PipelineJMWESingleton.java index d338cd9..ed7591b 100644 --- a/ArtificialAutism/src/main/java/FunctionLayer/PipelineJMWESingleton.java +++ b/ArtificialAutism/src/main/java/FunctionLayer/PipelineJMWESingleton.java @@ -86,7 +86,7 @@ public class PipelineJMWESingleton { propsJMWE = new Properties(); propsJMWE.setProperty("annotators", "tokenize,ssplit,pos,lemma"); propsJMWE.setProperty("tokenize.options", "untokenizable=firstKeep"); - propsJMWE.setProperty("threads", "1"); + propsJMWE.setProperty("threads", "2"); propsJMWE.setProperty("pos.maxlen", "90"); propsJMWE.setProperty("tokenize.maxlen", "90"); propsJMWE.setProperty("ssplit.maxlen", "90"); diff --git a/ArtificialAutism/src/main/java/PresentationLayer/DiscordHandler.java b/ArtificialAutism/src/main/java/PresentationLayer/DiscordHandler.java index 7df8b18..95cd836 100644 --- a/ArtificialAutism/src/main/java/PresentationLayer/DiscordHandler.java +++ b/ArtificialAutism/src/main/java/PresentationLayer/DiscordHandler.java @@ -2,6 +2,7 @@ package PresentationLayer; import DataLayer.RunnerClient; import DataLayer.ThreadClient; +import DataLayer.ThreadClientStoat; import DataLayer.settings; import FunctionLayer.Datahandler; import FunctionLayer.PipelineJMWESingleton; @@ -58,14 +59,17 @@ public class DiscordHandler extends ListenerAdapter { } String token = prop.getProperty("app.discordtoken"); - try { - JDABuilder.createLight(token, GatewayIntent.GUILD_MESSAGES, GatewayIntent.DIRECT_MESSAGES) - .addEventListeners(new DiscordHandler()) - .setActivity(Activity.playing("Being the autism bot")) - .build(); - } catch (LoginException e) { - throw new RuntimeException(e); - } + + JDABuilder.createLight(token, GatewayIntent.GUILD_MESSAGES, GatewayIntent.MESSAGE_CONTENT, GatewayIntent.DIRECT_MESSAGES) + .addEventListeners(new DiscordHandler()) + .setActivity(Activity.playing("Being the autism bot")) + .build(); + + Thread udpThread = new Thread(() -> { + new ThreadClientStoat(datahandler, stanfordCoreNLP, stanfordCoreNLPSentiment); + }, "UDP-Socket-Thread"); + udpThread.start(); + new ThreadClient(datahandler, stanfordCoreNLP, stanfordCoreNLPSentiment); } @@ -74,7 +78,8 @@ public class DiscordHandler extends ListenerAdapter { public void onMessageReceived(MessageReceivedEvent event) { String content = event.getMessage().getContentRaw(); String username = event.getMessage().getAuthor().getName(); - List mentionedMembers = event.getMessage().getMentionedMembers(); + List mentionedMembers = event.getMessage().getMentions().getMembers(); + //List mentionedMembers = event.getMessage().getMentionedMembers(); if (mentionedMembers != null) { for (Member member : mentionedMembers) { content = content.replace(member.getId(), "");