Commit 60a83c15 authored by Spotlight Deveaux's avatar Spotlight Deveaux 🦊

[bot] Add connection framework

This implements the main Discord surface of the bot - a mixture of JDA + JDA Utilities' wonderful handlers. It also provides necessary lifecycle actions to handle start up and shutdown, as coming. Configuration is handled. WebdriverTorso remains unfinished and rendering remains unimplemented.
parent 7fa1f074
......@@ -3,5 +3,8 @@
# Ignore Gradle build output directory
\ No newline at end of file
\ No newline at end of file
plugins {
id 'java'
id 'application'
id 'com.github.johnrengelman.shadow' version '5.1.0'
repositories {
......@@ -8,9 +9,25 @@ repositories {
dependencies {
testImplementation 'junit:junit:4.12'
compile 'com.jagrosh:jda-utilities:3.0.2'
compile 'net.dv8tion:JDA:4.0.0_52'
compile ''
// "You only need the karate-core Maven artifact." -Karate docs, 2019
// We require karate-apache to provide the "" file.
// Future: Should we continue requiring this separate dependency?
compile ''
compile ''
application {
mainClassName = 'space.joscomputing.discord.cssexpress.Main'
jar {
manifest {
attributes "Main-Class": "space.joscomputing.discord.cssexpress.Main"
"token": "BOT_TOKEN_HERE",
"botOwner": "239809536012058625",
"prefix": "<@635341691762638848> ",
"playingType": 3,
"playingText": "@Pinwheel fly",
"chromeExecutable": "/usr/bin/chromium-browser"
package space.joscomputing.discord.cssexpress;
public class Main {
public String getGreeting() {
return "Hello world.";
import com.jagrosh.jdautilities.command.CommandClientBuilder;
import com.jagrosh.jdautilities.commons.waiter.EventWaiter;
import net.dv8tion.jda.api.AccountType;
import net.dv8tion.jda.api.JDABuilder;
import net.dv8tion.jda.api.OnlineStatus;
import net.dv8tion.jda.api.entities.Activity;
import net.dv8tion.jda.api.hooks.EventListener;
import net.dv8tion.jda.api.hooks.ListenerAdapter;
import org.jetbrains.annotations.NotNull;
import java.nio.file.Paths;
public class Main extends ListenerAdapter implements EventListener {
private class SettingsFormat {
String token;
String botOwner;
String prefix;
// Note: Activity types may not age well. Please adapt better
// (or hard code the default status if absolutely necessary!)
int playingType;
String playingText;
String chromeExecutable;
private static WebdriverTorso torso;
public static void main(String[] args) throws IOException, LoginException {
// Check for config.json in the current directory.
File configuration = Paths.get(System.getProperty("user.dir"), "config.json").toFile();
if (!configuration.exists()) {
throw new FileNotFoundException("Configuration file \"config.json\" could not be found in the current directory!");
// Parse settings from given config
Gson gson = new Gson();
SettingsFormat config = gson.fromJson(new FileReader(configuration), SettingsFormat.class);
// JDA Utilities: set up its helper utilities
EventWaiter waiter = new EventWaiter();
CommandClientBuilder client = new CommandClientBuilder();
client.setActivity(Activity.of(Activity.ActivityType.fromKey(config.playingType), config.playingText));
new ShutdownCommand()
// Begin connection
torso = new WebdriverTorso(config.chromeExecutable);
// start getting a bot account set up
new JDABuilder(AccountType.BOT)
.setActivity(Activity.watching("wheels spin by, colors thrashing, the sheer utter beauty of a plastic farm..."))
.addEventListeners(waiter,, new Main())
public static void main(String[] args) {
System.out.println(new Main().getGreeting());
public void onReady(@NotNull ReadyEvent event) {
// For ctrl+c purposes
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
\ No newline at end of file
package space.joscomputing.discord.cssexpress;
import com.jagrosh.jdautilities.command.Command;
import com.jagrosh.jdautilities.command.CommandEvent;
public class ShutdownCommand extends Command {
ShutdownCommand() { = "shutdown"; = "shuts the bot down";
this.ownerCommand = true;
protected void execute(CommandEvent event) {
// Absolutely demolish life as we know it.
event.reply("And the colors drain.");
package space.joscomputing.discord.cssexpress;
* WebdriverTorso manages the lifecycle of a Chrome devtools connection.
* It also provides queueing abilities for necessary "rendered document" actions.
class WebdriverTorso {
private Chrome chrome;
WebdriverTorso(String hostLocation) {
chrome = Chrome.start(hostLocation, true);
void shutdown() {
package space.joscomputing.discord.cssexpress;
import org.junit.Test;
import static org.junit.Assert.*;
public class MainTest {
@Test public void testAppHasAGreeting() {
Main classUnderTest = new Main();
assertNotNull("main should have a greeting", classUnderTest.getGreeting());
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment