diff --git a/README.md b/README.md
index 713de9a..e2405b4 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,6 @@
# Tether
-An API designed to provide real-time access to a user's Discord data.
\ No newline at end of file
+An API designed to provide real-time access to a user's Discord data.
+
+## TODO
+- [ ] Caching
+- [ ] User account for extra account? (about me, connections, etc)
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 9571425..2d73586 100644
--- a/pom.xml
+++ b/pom.xml
@@ -3,6 +3,12 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 3.3.2
+
+
me.braydon
@@ -13,6 +19,8 @@
21
+ ${java.version}
+ ${java.version}
UTF-8
@@ -59,6 +67,17 @@
1.18.34
provided
+
+ net.dv8tion
+ JDA
+ 5.1.0
+
+
+ club.minnced
+ opus-java
+
+
+
com.github.ben-manes.caffeine
caffeine
diff --git a/src/main/java/me/braydon/tether/Tether.java b/src/main/java/me/braydon/tether/Tether.java
index 564fd57..a7ada3c 100644
--- a/src/main/java/me/braydon/tether/Tether.java
+++ b/src/main/java/me/braydon/tether/Tether.java
@@ -1,10 +1,36 @@
package me.braydon.tether;
+import lombok.NonNull;
+import lombok.SneakyThrows;
+import lombok.extern.log4j.Log4j2;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+import java.io.File;
+import java.nio.file.Files;
+import java.nio.file.StandardCopyOption;
+import java.util.Objects;
+
/**
* @author Braydon
*/
-public final class Tether {
- public static void main(String[] args) {
+@SpringBootApplication
+@Log4j2(topic = "Tether")
+public class Tether {
+ @SneakyThrows
+ public static void main(@NonNull String[] args) {
+ // Load the application.yml configuration file
+ File config = new File("application.yml");
+ if (!config.exists()) { // Saving the default config if it doesn't exist locally
+ Files.copy(Objects.requireNonNull(Tether.class.getResourceAsStream("/application.yml")), config.toPath(), StandardCopyOption.REPLACE_EXISTING);
+ log.info("Saved the default configuration to '{}', please re-launch the application",
+ config.getAbsolutePath()
+ );
+ return;
+ }
+ log.info("Found configuration at '{}'", config.getAbsolutePath());
+ // Start the app
+ SpringApplication.run(Tether.class, args);
}
}
\ No newline at end of file
diff --git a/src/main/java/me/braydon/tether/common/EnvironmentUtils.java b/src/main/java/me/braydon/tether/common/EnvironmentUtils.java
new file mode 100644
index 0000000..8ad865d
--- /dev/null
+++ b/src/main/java/me/braydon/tether/common/EnvironmentUtils.java
@@ -0,0 +1,19 @@
+package me.braydon.tether.common;
+
+import lombok.Getter;
+import lombok.experimental.UtilityClass;
+
+/**
+ * @author Braydon
+ */
+@UtilityClass
+public final class EnvironmentUtils {
+ /**
+ * Is the app running in a production environment?
+ */
+ @Getter private static final boolean production;
+ static {
+ String appEnv = System.getenv("APP_ENV");
+ production = appEnv != null && (appEnv.equals("production"));
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/me/braydon/tether/controller/AppController.java b/src/main/java/me/braydon/tether/controller/AppController.java
new file mode 100644
index 0000000..cec7740
--- /dev/null
+++ b/src/main/java/me/braydon/tether/controller/AppController.java
@@ -0,0 +1,47 @@
+package me.braydon.tether.controller;
+
+import lombok.NonNull;
+import me.braydon.tether.common.EnvironmentUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.info.BuildProperties;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.Map;
+
+/**
+ * The root controller for this app.
+ *
+ * @author Braydon
+ */
+@RestController
+@RequestMapping(value = "/", produces = MediaType.APPLICATION_JSON_VALUE)
+public final class AppController {
+ /**
+ * The build properties for this app, null if not available.
+ */
+ private final BuildProperties buildProperties;
+
+ @Autowired
+ public AppController(BuildProperties buildProperties) {
+ this.buildProperties = buildProperties;
+ }
+
+ /**
+ * A GET endpoint to get info about this app.
+ *
+ * @return the info response
+ */
+ @GetMapping @ResponseBody @NonNull
+ public ResponseEntity