Discord-Webhooks
Originally part of JDA, this library provides easy to use bindings for the
Discord Webhook API.
Introduction
Here we will give a small overview of the proper usage and applicability of the resources provided by this library.
Documentation is available via the GitHub pages on this repository: Javadoc
Limitations
Webhooks on discord are only capable of sending messages, nothing more. For anything else you either have to use OAuth2 or a bot account. This library does not provide any functionality for creating or modifying webhooks.
Getting Started
The first thing to do is to create either a WebhookClient
or a WebhookCluster
. The WebhookClient
provides functionality to send messages to one webhook based on either a webhook URL or the ID and token of a webhook. It implements automatic rate-limit handling and can be configured to use a shared thread-pool.
Creating a WebhookClient
WebhookClientBuilder builder = new WebhookClientBuilder(url);
builder.setThreadFactory((job) -> {
Thread thread = new Thread(job);
thread.setName("Hello");
thread.setDaemon(true);
return thread;
});
builder.setWait(true);
WebhookClient client = builder.build();
WebhookClient client = WebhookClient.withUrl(url);
Creating a WebhookCluster
WebhookCluster cluster = new WebhookCluster(5);
cluster.setDefaultHttpClient(new OkHttpClient());
cluster.setDefaultDaemon(true);
cluster.buildWebhook(id, token);
cluster.addWebhook(client);
Sending Messages
Sending messages happens in a background thread (configured through the pool/factory) and thus is async by default. To access the message you have to enable the wait
mechanic (enabled by default). With this you can use the callbacks provided by CompletableFuture<ReadonlyMessage>
.
client.send("Hello World");
WebhookEmbed embed = new WebhookEmbedBuilder()
.setColor(0xFF00EE)
.setDescription("Hello World")
.build();
client.send(embed)
.thenAccept((message) -> System.out.printf("Message with embed has been sent [%s]%n", message.getId()));
WebhookMessage message = new WebhookMessageBuilder()
.setUsername("Minn")
.setAvatarUrl(avatarUrl)
.setContent("Hello World")
.build();
client.send(message);
Threads
You can use the webhook clients provided by this library to send messages in threads. There are two ways to accomplish this.
Set a thread id in the client builder to send all messages in that client to the thread:
WebhookClient client = new WebhookClientBuilder(url)
.setThreadId(threadId)
.build();
client.send("Hello");
Use onThread
to create a client with a thread id and all other settings inherited:
try (WebhookClient client = WebhookClient.withUrl(url)) {
WebhookClient thread = client.onThread(123L);
thread.send("Hello");
client.send("Friend");
}
All WebhookClient
instances created with onThread
will share the same thread pool used by the original client. This means that shutting down or closing any of the clients will also close all other clients associated with that underlying thread pool.
WebhookClient thread = null;
try (WebhookClient client = WebhookClient.withUrl(url)) {
thread = client.onThread(id);
}
thread.send("Hello");
WebhookClient client = WebhookClient.withUrl(url);
try (WebhookClient thread = client.onThread(id)) {
thread.send("...");
}
client.send("Hello");
Shutdown
Since the clients use threads for sending messages you should close the client to end the threads. This can be ignored if a shared thread-pool is used between multiple clients but that pool has to be shutdown by the user accordingly.
try (WebhookClient client = WebhookClient.withUrl(url)) {
client.send("Hello World");
}
webhookCluster.close();
Error Handling
By default, this library will log every exception encountered when sending a message using the SLF4J logger implementation.
This can be configured using WebhookClient#setErrorHandler to custom behavior per client or WebhookClient#setDefaultErrorHandler for all clients.
Example
WebhookClient.setDefaultErrorHandler((client, message, throwable) -> {
System.err.printf("[%s] %s%n", client.getId(), message);
if (throwable != null)
throwable.printStackTrace();
if (throwable instanceof HttpException ex && ex.getCode() == 404) {
client.close();
}
});
External Libraries
This library also supports sending webhook messages with integration from other libraries such as
Example JDA
public void sendWebhook(Webhook webhook) {
MessageCreateData message = new MessageCreateBuilder().setContent("Hello World").build();
try (JDAWebhookClient client = JDAWebhookClient.from(webhook)) {
client.send(message);
}
}
Example Discord4J
public void sendWebhook(Webhook webhook) {
try (D4JWebhookClient client = D4JWebhookClient.from(webhook)) {
client.send(MessageCreateSpec.create()
.withContent("Hello World")
.addFile("cat.png", new FileInputStream("cat.png"))
);
}
}
Download
Note: Replace %VERSION%
below with the desired version.
Gradle
repositories {
mavenCentral()
}
dependencies {
implementation("club.minnced:discord-webhooks:%VERSION%")
}
Maven
<dependency>
<groupId>club.minnced</groupId>
<artifactId>discord-webhooks</artifactId>
<version>%VERSION%</version>
</dependency>
Compile Yourself
- Clone repository
- Run
gradlew shadowJar
- Use jar suffixed with
-all.jar
in build/libs
Example
class MyAppender extends AppenderBase<LoggingEvent> {
private final WebhookClient client;
@Override
protected void append(LoggingEvent eventObject) {
if (client == null)
return;
WebhookEmbedBuilder builder = new WebhookEmbedBuilder();
builder.setDescription(eventObject.getFormattedMessage());
int color = -1;
switch (eventObject.getLevel().toInt()) {
case ERROR_INT:
color = 0xFF0000;
break;
case INFO_INT:
color = 0xF8F8FF;
break;
}
if (color > 0)
builder.setColor(color);
builder.setTimestamp(Instant.ofEpochMilli(eventObject.getTimeStamp()));
client.send(builder.build());
}
}
This is an example implementation of an Appender for logback-classic