Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
104 changes: 93 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,24 +1,106 @@
![discord.jv banner](https://cdn.discordapp.com/attachments/1045606909195071498/1045608115074252800/AB1CEB6F-A4D9-496E-9520-821EB3BA0FCC-removebg-preview.png)

[![seailz - discord.jv](https://img.shields.io/static/v1?label=seailz&message=discord.jv&color=blue&logo=github)](https://github.com/seailz/discord.jv "Go to GitHub repo") [![stars - discord.jv](https://img.shields.io/github/stars/seailz/discord.jv?style=social)](https://github.com/seailz/discord.jv) [![forks - discord.jv](https://img.shields.io/github/forks/seailz/discord.jv?style=social)](https://github.com/seailz/discord.jv) [![License](https://img.shields.io/badge/License-GNU_General_Public_License_v3.0-blue)](#license) [![issues - discord.jv](https://img.shields.io/github/issues/seailz/discord.jv)](https://github.com/seailz/discord.jv/issues)

# discord.jv - a clean Java wrapper for Discord
discord.jv [![loc - discord.jv](https://sloc.xyz/github/seailz/discord.jv)](https://github.com/seailz/discord.jv) is a **work in progress** Java wrapper for the [Discord API](https://discord.com/developers/docs/intro).
Everything that needs doing can be found in the [Issues](https://github.com/seailz/discord.jv/issues) tab, so if you're interested in helping out it would be greatly appreciated!

discord.jv [![loc - discord.jv](https://sloc.xyz/github/seailz/discord.jv)](https://github.com/seailz/discord.jv) is
a **work in progress** Java wrapper for the [Discord API](https://discord.com/developers/docs/intro).
Everything that needs doing can be found in the [Issues](https://github.com/seailz/discord.jv/issues) tab, so if you're
interested in helping out it would be greatly appreciated!

## Getting Started

### Prerequisites

You'll need to add discord.jv to your project's dependencies. We are currently using
jitpack to host our builds. See tutorials for your dependency management
system [here](https://jitpack.io/#discord-jv/discord.jv/-SNAPSHOT).

A Discord bot token is required to use the API. You can get one by creating a bot
account [here](https://discord.com/developers/applications).

### Creating a Bot

To initialize a bot that uses the gateway (is able to receive events), you can use the following code:

```java
new DiscordJv("token");
```

You can specify intents to use with the gateway by using the following code:

```java
new DiscordJv("token",EnumSet.of(Intents.GUILDS,Intents.GUILD_MESSAGES));
```

Note: You can use the `Intents.ALL` constant to specify all intents. This does not include privileged intents.

### Creating an HTTP-Only bot

To make your bot an <a href="https://discord.com/developers/docs/topics/gateway#privileged-intents">HTTP only bot</a>,
you'll need to specify a couple more parameters.

```java
new DiscordJv("token",EnumSet.of(Intents.GUILDS,Intents.GUILD_MESSAGES),true,
new HTTPOnlyInfo(
"interactions",
"EXAMPLE_APPLICATION_PUBLIC_KEY", // this cxan be found in your application's page in the dev panel
));
```

You should set `"interactions"` to whatever endpoint you want to use to receive post requests from Discord. This will be
the endpoint you set in the Discord Developer Portal.

This WILL break some methods and is only recommended to be used if you know what you are doing.
Otherwise, making a normal bot is recommended.
HTTP-only bots (or Interaction-only bots) are bots that do not connect to the gateway, and therefore cannot receive
events.
They receive interactions through POST requests to a specified endpoint of your bot.
This is useful if you want to make a bot that only uses slash commands.
<p>
Voice <b>will not work</b>, neither will setting your status & most gateway events.
<br>Interaction-based events will still be delivered as usual.
<p>
To change the port of your web server, create a new file in the running directory called `application.properties` and add the following line:

```
server.port=8081
```

#### Getting it set up in the Discord Developer Portal

1. Go to the [Discord Developer Portal](https://discord.com/developers/applications)
2. You'll want to start your bot if you haven't already.
3. Select your bot.
4. Go to the "General Information" tab.
5. Scroll down to "INTERACTIONS ENDPOINT URL" and set it to the URL of your bot's endpoint. For example, if my bot's IP
was 123, the port was 321, and the endpoint was "interactions", I would set it to `http://123:321/interactions`.

If it fails to save after that, please contact `Seailz#0001` on Discord.

## Documentation
There is currently no documentation, but it will be avaliable [here](https://discord-jv.gitbook.io/discord.jv-documentation/) when it's ready. Although there is no documentation, there are still examples which are avaliable [here](https://github.com/discord-jv/discord.jv/tree/main/examples)

There is currently no documentation (excluding the tiny bit above), but it will be
available [here](https://discord-jv.gitbook.io/discord.jv-documentation/) when it's ready. Although there is no
documentation, there are still examples which are
avaliable [here](https://github.com/discord-jv/discord.jv/tree/main/examples)

Javadocs can be found [here](https://discord-jv.github.io/discord.jv).

## Contributing
If you want to contribute to this project, feel free to do so! Everything that needs doing can be found in the [Issues](https://github.com/seailz/discord.jv/issues) tab,
and if an issue there has the **avaliable** tag you are free to make a PR fixing/adding it! :)

Make sure you first check the [active PRs](https://github.com/seailz/discord.jv/pulls) and branches for the feature/bug you're fixing/adding.
If you make a PR for an issue with the **claimed** tag and you are not the one who claimed it, (or in other words if there is a PR open for the issue you're looking to fix/add), then your PR will be closed.

If you've opened a PR but it's not yet finished, please mark it as a draft PR.
Branches should be named either:

If you want to contribute to this project, feel free to do so! Everything that needs doing can be found in
the [Issues](https://github.com/seailz/discord.jv/issues) tab,
and if an issue there has the **available** tag you are free to make a PR fixing/adding it! :)

Make sure you first check the [active PRs](https://github.com/seailz/discord.jv/pulls) and branches for the feature/bug
you're fixing/adding.
If you make a PR for an issue with the **claimed** tag, and you are not the one who claimed it, (or in other words if
there is a PR open for the issue you're looking to fix/add), then your PR will be closed.

If you've opened a PR, but it's not yet finished, please mark it as a draft PR.
Branches should be named either:
`feature/[feature]`
or
`bug/[bugfix]`
Expand Down
21 changes: 21 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,16 @@
<goal>shade</goal>
</goals>
<configuration>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
<createDependencyReducedPom>false</createDependencyReducedPom>
</configuration>
</execution>
Expand All @@ -51,6 +61,17 @@
</build>

<dependencies>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.12</version>
</dependency>
<!-- Used for interaction-only bot security -->
<dependency>
<groupId>software.pando.crypto</groupId>
<artifactId>salty-coffee</artifactId>
<version>1.1.0</version>
</dependency>
<!-- Used for data parsing -->
<dependency>
<groupId>org.json</groupId>
Expand Down
37 changes: 30 additions & 7 deletions src/main/java/com/seailz/discordjv/DiscordJv.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import com.seailz.discordjv.events.DiscordListener;
import com.seailz.discordjv.events.EventDispatcher;
import com.seailz.discordjv.gateway.GatewayFactory;
import com.seailz.discordjv.http.HttpOnlyApplication;
import com.seailz.discordjv.model.application.Application;
import com.seailz.discordjv.model.application.Intent;
import com.seailz.discordjv.model.channel.Category;
Expand All @@ -28,6 +29,7 @@
import com.seailz.discordjv.model.status.Status;
import com.seailz.discordjv.model.user.User;
import com.seailz.discordjv.utils.Checker;
import com.seailz.discordjv.utils.HTTPOnlyInfo;
import com.seailz.discordjv.utils.URLS;
import com.seailz.discordjv.utils.cache.Cache;
import com.seailz.discordjv.utils.cache.JsonCache;
Expand Down Expand Up @@ -63,7 +65,7 @@ public class DiscordJv {
/**
* Used to manage the gateway connection
*/
private final GatewayFactory gatewayFactory;
private GatewayFactory gatewayFactory;
/**
* Stores the logger
*/
Expand Down Expand Up @@ -107,17 +109,30 @@ public class DiscordJv {
*/
private JsonCache selfUserCache;

public DiscordJv(String token, EnumSet<Intent> intents, APIVersion version) throws ExecutionException, InterruptedException {
this(token, intents, version, false, null);
}

/**
* Creates a new instance of the DiscordJv class
* This will start the connection to the Discord gateway, set caches, set the event dispatcher, set the logger, set up eliminate handling, and initiates no shutdown
*
* @param token The token of the bot
* @param intents The intents the bot will use
* @param version The version of the Discord API the bot will use
* @param token The token of the bot
* @param intents The intents the bot will use
* @param version The version of the Discord API the bot will use
* @param httpOnly Makes your bot an <a href="https://discord.com/developers/docs/topics/gateway#privileged-intents">HTTP only bot</a>. This WILL
* break some methods and is only recommended to be set to true if you know what you are doing. Otherwise, leave it to false or don't set it.
* HTTP-only bots (or Interaction-only bots) are bots that do not connect to the gateway, and therefore cannot receive events. They receive
* interactions through POST requests to a specified endpoint of your bot. This is useful if you want to make a bot that only uses slash commands.
* Voice <b>will not work</b>, neither will {@link #setStatus(Status)} & most gateway events.
* Interaction-based events will still be delivered as usual.
* For a full tutorial, see the README.md file.
* @param httpOnlyInfo The information needed to make your bot HTTP only. This is only needed if you set httpOnly to true, otherwise set to null.
* See the above parameter for more information.
* @throws ExecutionException If an error occurs while connecting to the gateway
* @throws InterruptedException If an error occurs while connecting to the gateway
*/
public DiscordJv(String token, EnumSet<Intent> intents, APIVersion version) throws ExecutionException, InterruptedException {
public DiscordJv(String token, EnumSet<Intent> intents, APIVersion version, boolean httpOnly, HTTPOnlyInfo httpOnlyInfo) throws ExecutionException, InterruptedException {
System.setProperty("sun.net.http.allowRestrictedHeaders", "true");
this.token = token;
this.intents = intents;
Expand All @@ -126,7 +141,7 @@ public DiscordJv(String token, EnumSet<Intent> intents, APIVersion version) thro
this.commandDispatcher = new CommandDispatcher();
this.rateLimits = new HashMap<>();
this.queuedRequests = new ArrayList<>();
this.gatewayFactory = new GatewayFactory(this);
if (!httpOnly) this.gatewayFactory = new GatewayFactory(this);
this.guildCache = new Cache<>(this, Guild.class,
new DiscordRequest(
new JSONObject(),
Expand Down Expand Up @@ -158,6 +173,12 @@ public DiscordJv(String token, EnumSet<Intent> intents, APIVersion version) thro
this.eventDispatcher = new EventDispatcher(this);
new RequestQueueHandler(this);

if (httpOnly) {
if (httpOnlyInfo == null)
throw new IllegalArgumentException("httpOnlyInfo cannot be null if httpOnly is true!");
HttpOnlyApplication.init(this, httpOnlyInfo.endpoint(), httpOnlyInfo.applicationPublicKey());
}

initiateNoShutdown();
initiateShutdownHooks();
}
Expand Down Expand Up @@ -193,7 +214,7 @@ protected void initiateShutdownHooks() {
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
gatewayFactory.close();
if (gatewayFactory != null) gatewayFactory.close();
}));
}

Expand All @@ -204,6 +225,8 @@ protected void initiateShutdownHooks() {
* @throws IOException If an error occurs while setting the status
*/
public void setStatus(@NotNull Status status) throws IOException {
if (gatewayFactory == null)
throw new IllegalStateException("Cannot set status on an HTTP-only bot. See the constructor for more information.");
JSONObject json = new JSONObject();
json.put("d", status.compile());
json.put("op", 3);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@ public void dispatch(String name, CommandInteractionEvent event) {
.get(subListeners.values().stream().toList().indexOf(detailsList));

if (Objects.equals(name, top.getClass().getAnnotation(SlashCommandInfo.class).name())) {
System.out.println("found top command " + name);
details.listener().onCommand(event);
}
return;
Expand Down
18 changes: 18 additions & 0 deletions src/main/java/com/seailz/discordjv/http/HttpOnlyApplication.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.seailz.discordjv.http;

import com.seailz.discordjv.DiscordJv;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class HttpOnlyApplication {

public HttpOnlyApplication() {
}

public static void init(DiscordJv discordJv, String endpoint, String applicationPublicKey) {
HttpOnlyManager.init(discordJv, endpoint, applicationPublicKey);
SpringApplication.run(HttpOnlyApplication.class);
}

}
Loading