Compare commits
5 commits
33aeb356a4
...
7f3ec2276f
Author | SHA1 | Date | |
---|---|---|---|
7f3ec2276f | |||
16bcc6fdf3 | |||
355cd01ee3 | |||
1a21d25861 | |||
1d56ce0511 |
27 changed files with 161 additions and 81 deletions
|
@ -15,7 +15,7 @@
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>de.hhhammer.dchat</groupId>
|
<groupId>de.hhhammer.dchat</groupId>
|
||||||
<artifactId>discord</artifactId>
|
<artifactId>discord-ws</artifactId>
|
||||||
<version>1.0-SNAPSHOT</version>
|
<version>1.0-SNAPSHOT</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package de.hhhammer.dchat.bot;
|
package de.hhhammer.dchat.bot;
|
||||||
|
|
||||||
|
import de.hhhammer.dchat.discord.ws.EventHandler;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
@ -7,6 +8,12 @@ public final class App {
|
||||||
private static final Logger logger = LoggerFactory.getLogger(App.class);
|
private static final Logger logger = LoggerFactory.getLogger(App.class);
|
||||||
|
|
||||||
public static void main(final String[] args) {
|
public static void main(final String[] args) {
|
||||||
|
final String discordApiKey = System.getenv("DISCORD_API_KEY");
|
||||||
|
if (discordApiKey == null) {
|
||||||
|
logger.error("Missing environment variables: DISCORD_API_KEY");
|
||||||
|
System.exit(1);
|
||||||
|
}
|
||||||
|
final var eventHandler = new EventHandler.LogEventHandler();
|
||||||
logger.error("Currently not implemented!");
|
logger.error("Currently not implemented!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
4
bot/src/main/java/module-info.java
Normal file
4
bot/src/main/java/module-info.java
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
module de.hhhammer.dchat.bot {
|
||||||
|
requires de.hhhammer.dchat.discord.ws;
|
||||||
|
requires org.slf4j;
|
||||||
|
}
|
23
discord-rest/pom.xml
Normal file
23
discord-rest/pom.xml
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<parent>
|
||||||
|
<groupId>de.hhhammer.dchat</groupId>
|
||||||
|
<artifactId>dchat</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<artifactId>discord-rest</artifactId>
|
||||||
|
<name>discord-rest</name>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.json</groupId>
|
||||||
|
<artifactId>json</artifactId>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</project>
|
|
@ -0,0 +1,7 @@
|
||||||
|
package de.hhhammer.dchat.discord.rest;
|
||||||
|
|
||||||
|
public class Main {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
System.out.println("Hello world!");
|
||||||
|
}
|
||||||
|
}
|
7
discord-rest/src/main/java/module-info.java
Normal file
7
discord-rest/src/main/java/module-info.java
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
module de.hhhammer.dchat.discord.rest {
|
||||||
|
|
||||||
|
requires java.net.http;
|
||||||
|
|
||||||
|
requires org.json;
|
||||||
|
requires org.slf4j;
|
||||||
|
}
|
|
@ -7,8 +7,8 @@
|
||||||
<version>1.0-SNAPSHOT</version>
|
<version>1.0-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>discord</artifactId>
|
<artifactId>discord-ws</artifactId>
|
||||||
<name>discord</name>
|
<name>discord-ws</name>
|
||||||
<version>1.0-SNAPSHOT</version>
|
<version>1.0-SNAPSHOT</version>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
@ -17,14 +17,5 @@
|
||||||
<groupId>org.json</groupId>
|
<groupId>org.json</groupId>
|
||||||
<artifactId>json</artifactId>
|
<artifactId>json</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>org.junit.jupiter</groupId>
|
|
||||||
<artifactId>junit-jupiter</artifactId>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>ch.qos.logback</groupId>
|
|
||||||
<artifactId>logback-classic</artifactId>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</project>
|
</project>
|
|
@ -0,0 +1,37 @@
|
||||||
|
package de.hhhammer.dchat.discord.ws;
|
||||||
|
|
||||||
|
import de.hhhammer.dchat.discord.ws.connection.BackoffRetryer;
|
||||||
|
import de.hhhammer.dchat.discord.ws.connection.ConnectionManager;
|
||||||
|
import de.hhhammer.dchat.discord.ws.connection.Connector;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
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;
|
||||||
|
|
||||||
|
public DiscordWebSocket(final String discordApiKey, final EventHandler eventHandler) {
|
||||||
|
this.discordApiKey = discordApiKey;
|
||||||
|
this.eventHandler = eventHandler;
|
||||||
|
this.retryer = new BackoffRetryer();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(final String[] args) throws InterruptedException {
|
||||||
|
final String discordApiKey = System.getenv("DISCORD_API_KEY");
|
||||||
|
if (discordApiKey == null) {
|
||||||
|
logger.error("Missing environment variables: DISCORD_API_KEY");
|
||||||
|
System.exit(1);
|
||||||
|
}
|
||||||
|
final var eventHandler = new EventHandler.LogEventHandler();
|
||||||
|
final var instance = new DiscordWebSocket(discordApiKey, eventHandler);
|
||||||
|
instance.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void start() {
|
||||||
|
final var connector = new Connector(eventHandler);
|
||||||
|
final var connectionManager = new ConnectionManager(DISCORD_API_URL, discordApiKey, retryer);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package de.hhhammer.dchat;
|
package de.hhhammer.dchat.discord.ws;
|
||||||
|
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
|
@ -0,0 +1,7 @@
|
||||||
|
package de.hhhammer.dchat.discord.ws;
|
||||||
|
|
||||||
|
public interface Retryer {
|
||||||
|
public int nextRetryInSeconds();
|
||||||
|
|
||||||
|
public boolean hasRetriesLeft();
|
||||||
|
}
|
|
@ -1,12 +1,22 @@
|
||||||
package de.hhhammer.dchat;
|
package de.hhhammer.dchat.discord.ws.connection;
|
||||||
|
|
||||||
|
import de.hhhammer.dchat.discord.ws.Retryer;
|
||||||
|
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
public final class Retryer {
|
public final class BackoffRetryer implements Retryer {
|
||||||
private static final int maxRetries = 5;
|
|
||||||
private static final int delayInSeconds = 10;
|
private static final int delayInSeconds = 10;
|
||||||
private static final int backoffMultiplier = 2;
|
private static final int backoffMultiplier = 2;
|
||||||
private final AtomicInteger tries = new AtomicInteger();
|
private final AtomicInteger tries = new AtomicInteger();
|
||||||
|
private final int maxRetries;
|
||||||
|
|
||||||
|
public BackoffRetryer(final int maxRetries) {
|
||||||
|
this.maxRetries = maxRetries;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BackoffRetryer() {
|
||||||
|
this(5);
|
||||||
|
}
|
||||||
|
|
||||||
public int nextRetryInSeconds() {
|
public int nextRetryInSeconds() {
|
||||||
final int currentTry = tries.getAndIncrement();
|
final int currentTry = tries.getAndIncrement();
|
|
@ -1,4 +1,4 @@
|
||||||
package de.hhhammer.dchat;
|
package de.hhhammer.dchat.discord.ws.connection;
|
||||||
|
|
||||||
public record ConnectionConfig(String gatewayUrl, ConnectionInitiator connectionInitiator) {
|
public record ConnectionConfig(String gatewayUrl, ConnectionInitiator connectionInitiator) {
|
||||||
}
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package de.hhhammer.dchat;
|
package de.hhhammer.dchat.discord.ws.connection;
|
||||||
|
|
||||||
import java.net.http.WebSocket;
|
import java.net.http.WebSocket;
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
package de.hhhammer.dchat;
|
package de.hhhammer.dchat.discord.ws.connection;
|
||||||
|
|
||||||
import de.hhhammer.dchat.model.CloseEvent;
|
import de.hhhammer.dchat.discord.ws.Retryer;
|
||||||
|
import de.hhhammer.dchat.discord.ws.connection.event.CloseEvent;
|
||||||
|
|
||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
import java.util.function.Function;
|
|
||||||
|
|
||||||
public final class ConnectionManager {
|
public final class ConnectionManager {
|
||||||
private final String initGatewayUrl;
|
private final String initGatewayUrl;
|
||||||
|
@ -16,7 +17,7 @@ public final class ConnectionManager {
|
||||||
this.retryer = retryer;
|
this.retryer = retryer;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void start(final Function<ConnectionConfig, CloseEvent> connector) throws InterruptedException {
|
public void start(final Connector connector) throws InterruptedException {
|
||||||
while (retryer.hasRetriesLeft()) {
|
while (retryer.hasRetriesLeft()) {
|
||||||
connect(connector);
|
connect(connector);
|
||||||
final int reconnectDelayInSeconds = retryer.nextRetryInSeconds();
|
final int reconnectDelayInSeconds = retryer.nextRetryInSeconds();
|
||||||
|
@ -24,11 +25,11 @@ public final class ConnectionManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void connect(final Function<ConnectionConfig, CloseEvent> connector) {
|
private void connect(final Connector connector) {
|
||||||
ConnectionConfig mutConnectionConfig = new ConnectionConfig(initGatewayUrl, new IdendificationConnectionInitiator(token));
|
ConnectionConfig mutConnectionConfig = new ConnectionConfig(initGatewayUrl, new IdendificationConnectionInitiator(token));
|
||||||
boolean isResumable = true;
|
boolean isResumable = true;
|
||||||
while (isResumable) {
|
while (isResumable) {
|
||||||
final CloseEvent closeEvent = connector.apply(mutConnectionConfig);
|
final CloseEvent closeEvent = connector.connect(mutConnectionConfig);
|
||||||
isResumable = switch (closeEvent) {
|
isResumable = switch (closeEvent) {
|
||||||
case CloseEvent.ResumableCloseEvent resumableCloseEvent -> {
|
case CloseEvent.ResumableCloseEvent resumableCloseEvent -> {
|
||||||
mutConnectionConfig = new ConnectionConfig(
|
mutConnectionConfig = new ConnectionConfig(
|
|
@ -1,21 +1,21 @@
|
||||||
package de.hhhammer.dchat;
|
package de.hhhammer.dchat.discord.ws.connection;
|
||||||
|
|
||||||
import de.hhhammer.dchat.model.CloseEvent;
|
import de.hhhammer.dchat.discord.ws.EventHandler;
|
||||||
|
import de.hhhammer.dchat.discord.ws.connection.event.CloseEvent;
|
||||||
|
import de.hhhammer.dchat.discord.ws.connection.listener.DiscordListener;
|
||||||
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.net.http.HttpClient;
|
import java.net.http.HttpClient;
|
||||||
import java.util.concurrent.ArrayBlockingQueue;
|
import java.util.concurrent.ArrayBlockingQueue;
|
||||||
import java.util.function.Function;
|
|
||||||
|
|
||||||
public final class Connector implements Function<ConnectionConfig, CloseEvent> {
|
public final class Connector {
|
||||||
private final EventHandler eventHandler;
|
private final EventHandler eventHandler;
|
||||||
|
|
||||||
public Connector(final EventHandler eventHandler) {
|
public Connector(final EventHandler eventHandler) {
|
||||||
this.eventHandler = eventHandler;
|
this.eventHandler = eventHandler;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public CloseEvent connect(final ConnectionConfig connectionConfig) {
|
||||||
public CloseEvent apply(final ConnectionConfig connectionConfig) {
|
|
||||||
final ArrayBlockingQueue<CloseEvent> closeEventQueue = new ArrayBlockingQueue<>(1);
|
final ArrayBlockingQueue<CloseEvent> closeEventQueue = new ArrayBlockingQueue<>(1);
|
||||||
try (final HttpClient client = HttpClient.newHttpClient()) {
|
try (final HttpClient client = HttpClient.newHttpClient()) {
|
||||||
client.newWebSocketBuilder()
|
client.newWebSocketBuilder()
|
|
@ -1,4 +1,4 @@
|
||||||
package de.hhhammer.dchat;
|
package de.hhhammer.dchat.discord.ws.connection;
|
||||||
|
|
||||||
import java.net.http.WebSocket;
|
import java.net.http.WebSocket;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package de.hhhammer.dchat;
|
package de.hhhammer.dchat.discord.ws.connection;
|
||||||
|
|
||||||
import java.net.http.WebSocket;
|
import java.net.http.WebSocket;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package de.hhhammer.dchat.model;
|
package de.hhhammer.dchat.discord.ws.connection.event;
|
||||||
|
|
||||||
public sealed interface CloseEvent {
|
public sealed interface CloseEvent {
|
||||||
record UnresumableCloseEvent() implements CloseEvent {
|
record UnresumableCloseEvent() implements CloseEvent {
|
|
@ -1,4 +1,4 @@
|
||||||
package de.hhhammer.dchat.model;
|
package de.hhhammer.dchat.discord.ws.connection.event;
|
||||||
|
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
package de.hhhammer.dchat;
|
package de.hhhammer.dchat.discord.ws.connection.event;
|
||||||
|
|
||||||
import de.hhhammer.dchat.model.Event;
|
|
||||||
import de.hhhammer.dchat.model.EventType;
|
|
||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package de.hhhammer.dchat.model;
|
package de.hhhammer.dchat.discord.ws.connection.event;
|
||||||
|
|
||||||
public sealed interface EventType {
|
public sealed interface EventType {
|
||||||
String value();
|
String value();
|
|
@ -1,8 +1,11 @@
|
||||||
package de.hhhammer.dchat;
|
package de.hhhammer.dchat.discord.ws.connection.listener;
|
||||||
|
|
||||||
import de.hhhammer.dchat.model.CloseEvent;
|
import de.hhhammer.dchat.discord.ws.EventHandler;
|
||||||
import de.hhhammer.dchat.model.Event;
|
import de.hhhammer.dchat.discord.ws.connection.ConnectionInitiator;
|
||||||
import de.hhhammer.dchat.model.EventType;
|
import de.hhhammer.dchat.discord.ws.connection.event.CloseEvent;
|
||||||
|
import de.hhhammer.dchat.discord.ws.connection.event.Event;
|
||||||
|
import de.hhhammer.dchat.discord.ws.connection.event.EventDeserializer;
|
||||||
|
import de.hhhammer.dchat.discord.ws.connection.event.EventType;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
@ -30,7 +33,7 @@ public final class DiscordListener implements WebSocket.Listener {
|
||||||
private final EventHandler eventHandler;
|
private final EventHandler eventHandler;
|
||||||
private final BlockingQueue<CloseEvent> closeEventQueue;
|
private final BlockingQueue<CloseEvent> closeEventQueue;
|
||||||
|
|
||||||
public DiscordListener(final TextCollector textCollector,
|
DiscordListener(final TextCollector textCollector,
|
||||||
final EventDeserializer eventDeserializer,
|
final EventDeserializer eventDeserializer,
|
||||||
final ConnectionInitiator connectionInitiator,
|
final ConnectionInitiator connectionInitiator,
|
||||||
final EventHandler eventHandler,
|
final EventHandler eventHandler,
|
|
@ -1,11 +1,11 @@
|
||||||
package de.hhhammer.dchat;
|
package de.hhhammer.dchat.discord.ws.connection.listener;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
public final class TextCollector {
|
final class TextCollector {
|
||||||
private static final Logger logger = LoggerFactory.getLogger(TextCollector.class);
|
private static final Logger logger = LoggerFactory.getLogger(TextCollector.class);
|
||||||
private final StringBuilder stringBuilder = new StringBuilder();
|
private final StringBuilder stringBuilder = new StringBuilder();
|
||||||
|
|
8
discord-ws/src/main/java/module-info.java
Normal file
8
discord-ws/src/main/java/module-info.java
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
module de.hhhammer.dchat.discord.ws {
|
||||||
|
exports de.hhhammer.dchat.discord.ws;
|
||||||
|
|
||||||
|
requires java.net.http;
|
||||||
|
|
||||||
|
requires org.json;
|
||||||
|
requires org.slf4j;
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package de.hhhammer.dchat;
|
package de.hhhammer.dchat.discord.ws;
|
||||||
|
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
|
@ -1,22 +0,0 @@
|
||||||
package de.hhhammer.dchat;
|
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
public final class DiscordBotWebSocket {
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(DiscordBotWebSocket.class);
|
|
||||||
private static final String DISCORD_API_URL = "wss://gateway.discord.gg/?v=10&encoding=json";
|
|
||||||
|
|
||||||
public static void main(final String[] args) throws InterruptedException {
|
|
||||||
final String discordApiKey = System.getenv("DISCORD_API_KEY");
|
|
||||||
if (discordApiKey == null) {
|
|
||||||
logger.error("Missing environment variables: DISCORD_API_KEY");
|
|
||||||
System.exit(1);
|
|
||||||
}
|
|
||||||
final var eventHandler = new EventHandler.LogEventHandler();
|
|
||||||
final var connector = new Connector(eventHandler);
|
|
||||||
final var retryer = new Retryer();
|
|
||||||
final var connectionManager = new ConnectionManager(DISCORD_API_URL, discordApiKey, retryer);
|
|
||||||
connectionManager.start(connector);
|
|
||||||
}
|
|
||||||
}
|
|
15
pom.xml
15
pom.xml
|
@ -42,6 +42,11 @@
|
||||||
<groupId>org.jetbrains</groupId>
|
<groupId>org.jetbrains</groupId>
|
||||||
<artifactId>annotations</artifactId>
|
<artifactId>annotations</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.junit.jupiter</groupId>
|
||||||
|
<artifactId>junit-jupiter</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
|
|
||||||
|
@ -76,13 +81,6 @@
|
||||||
<artifactId>json</artifactId>
|
<artifactId>json</artifactId>
|
||||||
<version>20240303</version>
|
<version>20240303</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>com.fasterxml.jackson</groupId>
|
|
||||||
<artifactId>jackson-bom</artifactId>
|
|
||||||
<version>2.18.1</version>
|
|
||||||
<type>pom</type>
|
|
||||||
<scope>import</scope>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</dependencyManagement>
|
</dependencyManagement>
|
||||||
<build>
|
<build>
|
||||||
|
@ -98,6 +96,7 @@
|
||||||
</build>
|
</build>
|
||||||
<modules>
|
<modules>
|
||||||
<module>bot</module>
|
<module>bot</module>
|
||||||
<module>discord</module>
|
<module>discord-ws</module>
|
||||||
|
<module>discord-rest</module>
|
||||||
</modules>
|
</modules>
|
||||||
</project>
|
</project>
|
Loading…
Reference in a new issue